UserZoom functionality in Code

96 views
Skip to first unread message

Sean Craft

unread,
Feb 23, 2015, 3:52:57 PM2/23/15
to vpytho...@googlegroups.com
I need some help implementing Zoom functionality in code.  I realize that this can be achieved by changing the scene.range parameter, but from my experience this has a slightly different effect at close range.  Let's say I have a cube object, and it is very close to me (1 or 2 spaces away with a diameter of 1).  Depending on the level of UserZoom, the box may be obscured by the Camera, rendering it invisible at close distances.  I have noticed that I cannot resolve this matter, regardless of how small I set the range.  However, if I enable userzoom, and zoom in all the way, this issue is resolved.  This leads me to believe that the two operations are in fact slightly different, on the backend.  Is there any way I can implement the Zoom functionality in code, since I want to achieve this same effect programmattically? 

I am using the latest Vpython as well as Python 2.7

Sean

Bruce Sherwood

unread,
Feb 23, 2015, 5:30:54 PM2/23/15
to vpytho...@googlegroups.com
For starters, you might look at the program "Zoom and spin under complete program control" in the "Contributed programs" section of vpython.org.

Sean Craft

unread,
Feb 23, 2015, 8:58:25 PM2/23/15
to vpytho...@googlegroups.com
I have looked at it, but it utilizes changing the scene.range property to affect a zoom effect.  Is this the same thing that UserZoom does in the background, just change the range?  Because from what I can tell, they are not precisely the same.  On a superficial level, they appear to do the same thing, but on a more subtle level, there seem to be semantic differences in how the functionality is handled in the background.  I will try to provide some screenshots and examples soon.  But if Zooming and changing the range operate exactly the same on the backend, then quick question - what is the minimum range possible, if there is one.  

Also - when I use UserZoom and zoom into a scene, if I am constantly printing scene.range, i notice that it does not change.  This also concerns me.  Is the value simply not being updated?  Or is it not being changed?

Thanks,
Sean


Bruce Sherwood

unread,
Feb 23, 2015, 10:40:06 PM2/23/15
to vpytho...@googlegroups.com
This area of VPython is not ideal. There is a hidden parameter that characterizes the user's modification by zooming of the camera position; user zoom does not change range. That various aspects of camera positioning are more read than right goes way back to the origins of VPython and I think have something to do with possible synchronization issues that could otherwise have arisen when, as was the case before VPython 6, rendering was interrupt-driven and could interrupt user code at any time.

That said, the last time this came up the user who wanted complete control commented that the contributed program did provide the control they needed.

I don't know of any restriction on range. There exist programs for which the display width is 1e-13 and others where the display width is 1e12.

Sean Craft

unread,
Mar 7, 2015, 3:05:51 PM3/7/15
to vpytho...@googlegroups.com
Alright, sorry this took so long.  So if you look through these pictures, it will give you an idea of my issue.  So first I start off with a range of 1E-10 in 1.png.  there are several objects nearby, but none are visible.  Then, in 2.png, I use the builtin UserZoom function with my mouse to zoom in.  I continue to zoom in using this method in 3 and 4.png.  Now, I use the same functionality to zoom back out to the original (non-visible) zoom level.  Now, I have set key "q" to zoom in using range changes, and "p" to zoom out using range changes.  Since my range is still 1e-10, I start to play with q and p a bit.  I zoom out to a level where I can see the platform (Range1.png).  Then I press q to zoom in (decrease range by half), and that is Range2.png.  I continue this process in Range3.png, and Range4.png.  You can see the issue, using range to adjust the zoom, for some strange reason, does not allow me to get an up-close view of my platform.  When I get a range that would have me near the platform, the platform becomes invisible.  

As it turns out, I have realized that this issue has something to do with the skysphere that I developed.  When I remove the skysphere, and just leave the regular black python  background for the scene, using the range to back out and zoom in works as intended (the platform is always visible, no matter how close I get).  So, either I have to figure out what is wrong with my design of the skysphere, that is causing this to break, or I have to find a way to zoom in the same way that VPython handles UserZoom.  I have included below, also, my code for skysphere generation, so perhaps you can see something blatantly wrong with my design.  

class SkySphere(extrusion):
   
def __init__(this, display, pos, radius, material, visible = True):
       
this.path = paths.arc(pos = pos, radius = 0.001, np=128, angle1=0, angle2=2*pi)
       
this.ocirc = shapes.circle(pos=pos, radius = radius+1,rotate = pi)
       
