Creating a panning function

59 views
Skip to first unread message

Diego Saenz

unread,
Oct 12, 2017, 2:03:20 PM10/12/17
to glowscri...@googlegroups.com
Hi everyone, I want to be able to pan the scene with the left click of the mouse.

I'm using the mousedown, mousemove, and mouseup events, and updating the camera position and scene center. But it behaves all shaky and sometimes kinda random, can someone point out what am I doing wrong? Or share a panning function if you have one? Thanks.

When the left mouse button is pressed I read the current mouse and camera position, as well as the scene center vector.
Then when the drag motion starts I update the camera position and the center vector.

Here's the code:
http://www.glowscript.org/#/user/disa/folder/Public/program/panxyplane

from vpython import*

def down():
    global drag, center_x, center_y, center_z, camera_z, mouse_x, mouse_y
    center_x = scene.center.x
    center_y = scene.center.y
    center_z = scene.center.z
    camera_z = scene.camera.pos.z
    mouse_x = scene.mouse.pos.x
    mouse_y = scene.mouse.pos.y
    drag = True
   
def move():
    if drag: 
        x = center_x - (scene.mouse.pos.x - mouse_x)
        y = center_y - (scene.mouse.pos.y - mouse_y)
        scene.camera.pos = vec(x,y,camera_z)
        scene.center = vec(x,y,center_z)
       
def up():
    drag = False
   
sphere(pos=vec(0,0,0), radius=0.1)

scene.bind("mousedown", down)
scene.bind("mousemove", move)
scene.bind("mouseup", up

Bruce Sherwood

unread,
Oct 12, 2017, 4:22:53 PM10/12/17
to Glowscript Users
Here is a program that works properly. The key subtle issue is this: Suppose you press down the mouse button at x = 0.4, and you set scene.center.x to 0.4. Now where the mouse is located is no longer x = 0.4 but x = 0.8. A way to deal with that is to set the initial lastx to 0.8 rather than 0.4, hence the odd factor of 2 in the last line of the down function.

#---------------------------------------------------------------

def down():
    global drag, lastx
    drag = True
    scene.center.x = scene.mouse.pos.x
    lastx = 2*scene.center.x

def move():
    global lastx
    if drag:
        dx = scene.mouse.pos.x - lastx
        scene.center.x += dx
        lastx = scene.mouse.pos.x+dx
        
def up():
    global drag
    drag = False
    
#---------------------------------------------------------------

scene.range = 1
sphere(pos=vec(-.4,0,0), radius=0.1, color=color.red)
sphere(pos=vec(0,0,0), radius=0.1, color=color.green)
sphere(pos=vec(.4,0,0), radius=0.1, color=color.blue)

scene.bind("mousedown", down)
scene.bind("mousemove", move)
scene.bind("mouseup", up)

Bruce Sherwood

unread,
Oct 13, 2017, 10:41:32 AM10/13/17
to Glowscript Users
I didn't get it quite right. Here's a corrected version, which works whatever the starting scene.center.x is::

#---------------------------------------------------------------
def down():
    global drag, lastx
    drag = True
    cx = scene.center.x
    scene.center.x = scene.mouse.pos.x
    lastx = scene.mouse.pos.x + (scene.center.x - cx)

def move():
    global lastx
    if drag:
        dx = scene.mouse.pos.x - lastx
        scene.center.x += dx
        lastx = scene.mouse.pos.x+dx
        
def up():
    global drag
    drag = False
    
#---------------------------------------------------------------

scene.range = 2
sphere(pos=vec(-1,0,0), radius=0.2, color=color.red)
sphere(pos=vec(0,0,0), radius=0.2, color=color.green)
sphere(pos=vec(1,0,0), radius=0.2, color=color.blue)
scene.center.x = 1

Diego Saenz

unread,
Oct 13, 2017, 11:02:53 AM10/13/17
to Glowscript Users
Thanks you for the quick response, the program seems to work perfectly.
And thanks for maintaining this tool and the community.

Bruce Sherwood

unread,
Oct 13, 2017, 11:22:18 AM10/13/17
to Glowscript Users
You're welcome! And your question exposed an error (now fixed) in GlowScript, so your question was quite useful.

The error was that changing a component of scene.center didn't trigger GlowScript noticing that you had changed scene.center.

Bruce

Diego Saenz

unread,
Oct 15, 2017, 11:04:54 PM10/15/17
to Glowscript Users
Bruce, I see the changes you made to the code in the github repository, and the code works as expected when I'm using online version (working directly on glowscript.org), but my local installation is not updated and still glitchy. How can I update my local installation?

I downloaded the package via Anaconda with: conda install -c vpython vpython
And I already tried: conda update -c vpython vpython

Thanks in advance.

Bruce Sherwood

unread,
Oct 16, 2017, 11:39:51 AM10/16/17
to Glowscript Users
I tried running the program in VPython 7 and I think I see what you mean, that the motion can be jerky. My first thought was that the problem could be due to the fact that we need to release an updated vpython module to use the latest GlowScript library, to fix the bug in setting scene.center.x not being noticed as a change to scene.center. So I rewrote the program to set scene.center:

#---------------------------------------------------------------
def down():
    global drag, lastx
    drag = True
    cx = scene.center.x
    sx = scene.mouse.pos.x
    scene.center = vec(sx,0,0)
    lastx = scene.mouse.pos.x + (sx - cx)

def move():
    global lastx
    if drag:
        dx = scene.mouse.pos.x - lastx
        sx = scene.center.x + dx
        scene.center = vec(sx,0,0)
        lastx = scene.mouse.pos.x+dx
        
def up():
    global drag
    drag = False
    
#---------------------------------------------------------------

scene.range = 2
sphere(pos=vec(-1,0,0), radius=0.2, color=color.red)
sphere(pos=vec(0,0,0), radius=0.2, color=color.green)
sphere(pos=vec(1,0,0), radius=0.2, color=color.blue)
scene.center = vec(1,0,0)

scene.bind("mousedown", down)
scene.bind("mousemove", move)
scene.bind("mouseup", up)

However, that doesn't solve the problem. I'll look into this. Thanks for the report.

Bruce
Reply all
Reply to author
Forward
0 new messages