<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<tt>Hello,</tt><tt></tt>
<p><tt>I rewrote the code for zoom window from the TKinteractor.tcl (below).
It works most of the time but if I try to zoom in to a smaller feature
then it doesnt center the model as expected. Has anyone else had
this problem, and if so what is the fix?</tt><tt></tt>
<p><tt>A sample application to test is available at <A HREF="http://www.caept.com/vtk/test.exe">http://www.caept.com/vtk/test.exe</A></tt><tt></tt>
<p><tt>Using the zoom window toolbar button, try zooming in on the top
left corner of the block. It will zoom in but the model will only
show in the top right corner of the view not at all centered as expected.</tt><tt></tt>
<p><tt>Your help is appreciated.</tt><tt></tt>
<p><tt>Ted</tt><tt></tt>
<p><tt>class CFEvisGLView</tt>
<br><tt>{</tt><tt></tt>
<p><tt><snip></tt>
<br><tt> // zoom window</tt>
<br><tt> void DoZoomWindow(CPoint point);</tt>
<br><tt> CPoint m_startdrag;</tt>
<br><tt> CRect m_previous;</tt>
<br><tt> CRect m_current;</tt>
<br><tt> BOOL m_dragging;</tt>
<br><tt></snip></tt>
<br><tt>};</tt>
<br><tt></tt> <tt></tt>
<p><tt>/////////////////////////////////////////////////////////////////////////////</tt>
<br><tt>// Zoom window</tt>
<br><tt>// <A HREF="http://public.kitware.com/pipermail/vtkusers/2000-January/003119.html">http://public.kitware.com/pipermail/vtkusers/2000-January/003119.html</A></tt>
<br><tt>// From TCL implementation: Tkinteractor.tcl</tt>
<br><tt>/////////////////////////////////////////////////////////////////////////////</tt>
<br><tt>void CFEvisGLView::DoZoomWindow(CPoint point)</tt>
<br><tt>{</tt>
<br><tt> CRect viewdims;</tt>
<br><tt> CPoint zoomboxcenter;</tt><tt></tt>
<p><tt> vtkCamera *pCam = Renderer->GetActiveCamera();</tt><tt></tt>
<p><tt> // get view dimensions</tt>
<br><tt> GetClientRect(&viewdims);</tt><tt></tt>
<p><tt> // get box center point in pixels</tt>
<br><tt> zoomboxcenter = m_current.CenterPoint();</tt>
<br><tt> // correct</tt>
<br><tt> // zoomboxcenter.y = viewdims.CenterPoint().y - zoomboxcenter.y;</tt>
<br><tt> </tt>
<br><tt> // Convert the focal point to a display coordinate
in order to get the</tt>
<br><tt> // depth of the focal point in display units</tt>
<br><tt> double focalpoint[3];</tt>
<br><tt> pCam->GetFocalPoint(focalpoint);</tt>
<br><tt> Renderer->SetWorldPoint(focalpoint[0], focalpoint[1], focalpoint[2],
1.0);</tt>
<br><tt> Renderer->WorldToDisplay();</tt>
<br><tt> double displaypoint[3];</tt>
<br><tt> Renderer->GetDisplayPoint(displaypoint);</tt>
<br><tt> double focaldepth = displaypoint[2];</tt>
<br><tt></tt>
<br><tt></tt> <tt></tt>
<p><tt> // Convert the position of the camera to a display
coordinate in order</tt>
<br><tt> // to get the depth of the camera in display
coordinates. Note this is</tt>
<br><tt> // a negative number (behind the near clipping
plane of 0) but it works</tt>
<br><tt> // ok anyway</tt>
<br><tt> double camposition[3];</tt>
<br><tt> pCam->GetPosition(camposition[0], camposition[1], camposition[2]);</tt>
<br><tt> Renderer->SetWorldPoint(camposition[0], camposition[1], camposition[2],
1.0);</tt>
<br><tt> Renderer->WorldToDisplay();</tt>
<br><tt> Renderer->GetDisplayPoint(displaypoint);</tt>
<br><tt> double positiondepth = displaypoint[2];</tt>
<br><tt></tt> <tt></tt>
<p><tt> // Find out the world position of where our new
focal point should</tt>
<br><tt> // be - it will be at the center of the box,
back at the same focal depth</tt>
<br><tt> // Don't actually set it now - we need to do
all our computations before</tt>
<br><tt> // we modify the camera</tt>
<br><tt> Renderer->SetDisplayPoint(zoomboxcenter.x, zoomboxcenter.y,
focaldepth);</tt>
<br><tt> Renderer->DisplayToWorld();</tt>
<br><tt> float newfocalpoint[4];</tt>
<br><tt> Renderer->GetWorldPoint(newfocalpoint);</tt>
<br><tt> if (newfocalpoint[3] != 0.0) {</tt>
<br><tt> newfocalpoint[0] = newfocalpoint[0] / newfocalpoint[3];</tt>
<br><tt> newfocalpoint[1] = newfocalpoint[1] / newfocalpoint[3];</tt>
<br><tt> newfocalpoint[2] = newfocalpoint[2] / newfocalpoint[3];</tt>
<br><tt> }</tt><tt></tt>
<p><tt> // Find out where the new camera position will
be - at the center of</tt>
<br><tt> // the rubber band box at the position depth.
Don't set it yet...</tt>
<br><tt> Renderer->SetDisplayPoint(zoomboxcenter.x, zoomboxcenter.y,
positiondepth);</tt>
<br><tt> Renderer->DisplayToWorld();</tt>
<br><tt> float newposition[4];</tt>
<br><tt> Renderer->GetWorldPoint(newposition);</tt>
<br><tt> if (newposition[3] != 0.0) {</tt>
<br><tt> newposition[0] = newposition[0] / newposition[3];</tt>
<br><tt> newposition[1] = newposition[1] / newposition[3];</tt>
<br><tt> newposition[2] = newposition[2] / newposition[3];</tt>
<br><tt> }</tt><tt></tt>
<p><tt> // We figured out how to position the camera
to be centered, now we</tt>
<br><tt> // need to "zoom". In parallel, this is simple
since we only need to</tt>
<br><tt> // change our parallel scale to encompass the
entire y range of the</tt>
<br><tt> // rubber band box. In perspective, we assume
the box is drawn on the</tt>
<br><tt> // near plane - this means that it is not possible
that someone can</tt>
<br><tt> // draw a rubber band box around a nearby object
and dolly past it. It</tt>
<br><tt> // also means that you won't get very close
to distance objects - but that</tt>
<br><tt> // seems better than getting lost.</tt>
<br><tt> ASSERT(pCam->GetParallelProjection() == TRUE);</tt>
<br><tt> // the new scale is just based on the y size of the rubber
band box</tt>
<br><tt> // compared to the y size of the window</tt>
<br><tt> double newscale = pCam->GetParallelScale();</tt>
<br><tt> newscale = newscale * m_current.Width() / viewdims.Width();</tt>
<br><tt> TRACE("CFEvisGLView::DoZoomWindow, newscale=%f\n", newscale);</tt><tt></tt>
<p><tt> // now we can actually modify the camera</tt>
<br><tt> pCam->SetFocalPoint(newfocalpoint[0], newfocalpoint[1], newfocalpoint[2]);</tt>
<br><tt> pCam->SetPosition(newposition[0], newposition[1], newposition[2]);</tt>
<br><tt> pCam->SetParallelScale(newscale);</tt><tt></tt>
<p><tt> // redraw thus erasing rubberbanded box</tt>
<br><tt> Invalidate(FALSE);</tt>
<br><tt>}</tt>
<br><tt></tt> </html>