|
|
Home
If you're new to Python
and VPython: Introduction
A VPython tutorial
Pictures of 3D objects
Choose a 3D object:
Work with 3D objects:
Windows, Events, & Files:
Vector operations
Graphs
factorial/combin
What's new in Visual 5
VPython web site
Visual license
Python web site
Math module (sqrt etc.)
Numpy module (arrays) |
|
Drag example
Here is the sequence of mouse events involved in dragging something:
1) m1.press is true when you depress the mouse button (it is
'left' if left button; any quantity that is nonzero is considered true in Python).
2) m1.drag is true when the mouse coordinates change from what they were at
the time of m1.press.
At the time of the drag event, the mouse position is reported to be what it
was at the time of the press event, so that the dragging can start at the place
where the user first pressed the mouse button. If the mouse is in motion at the time of the press
event, it is quite possible that the next position seen by the computer, at
the time of the drag event, could be quite far from the click position. This
is why the position of the drag event is reported as though it occurred at the
press location.
3) No events occur while dragging; you continually use scene.mouse.pos to update
what you're dragging.
4) m1.drop is true when you release the mouse button.
You can program dragging with the mouse simply by continually
reading the current value of scene.mouse.pos.
Here is a complete routine for dragging a sphere with the left button down. Copy this into an edit window and try it!
from visual import *
scene.range = 5 # fixed size, no autoscaling
ball = sphere(pos=(-3,0,0), color=color.cyan)
cube = box(pos=(+3,0,0), size=(2,2,2), color=color.red)
pick = None # no object picked out of the scene yet
while True:
if scene.mouse.events:
m1 = scene.mouse.getevent()
# get event
if m1.drag
and m1.pick == ball: # if touched ball
drag_pos
= m1.pickpos # where on the ball
pick
= m1.pick # pick now true (not None)
elif m1.drop:
# released at end of drag
pick
= None # end dragging (None is false)
if pick:
# project onto xy plane, even if scene rotated:
new_pos = scene.mouse.project(normal=(0,0,1))
if new_pos
!= drag_pos: # if mouse has moved
# offset for where the ball was clicked:
pick.pos
+= new_pos - drag_pos
drag_pos
= new_pos # update drag position
If you do a lot of processing of each mouse movement, or you
are leaving a trail behind the moving object, you may need to check whether
the "new" mouse position is in fact different from the previous position
before processing the "move", as is done in the example above. For
example, a trail drawn with a curve object that contains a huge number of points
all at the same location may not display properly.
Most VPython objects can be "picked" by
clicking them. Here is a more general routine
which lets you drag either the tail or the tip of an arrow. Copy this into an edit window and try it!
from visual import *
scene.range = 8 # fixed size, no autoscaling
arr = arrow(pos=(2,0,0),axis=(0,5,0))
by = 0.3 # click this close to tail or tip
drag = None # have not selected tail
or tip of arrow
while True:
if scene.mouse.events:
m1 = scene.mouse.getevent()
# obtain event
if m1.press:
if
mag(arr.pos-m1.pos) <= by:
drag
= 'tail' # near tail of arrow
elif
mag((arr.pos+arr.axis)-m1.pos) <= by:
drag
= 'tip' # near tip of arrow
drag_pos
= m1.pos # save press location
elif m1.drop:
# released at end of drag
drag
= None # end dragging (None is False)
if drag:
new_pos = scene.mouse.pos
if new_pos
!= drag_pos: # if mouse has moved
displace
= new_pos - drag_pos # moved how far
drag_pos
= new_pos # update drag position
if
drag == 'tail':
arr.pos
+= displace # displace the tail
else:
arr.axis
+= displace # displace the tip
Here is general mouse
documentation.
|