• Advertisement
Sign in to follow this  

adjusting zoom speed

This topic is 4320 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, In my display() I calculate the time it takes do draw a frame since the last frame and multiply that by some really small value like 0.0001. Then I add that to the current zoomFactor value and run an Animator when the user presses a zoom key. I then use this zoomFactor value in a glOrtho() call and multiply it by the left, right, bottom and top values to zoom my model in and out. The reason I do this is because it zooms my model very smoothly. My problem is that when the model is far away, it zooms slow enough to be under user control, but as it gets nearer (larger) it moves faster and is very hard to adjust and stop at the exact size I want the model to be. It's like watching the Enterprise go into warp speed as near distances and move slowly when it's far away. Anyone have any ideas how to fix this?

Share this post


Link to post
Share on other sites
Advertisement
Sounds like you just need a non-linear mapping from 'interface' zoom to 'actual' zoom. Say both ranges are normalized to the range [0, 1]. You could then try a simple mapping such as:
actual_zoom = input_zoomn
Where n > 1.

This is just an idea; there are probably better solutions (or at least alternate functions that you could apply).

Share this post


Link to post
Share on other sites
Lucky for me I'm getting back into math classes this year. I don't really understand what a non-linear mapping or normalizing the ranges would mean.

I'm guessing the 'actual_zoom' value is the value I pass into my opengl calls but the 'input_value' to the 'n' ... I don't get yet. I know exponentials, but I don't get what an exponent or what value to use would do.

Share this post


Link to post
Share on other sites
Have you change in distance based on the current distance.

Zoom in: NewMagnification *= 1.1f;
Zoom out: NewMagnification /= 1.1f;

or

Zoom in(x): NewMagnification *= power(1.1f, x);
Zoom out(x): NewMagnification /= power(1.1f, x);

It would be a bit faster if you wrote your own power function assuming x is an integer.
I like to use the 2nd set and the param:x is set to the number of clicks on the mouse scroll wheel.

Share this post


Link to post
Share on other sites
I'm not having much luck at this. I commented out my setZoomFactor() methods to try with powers and it zooms so quick either way I can't even see it most of the time. I have JOGL animators started in my key handler which calls my main display loop.

Anyways, can anyone see maybe what's wrong here?



public void display(GLAutoDrawable drawable) {
updateTime();
...

gl.glOrtho(-winWidth * getZoomFactor(), winWidth * getZoomFactor(), -winHeight * getZoomFactor(), winHeight * getZoomFactor(), 100, -100);
...
}

// get time it took to draw this frame since last frame
private void updateTime() {
if(lastTime == -1) {
lastTime = System.currentTimeMillis();
lastFrameTime = 0;
}
else {currentTime = System.currentTimeMillis();
// Time taken to draw the last frame.
lastFrameTime = currentTime - lastTime;
lastTime = currentTime;
}

if (keyHandler.isZoomInPressed()) {
timeRatio = (float) (lastFrameTime * -0.0001);
//setZoomFactor((float) (getZoomFactor() + timeRatio));
setZoomFactor(getZoomFactor() * (float) Math.pow((getZoomFactor() + timeRatio), 1.1));
}
else if (keyHandler.isZoomOutPressed()) {
timeRatio = (float) (lastFrameTime * 0.0001);
//setZoomFactor((float) (getZoomFactor() + timeRatio));
setZoomFactor(getZoomFactor() / (float) Math.pow((getZoomFactor() + timeRatio), 1.1));
}
}

Share this post


Link to post
Share on other sites
The mapping I suggested will only work if the input zoom is normalized, i.e. in the range [0, 1]. Also, it looks like you're doing something different than what I suggested in my previous post. I'm not sure from looking at your code sample what your zoom range is, but I'll try to sketch out how I would do the conversion:
// Adjust zoom based on user input and frametime, and then:
float normalized_zoom = (input_zoom - zoom_min)/(zoom_max - zoom_min);
float adjusted_zoom = std::pow(normalized_zoom, zoom_exp); // zoom_exp > 1, adjust to taste
float actual_zoom = zoom_min + adjusted_zoom * (zoom_max - zoom_min);
This is just an idea; it hasn't been tested or anything. But it seems like it should produce the effect you're looking for.

Share this post


Link to post
Share on other sites
Thanks, I'll keep working at it. One thing different that I have from what you posted is that there is no input_zoom because I have no destination zoom level. The user pushes a plus or minus key till he gets the desired zoom level he wants and then releases the key.

That is ... if I understood your user input zoom correctly.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement