Tuesday, February 26, 2013

Scene Navigation Zoom Tracking

In my last post I began working on a 2D scene manipulation system for an upcoming project. One of the design goals was to have a "smart zoom" feature which would track to where the mouse was. This is one of my favorite scene navigation tools as all I had to do to focus on a particular area was put my mouse in the center of that area and zoom in. I could also "pan" around the view by zooming out/in while moving my mouse around. Two applications that I know have this feature off the top of my head are SolidWorks and Eagle, though I really wish this feature was in all applications which require any type of scene navigation. I didn't have this feature implemented last time because I wasn't quite sure how to do it. However, I have since figured out how this feature can be implemented.

The key idea behind this functionality is we want to keep the point in the scene that the mouse pointer is over in the same place on the screen after we zoom. Actually, we only want the pointer to be tracked on a zoom-in. Zooming out is performed relative to the center of viewport. It's a simple idea and can easily be implemented. Here's the implementation I used which takes advantage of the Qt framework functions. It saves me the hassle of having to calculate the translations between different coordinate systems.

void Viewport::zoom(qreal delta, const QPoint &center)
{
    QPointF scenePos = mapToScene(center);
    scale(pow(zoomFactor, delta / 56), pow(zoomFactor, delta / 56));
    if(delta > 0)
    {
        scenePos = mapFromScene(scenePos) - center;
        pan(scenePos.x(), scenePos.y());
    }
}

Really simple and easy to add. it's a shame more programs don't do this. delta is the same mouse wheel delta I meantioned last time (along with it's eighth degree increments), and center is the point you want to track. In my case this would be the location of the pointer.

No comments :

Post a Comment