- Drag any of the red handles to reposition - the head's not independently movable yet
- Position the floor, if you need to
- Click the toggle switch to hide the handles
- Screenshot
- Done!
I borrowed the kernel of the drag-and-drop code from Sherwood/Chabay. Let me know if you find it useful!
The source:
from __future__ import division
from visual import *
from visual.controls import *
def toggle_visible(scene):
for obj in scene.objects:
if obj.__class__ == sphere:
if obj.radius == .5:
obj.radius = .35
obj.color = color.black
elif obj.radius == .35:
obj.radius = .5
obj.color = color.red
scene.background = color.white
# physical parameters
ULlen = 8
LLlen = 8
UAlen = 6
LAlen = 6
bodlen = 10
thickness = .3
# initial joint locations
CJ = vector(0,0,0)
LF = vector(-3,-15,0)
RF = vector(3,-15,0)
LK = CJ+(LF-CJ)/2
RK = CJ+(RF-CJ)/2
NJ = vector(0,bodlen,0)
LH = vector(-2,-2,0)
RH = vector(2,-2,0)
LE = NJ+(LH-NJ)/2
RE = NJ+(RH-NJ)/2
#objects: joints and limbs
ground = box(color = color.black, pos = (0,-16,0), height = 1, length = 50, width = 3)
leftUL = cylinder(color=color.black, pos = CJ, radius = thickness, axis = LK-CJ)
rightUL = cylinder(color=color.black, pos = CJ, radius = thickness, axis = RK-CJ)
leftK = sphere(color=color.red, radius = .5, pos = LK)
rightK = sphere(color=color.red, radius = .5, pos = RK)
leftLL = cylinder(color=color.black, pos = LK, radius = thickness, axis = LF-LK)
rightLL = cylinder(color=color.black, pos = RK, radius = thickness, axis = RF-RK)
leftF = sphere(color=color.red, radius = .5, pos = LF)
rightF = sphere(color=color.red, radius = .5, pos = RF)
body = cylinder(color=color.black, pos = CJ, radius = .05+thickness, axis = NJ-CJ)
leftUA = cylinder(color=color.black, pos = NJ, radius = thickness, axis = LE-NJ)
rightUA = cylinder(color=color.black, pos = NJ, radius = thickness, axis = RE-NJ)
leftE = sphere(color=color.red, radius = .5, pos = LE)
rightE = sphere(color=color.red, radius = .5, pos = RE)
leftLA = cylinder(color=color.black, pos = LE, radius = thickness, axis = LH-LE)
rightLA = cylinder(color=color.black, pos = RE, radius = thickness, axis = RH-RE)
leftH = sphere(color=color.red, radius = .5, pos = LH)
rightH = sphere(color=color.red, radius = .5, pos = RH)
C = sphere(color=color.black, radius = .36, pos = CJ)
neck = sphere(color=color.red, radius = .5, pos = NJ)
# toggle to show/hide handles
c = controls(x = 800, y=0, width = 300, height = 200, range = 100)
tR = toggle(pos = (-30,25), width = 10, height = 30, text0='',text1='Show positioning handles',
action = lambda:toggle_visible(scene))
# head
R = 3.1
headpos = NJ+vector(0,R,0)
headshape = shapes.ellipse(thickness =.035, height =2*R, width = 4.7)
headpath = [headpos,headpos+(0,0,-.05)]
head = extrusion(pos=headpath, shape = headshape, color = color.black)
pick = None
# the loop: adjusts axes and positions based on the handles that you're dragging
while 1:
rate(1000)
if scene.mouse.events:
m1 = scene.mouse.getevent() # obtain drag or drop event
if m1.drag and m1.pick: #
drag_pos = m1.pickpos # where on the ball the mouse was
pick = m1.pick # pick is now True (nonzero)
scene.cursor.visible = False # make cursor invisible
elif m1.drop: # released the mouse button at end of drag
pick = None # end dragging (None is False)
scene.cursor.visible = True # cursor visible again
if pick == ground:
new_pos = scene.mouse.project(normal=(0,0,1)) # project onto xz plane
if new_pos != drag_pos: # if the mouse has moved since last position
loc = scene.mouse.pos
ground.pos.y = loc.y
if pick == neck:
new_pos = scene.mouse.project(normal=(0,0,1)) # project onto xz plane
if new_pos != drag_pos: # if the mouse has moved since last position
loc = scene.mouse.pos
# neck motion
neck.pos = (loc-CJ)*bodlen/mag(loc-CJ)
body.axis = neck.pos-CJ
head.pos = (bodlen+R)*(neck.pos-CJ)/mag(neck.pos-CJ)
leftUA.axis = (leftE.pos-neck.pos)*UAlen/mag(leftE.pos-neck.pos)
leftUA.pos = neck.pos
leftE.pos = neck.pos + leftUA.axis
leftLA.axis = (leftH.pos-leftE.pos)*LAlen/mag(leftH.pos-leftE.pos)
leftLA.pos = leftE.pos
leftH.pos = leftE.pos + leftLA.axis
rightUA.axis = (rightE.pos-neck.pos)*UAlen/mag(rightE.pos-neck.pos)
rightUA.pos = neck.pos
rightE.pos = neck.pos + rightUA.axis
rightLA.axis = (rightH.pos-rightE.pos)*LAlen/mag(rightH.pos-rightE.pos)
rightLA.pos = rightE.pos
rightH.pos = rightE.pos + rightLA.axis
head.visible = False
R = 3.1
headpos = neck.pos*(bodlen+R)/bodlen
headshape = shapes.ellipse(thickness =.035, height =2*R, width = 4.7, rotate = -atan(neck.pos.x/neck.pos.y))
headpath = [headpos,headpos+(0,0,-.05)]
head = extrusion(pos=headpath, shape = headshape, color = color.black)
head.visible = True
if pick == leftK:
new_pos = scene.mouse.project(normal=(0,0,1)) # project onto xz plane
if new_pos != drag_pos: # if the mouse has moved since last position
loc = scene.mouse.pos
# left knee motion
leftK.pos = (loc-CJ)*ULlen/mag(loc-CJ)
leftUL.axis = leftK.pos-CJ
leftLL.axis = (leftF.pos-leftK.pos)*LLlen/mag(leftF.pos-leftK.pos)
leftLL.pos = leftK.pos
leftF.pos = leftK.pos + leftLL.axis
if pick == rightK:
new_pos = scene.mouse.project(normal=(0,0,1)) # project onto xz plane
if new_pos != drag_pos: # if the mouse has moved since last position
loc = scene.mouse.pos
# right knee motion
rightK.pos = (loc-CJ)*ULlen/mag(loc-CJ)
rightUL.axis = rightK.pos-CJ
rightLL.axis = (rightF.pos-rightK.pos)*LLlen/mag(rightF.pos-rightK.pos)
rightLL.pos = rightK.pos
rightF.pos = rightK.pos + rightLL.axis
if pick == leftF:
new_pos = scene.mouse.project(normal=(0,0,1)) # project onto xz plane
if new_pos != drag_pos: # if the mouse has moved since last position
loc = scene.mouse.pos
# left foot motion
leftLL.axis = (loc-leftK.pos)*LLlen/mag(loc-leftK.pos)
leftF.pos = leftK.pos + leftLL.axis
if pick == rightF:
new_pos = scene.mouse.project(normal=(0,0,1)) # project onto xz plane
if new_pos != drag_pos: # if the mouse has moved since last position
loc = scene.mouse.pos
# right foot motion
rightLL.axis = (loc-rightK.pos)*LLlen/mag(loc-rightK.pos)
rightF.pos = rightK.pos + rightLL.axis
if pick == leftE:
new_pos = scene.mouse.project(normal=(0,0,1)) # project onto xz plane
if new_pos != drag_pos: # if the mouse has moved since last position
loc = scene.mouse.pos
# right elbow motion
leftE.pos = neck.pos+(loc-neck.pos)*UAlen/mag(loc-neck.pos)
leftUA.axis = leftE.pos-neck.pos
leftLA.axis = (leftH.pos-leftE.pos)*LAlen/mag(leftH.pos-leftE.pos)
leftLA.pos = leftE.pos
leftH.pos = leftE.pos + leftLA.axis
if pick == rightE:
new_pos = scene.mouse.project(normal=(0,0,1)) # project onto xz plane
if new_pos != drag_pos: # if the mouse has moved since last position
loc = scene.mouse.pos
# right elbow motion
rightE.pos = neck.pos+(loc-neck.pos)*UAlen/mag(loc-neck.pos)
rightUA.axis = rightE.pos-neck.pos
rightLA.axis = (rightH.pos-rightE.pos)*LAlen/mag(rightH.pos-rightE.pos)
rightLA.pos = rightE.pos
rightH.pos = rightE.pos + rightLA.axis
if pick == leftH:
new_pos = scene.mouse.project(normal=(0,0,1)) # project onto xz plane
if new_pos != drag_pos: # if the mouse has moved since last position
loc = scene.mouse.pos
# left hand motion
leftLA.axis = (loc-leftE.pos)*LAlen/mag(loc-leftE.pos)
leftH.pos = leftE.pos + leftLA.axis
if pick == rightH:
new_pos = scene.mouse.project(normal=(0,0,1)) # project onto xz plane
if new_pos != drag_pos: # if the mouse has moved since last position
loc = scene.mouse.pos
# right hand motion
rightLA.axis = (loc-rightE.pos)*LAlen/mag(loc-rightE.pos)
rightH.pos = rightE.pos + rightLA.axis
No comments:
Post a Comment