Skip to content

Instantly share code, notes, and snippets.

# HansNewbie/maya_make_circular_motion.py

Last active August 29, 2015 14:15
Show Gist options
• Save HansNewbie/0fc560d134fa9181f2b7 to your computer and use it in GitHub Desktop.
CS3242
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 from maya import cmds from math import * def euler(x, dt, dxdt): x_new = [0, 0, 0] # TODO: implement the Euler method here for i in range(0,3): x_new[i] = x[i] + dt*dxdt[i] return x_new def make_state(x): return [x] def get_location(state): return state[0] def compute_circle_derivatives(state, angular_velocity): x = get_location(state) dxdt = [0, 0, 0] # TODO: compute the derivative dxdt from the current location and the angular velocity ###### Cheating way by getting next position radius = sqrt(pow(x[0], 2) + pow(x[1], 2)) angle = atan2(x[1], x[0]) dxdt[0] = radius * cos(angle+angular_velocity) - x[0] dxdt[1] = radius * sin(angle+angular_velocity) - x[1] ###### ###### Proper method by derivation # This will not be perfect circle but rather spiral because lim (t -> 0) is not fulfilled # Set parameter time step to be smaller to achieve this dxdt[0] = -1 * x[1] * angular_velocity dxdt[1] = x[0] * angular_velocity ###### return dxdt def simulate_circle(state, angular_velocity, dt): x = get_location(state) dxdt = compute_circle_derivatives(state, angular_velocity) x = euler(x, dt, dxdt) return make_state(x) def maya_move(angular_velocity, time_step): objects = cmds.ls(sl=True) if objects == []: print('* Please select at least an object.') return trajectory = cmds.ls('trajectory') for i, o in enumerate(objects): x = cmds.getAttr(o + '.translateX') y = cmds.getAttr(o + '.translateY') z = cmds.getAttr(o + '.translateZ') loc = [x, y, z] state = make_state(loc) state = simulate_circle(state, angular_velocity, time_step) old_loc = loc loc = get_location(state) cmds.select(o) cmds.move(loc[0], loc[1], loc[2]) # draw trajectory for the first object if i == 0: if trajectory == []: cv = cmds.curve(point=[old_loc, loc], degree=1) cmds.rename(cv, 'trajectory') else: cmds.curve('trajectory', point=[loc], degree=1, append=True) # keep all objects selected cmds.select(objects) maya_move(0.1 * pi, 1.0)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 from maya import cmds from math import * def euler(x, dt, dxdt): x_new = [0, 0, 0] # TODO: implement euler method here for i in range(0, 3): x_new[i] = x[i] + dt*dxdt[i] return x_new def compute_force_derivatives(force, mass, velocity): dxdt = [0, 0, 0] dvdt = [0, 0, 0] # TODO: compute location derivative dxdt for i in range(0,3): dxdt[i] = velocity[i] # TODO: compute velocity derivative dvdt for i in range(0,3): dvdt[i] = force[i]/mass return [dxdt, dvdt] def compute_force(const, mass, velocity): gravity = const['gravity'] viscous_drag = const['viscous_drag'] force = [0, 0, 0] # TODO: compute total force # You can ignore the viscous drag force[1] = -1 * mass * gravity return force def make_state(x, v): return [x, v] def get_location(state): return state[0] def get_velocity(state): return state[1] def simulate_force(state, const, mass, dt): x = get_location(state) v = get_velocity(state) # TODO: compute force, derivatives, and make an Euler step on the state force = compute_force(const, mass, v) state = compute_force_derivatives(force, mass, v) # TODO: make one step Euler x = euler(x, dt, state[0]) v = euler(v, dt, state[1]) return make_state(x, v) def maya_reset(params): initial_location = params['initial_location'] initial_velocity = params['initial_velocity'] objects = cmds.ls(sl=True) if objects == []: print('* Please select at least an object.') return for i, o in enumerate(objects): cmds.select(o) if not cmds.attributeQuery('velocityX', n=o, exists=True): cmds.addAttr(longName='velocityX', defaultValue=initial_velocity[0]) cmds.addAttr(longName='velocityY', defaultValue=initial_velocity[1]) cmds.addAttr(longName='velocityZ', defaultValue=initial_velocity[2]) else: cmds.setAttr(o + '.velocityX', initial_velocity[0]) cmds.setAttr(o + '.velocityY', initial_velocity[1]) cmds.setAttr(o + '.velocityZ', initial_velocity[2]) cmds.move(initial_location[0], initial_location[1], initial_location[2]) cmds.select(objects) print 'Attributes reset.' def maya_create_destination(const, params): # destination is when the object touches the ground again # assume no viscous drag gravity = const['gravity'] v = params['initial_velocity'] # TODO: compute the time the particle touches the ground t = 0 x = v[0] * t z = v[2] * t cube = cmds.polyCube(h=2, w=2, d=2) cmds.select(cube) cmds.move(x, 0.0, z) def maya_move(const, params, time_step): mass = params['mass'] initial_velocity = params['initial_velocity'] objects = cmds.ls(sl=True) if objects == []: print('* Please select at least an object.') return trajectory = cmds.ls('trajectory') for i, o in enumerate(objects): cmds.select(o) x = cmds.getAttr(o + '.translateX') y = cmds.getAttr(o + '.translateY') z = cmds.getAttr(o + '.translateZ') if not cmds.attributeQuery('velocityX', n=o, exists=True): cmds.addAttr(longName='velocityX', defaultValue=initial_velocity[0]) cmds.addAttr(longName='velocityY', defaultValue=initial_velocity[1]) cmds.addAttr(longName='velocityZ', defaultValue=initial_velocity[2]) vx = cmds.getAttr(o + '.velocityX') vy = cmds.getAttr(o + '.velocityY') vz = cmds.getAttr(o + '.velocityZ') loc = [x, y, z] vel = [vx, vy, vz] state = make_state(loc, vel) state = simulate_force(state, const, mass, time_step) old_loc = loc loc = get_location(state) cmds.move(loc[0], loc[1], loc[2]) vel = get_velocity(state) cmds.setAttr(o + '.velocityX', vel[0]) cmds.setAttr(o + '.velocityY', vel[1]) cmds.setAttr(o + '.velocityZ', vel[2]) # draw trajectory for the first object if i == 0: if trajectory == []: cv = cmds.curve(point=[old_loc, loc], degree=1) cmds.rename(cv, 'trajectory') else: cmds.curve('trajectory', point=[loc], degree=1, append=True) # keep all objects selected cmds.select(objects) # NOTE: remember to call reset every time initial velocity is changed. const = {'gravity' : 0.98, 'viscous_drag' : 0.0} params = {'mass' : 1, 'initial_location' : [0, 0, 0], 'initial_velocity' : [5, 5, 0.0]} maya_create_destination(const, params) maya_reset(params) maya_move(const, params, 1.0)
to join this conversation on GitHub. Already have an account? Sign in to comment