<!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).&nbsp;
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.&nbsp; 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.&nbsp; 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>&lt;snip></tt>
<br><tt>&nbsp;// zoom window</tt>
<br><tt>&nbsp;void DoZoomWindow(CPoint point);</tt>
<br><tt>&nbsp;CPoint&nbsp;&nbsp;&nbsp; m_startdrag;</tt>
<br><tt>&nbsp;CRect&nbsp;&nbsp;&nbsp; m_previous;</tt>
<br><tt>&nbsp;CRect&nbsp;&nbsp;&nbsp; m_current;</tt>
<br><tt>&nbsp;BOOL&nbsp;&nbsp;&nbsp; m_dragging;</tt>
<br><tt>&lt;/snip></tt>
<br><tt>};</tt>
<br><tt></tt>&nbsp;<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>&nbsp;CRect viewdims;</tt>
<br><tt>&nbsp;CPoint zoomboxcenter;</tt><tt></tt>
<p><tt>&nbsp;vtkCamera *pCam = Renderer->GetActiveCamera();</tt><tt></tt>
<p><tt>&nbsp;// get view dimensions</tt>
<br><tt>&nbsp;GetClientRect(&amp;viewdims);</tt><tt></tt>
<p><tt>&nbsp;// get box center point in pixels</tt>
<br><tt>&nbsp;zoomboxcenter = m_current.CenterPoint();</tt>
<br><tt>&nbsp;// correct</tt>
<br><tt>&nbsp;// zoomboxcenter.y = viewdims.CenterPoint().y - zoomboxcenter.y;</tt>
<br><tt>&nbsp;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // Convert the focal point to a display coordinate
in order to get the</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // depth of the focal point in display units</tt>
<br><tt>&nbsp;double focalpoint[3];</tt>
<br><tt>&nbsp;pCam->GetFocalPoint(focalpoint);</tt>
<br><tt>&nbsp;Renderer->SetWorldPoint(focalpoint[0], focalpoint[1], focalpoint[2],
1.0);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; Renderer->WorldToDisplay();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; double displaypoint[3];</tt>
<br><tt>&nbsp;Renderer->GetDisplayPoint(displaypoint);</tt>
<br><tt>&nbsp;double focaldepth = displaypoint[2];</tt>
<br><tt></tt>&nbsp;
<br><tt></tt>&nbsp;<tt></tt>
<p><tt>&nbsp;&nbsp;&nbsp; // Convert the position of the camera to a display
coordinate in order</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // to get the depth of the camera in display
coordinates. Note this is</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // a negative number (behind the near clipping
plane of 0) but it works</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // ok anyway</tt>
<br><tt>&nbsp;double camposition[3];</tt>
<br><tt>&nbsp;pCam->GetPosition(camposition[0], camposition[1], camposition[2]);</tt>
<br><tt>&nbsp;Renderer->SetWorldPoint(camposition[0], camposition[1], camposition[2],
1.0);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; Renderer->WorldToDisplay();</tt>
<br><tt>&nbsp;Renderer->GetDisplayPoint(displaypoint);</tt>
<br><tt>&nbsp;double positiondepth = displaypoint[2];</tt>
<br><tt></tt>&nbsp;<tt></tt>
<p><tt>&nbsp;&nbsp;&nbsp; // Find out the world position of where our new
focal point should</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // be - it will be at the center of the box,
back at the same focal depth</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // Don't actually set it now - we need to do
all our computations before</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // we modify the camera</tt>
<br><tt>&nbsp;Renderer->SetDisplayPoint(zoomboxcenter.x, zoomboxcenter.y,
focaldepth);</tt>
<br><tt>&nbsp;Renderer->DisplayToWorld();</tt>
<br><tt>&nbsp;float newfocalpoint[4];</tt>
<br><tt>&nbsp;Renderer->GetWorldPoint(newfocalpoint);</tt>
<br><tt>&nbsp;if (newfocalpoint[3] != 0.0) {</tt>
<br><tt>&nbsp; newfocalpoint[0] = newfocalpoint[0] / newfocalpoint[3];</tt>
<br><tt>&nbsp; newfocalpoint[1] = newfocalpoint[1] / newfocalpoint[3];</tt>
<br><tt>&nbsp; newfocalpoint[2] = newfocalpoint[2] / newfocalpoint[3];</tt>
<br><tt>&nbsp;}</tt><tt></tt>
<p><tt>&nbsp;&nbsp;&nbsp; // Find out where the new camera position will
be - at the center of</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // the rubber band box at the position depth.
Don't set it yet...</tt>
<br><tt>&nbsp;&nbsp;&nbsp; Renderer->SetDisplayPoint(zoomboxcenter.x, zoomboxcenter.y,
positiondepth);</tt>
<br><tt>&nbsp;Renderer->DisplayToWorld();</tt>
<br><tt>&nbsp;float newposition[4];</tt>
<br><tt>&nbsp;Renderer->GetWorldPoint(newposition);</tt>
<br><tt>&nbsp;if (newposition[3] != 0.0) {</tt>
<br><tt>&nbsp; newposition[0] = newposition[0] / newposition[3];</tt>
<br><tt>&nbsp; newposition[1] = newposition[1] / newposition[3];</tt>
<br><tt>&nbsp; newposition[2] = newposition[2] / newposition[3];</tt>
<br><tt>&nbsp;}</tt><tt></tt>
<p><tt>&nbsp;&nbsp;&nbsp; // We figured out how to position the camera
to be centered, now we</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // need to "zoom". In parallel, this is simple
since we only need to</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // change our parallel scale to encompass the
entire y range of the</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // rubber band box. In perspective, we assume
the box is drawn on the</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // near plane - this means that it is not possible
that someone can</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // draw a rubber band box around a nearby object
and dolly past it. It</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // also means that you won't get very close
to distance objects - but that</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // seems better than getting lost.</tt>
<br><tt>&nbsp;ASSERT(pCam->GetParallelProjection() == TRUE);</tt>
<br><tt>&nbsp;// the new scale is just based on the y size of the rubber
band box</tt>
<br><tt>&nbsp;// compared to the y size of the window</tt>
<br><tt>&nbsp;double newscale = pCam->GetParallelScale();</tt>
<br><tt>&nbsp;newscale = newscale * m_current.Width() / viewdims.Width();</tt>
<br><tt>&nbsp;TRACE("CFEvisGLView::DoZoomWindow, newscale=%f\n", newscale);</tt><tt></tt>
<p><tt>&nbsp;// now we can actually modify the camera</tt>
<br><tt>&nbsp;pCam->SetFocalPoint(newfocalpoint[0], newfocalpoint[1], newfocalpoint[2]);</tt>
<br><tt>&nbsp;pCam->SetPosition(newposition[0], newposition[1], newposition[2]);</tt>
<br><tt>&nbsp;pCam->SetParallelScale(newscale);</tt><tt></tt>
<p><tt>&nbsp;// redraw thus erasing rubberbanded box</tt>
<br><tt>&nbsp;Invalidate(FALSE);</tt>
<br><tt>}</tt>
<br><tt></tt>&nbsp;</html>