예제 #1
0
void
Zoom3D::ZoomCamera(void)
{
    vtkRenderWindowInteractor *rwi = Interactor;

    if (!SufficientDistanceMoved())
    {
        //
        // This is a point, line, or very, very small rectangle
        //
        return;
    }

    //
    // Determine the size of the window.
    //
    int       size[2];

    rwi->GetSize(size);

    //
    // Get the current view information.
    //
    VisWindow *vw = proxy;

    //
    // Set the new image pan and image zoom.
    //
    double    zoomFactor;
    double    pan[2];

    avtView3D newView3D = vw->GetView3D();

    if (!controlKeyDown) // zoom
    {
        pan[0] = (((double)(anchorX + lastX - size[0])) / (2.0 * (double)size[0]))
             / newView3D.imageZoom;
        pan[1] = (((double)(anchorY + lastY - size[1])) / (2.0 * (double)size[1]))
             / newView3D.imageZoom;
        zoomFactor = fabs((double)(anchorY - lastY)) / (double) size[1];

        newView3D.imagePan[0] -= pan[0];
        newView3D.imagePan[1] -= pan[1];
        newView3D.imageZoom = newView3D.imageZoom / zoomFactor;
    }
    else  // unzoom
    {
        zoomFactor = fabs((double)(anchorY - lastY)) / (double) size[1];
        newView3D.imageZoom = newView3D.imageZoom * zoomFactor;

        pan[0] = (((double)(anchorX + lastX - size[0])) / (2.0 * (double)size[0]))
             / newView3D.imageZoom;
        pan[1] = (((double)(anchorY + lastY - size[1])) / (2.0 * (double)size[1]))
             / newView3D.imageZoom;

        newView3D.imagePan[0] += pan[0];
        newView3D.imagePan[1] += pan[1];
    }

    vw->SetView3D(newView3D);
}
void
ZoomCurve::ZoomCamera(void)
{
    if (!SufficientDistanceMoved())
    {
        //
        // This is a point, line, or very, very small rectangle.
        //
        return;
    }

    //
    // Figure out the lower left and upper right hand corners in
    // display space.
    //
    double leftX   = (double) (anchorX < lastX ? anchorX : lastX);
    double rightX  = (double) (anchorX > lastX ? anchorX : lastX);
    double bottomY = (double) (anchorY < lastY ? anchorY : lastY);
    double topY    = (double) (anchorY > lastY ? anchorY : lastY);
    double dummyZ  = 0.;

    //
    // Convert them to world coordinates.
    //
    vtkRenderer *canvas = proxy.GetCanvas();

    canvas->DisplayToNormalizedDisplay(leftX, topY);
    canvas->NormalizedDisplayToViewport(leftX, topY);
    canvas->ViewportToNormalizedViewport(leftX, topY);
    canvas->NormalizedViewportToView(leftX, topY, dummyZ);
    canvas->ViewToWorld(leftX, topY, dummyZ);

    canvas->DisplayToNormalizedDisplay(rightX, bottomY);
    canvas->NormalizedDisplayToViewport(rightX, bottomY);
    canvas->ViewportToNormalizedViewport(rightX, bottomY);
    canvas->NormalizedViewportToView(rightX, bottomY, dummyZ);
    canvas->ViewToWorld(rightX, bottomY, dummyZ);

    //
    // Set the new view window.
    //
    VisWindow *vw = proxy;

    avtViewCurve newViewCurve=vw->GetViewCurve();

    int       size[2];

    vtkRenderWindowInteractor *rwi = Interactor;
    rwi->GetSize(size);

    double s = newViewCurve.GetScaleFactor(size);

    if (!controlKeyDown) // zoom
    {
        newViewCurve.domain[0] = leftX;
        newViewCurve.domain[1] = rightX;
        newViewCurve.range[0]  = bottomY/s;
        newViewCurve.range[1]  = topY/s;
    }
    else // un-zoom 
    {
        float win1[4], win2[4], win3[4], win4[4];

        // window created by rubber band
        win1[0] = leftX;
        win1[1] = rightX;
        win1[2] = bottomY;
        win1[3] = topY;
        float win1_w = win1[1] - win1[0];
        float win1_h = win1[3] - win1[2];

        // the current window 
        win2[0] = newViewCurve.domain[0];
        win2[1] = newViewCurve.domain[1];
        win2[2] = newViewCurve.range[0];
        win2[3] = newViewCurve.range[1];
        float win2_w = win2[1] - win2[0];
        float win2_h = win2[3] - win2[2];

        float scaleX = win1_w / win2_w;
        float scaleY = win1_h / win2_h;

        if (scaleY < scaleX)
        {
            float midX = (win2[0] + win2[1]) / 2.;
            float halfw = (win2_h) * (win1_w / win1_h) / 2.;
            win3[0] = midX - halfw;
            win3[1] = midX + halfw;
            win3[2] = win2[2];
            win3[3] = win2[3];
        }
        else 
        {
            float midY = (win2[2] + win2[3]) /2.;
            float halfh = (win2_w) * (win1_h / win1_w) / 2.;
            win3[0] = win2[0];
            win3[1] = win2[1]; 
            win3[2] = midY - halfh;
            win3[3] = midY + halfh;
        }

        float win3_w = (win3[1] - win3[0]);
        float win3_h = (win3[3] - win3[2]);

        win4[0] = ((win1[0] - win2[0]) / win2_w) * win3_w + win3[0];
        win4[1] = ((win1[1] - win2[0]) / win2_w) * win3_w + win3[0];
        win4[2] = ((win1[2] - win2[2]) / win2_h) * win3_h + win3[2];
        win4[3] = ((win1[3] - win2[2]) / win2_h) * win3_h + win3[2];

        float win4_w = (win4[1] - win4[0]);
        float win4_h = (win4[3] - win4[2]);

        newViewCurve.domain[0] = (win3[0] - win4[0]) * win3_w / win4_w + win3[0];
        newViewCurve.domain[1] = (win3[1] - win4[0]) * win3_w / win4_w + win3[0];
        newViewCurve.range[0]  = (win3[2] - win4[2]) * win3_h / win4_h + win3[2];
        newViewCurve.range[1]  = (win3[3] - win4[2]) * win3_h / win4_h + win3[2];

        newViewCurve.range[0] /= s;
        newViewCurve.range[1] /= s;
    }

    vw->SetViewCurve(newViewCurve);

    //
    // It looks like we need to explicitly re-render.
    //
    proxy.Render();
}