this.icirc = shapes.circle(pos=pos, radius = radius,rotate = pi)
       
this.semiCirc = shapes.arc(radius = radius, angle1 = 3*pi/2, angle2 = 5*pi/2)
       
this.radius = radius
       
super(extrusion,this).__init__(display = display,
                                        pos
=this.path,
                                       shape
=this.semiCirc,
                                       material
=material, visible = visible)


skysphere
= SkySphere(display = world, pos =(0,0,0), visible = False, radius=2000, material=stex.sky)
skysphere
.visible = True


Thanks,
Sean
2.png
3.png
4.png
Range1.png
Range2.png
Range3.png
range4.png
range5.png
1.png

Bruce Sherwood

unread,
Mar 7, 2015, 5:17:40 PM3/7/15
to vpytho...@googlegroups.com
Just starting to look into the information you've furnished, and I have an immediate question. I don't understand the purpose of the SkySphere class, since all it does is create a hollow sphere, but with vastly more expensive code than just using "sphere". Moreover, the material is basically lost, presumably as an effect somehow of displaying lots of thin lunes. Nor are this.icirc or this.ocirc used for anything. What is this about?

Bruce Sherwood

unread,
Mar 7, 2015, 5:30:50 PM3/7/15
to vpytho...@googlegroups.com
I don't see any difference between range1 and range2.

While I don't fully understand what's going on, I would certainly predict problems with putting a 1e-10 scene inside an extrusion whose size is 2000. I would expect there to be serious problems in attempting to render in the same scene objects that differ so much in size, as the OpenGL z clipping planes are going to behave strangely.

I think I now understand what SkySphere is for, but I doubt that it can work. I think that a sky map is something that has to be implemented in OpenGL with very different tools than creating a huge sphere.

Sean Craft

unread,
Mar 7, 2015, 5:38:35 PM3/7/15
to vpytho...@googlegroups.com
Honestly, that's a good question.  I wrote that so long ago, I don't remember for sure.  But I think it was actually an attempt to try to solve the same problem I am talking about in this thread...  meaning it was a failed attempt.  So I tested it with a sphere, and it looks better and I agree it should be less expensive.  But the issue of the invisible platform is still there, and is exactly identical, almost as if it still thinks I'm using a skysphere.  As for ocirc and icirc, I didn't realize i put that in there, that is deprecated code.  It took me a few tries to get the skysphere to look right.  

I originally thought this issue was caused by the native sphere's "volume", in the sense that i thought it was not hollow, and actually had "matter" inside the sphere that was blocking the platform.  So I tried the skysphere approach that you saw.  

Sean

Sean Craft

unread,
Mar 7, 2015, 5:42:29 PM3/7/15
to vpytho...@googlegroups.com
Eh, I guess you are right about the range1/range2 thing.  I didn't realize I didn't increment in between those captures.  As for the 1E-10 range, that was an experiment to see if it improved anything.  Originally I was using range of 10, or range of 1.  Those produced almost the exact same error.  But I think perhaps you are right in that the issue has to do with the relatively large size of the sphere...  However, that is kind of necessary to make it look realistic.  And aside from that, zooming in using the userzoom functionality shows the platform and gives the desired effect, as seen in the pictures.  

Sean Craft

unread,
Mar 7, 2015, 6:01:59 PM3/7/15
to vpytho...@googlegroups.com
Confirmed, the issue is due to the relative size difference of the blocks and the skysphere (which I have changed to just a regular vpython sphere, for reasons that you mentioned).  If I tone the sphere's radius down to 200, the platform displays as expected..  But...  Its really not an ideal size, due to the fact that it detracts a bit from the realism.  Any idea if there is a way to overcome this limitation in the way that the userzoom does?  

By the way, thanks alot for all the help Bruce.  I really do appreciate it.  

Bruce Sherwood

unread,
Mar 7, 2015, 6:34:57 PM3/7/15
to vpytho...@googlegroups.com
No, I don't fully understand the issue, though it seems to be associated with large differences in the sizes of objects in the scene, and with the way that OpenGL z clipping planes function.

Sean Craft

unread,
Mar 7, 2015, 11:28:44 PM3/7/15
to vpytho...@googlegroups.com
Perhaps I can artificially create mouse presses on the display and move the cursor to induce a userzoom event programmatically, and then turn off the userzoom afterward.  I think I'll try that route.  

Thanks again, I'll try to let you know how it goes.  

Sean
Reply all
Reply to author
Forward
0 new messages