[vtkusers] Error in vtkRenderer::ResetCamera
Scott Johnson
Scott.Johnson at neuwave.com
Tue Nov 24 17:52:45 EST 2009
Hello Folks,
I'm new to VTK and was trying to figure out some clipping issues in
vtkRenderer. While poking around in the code I ran across
vtkRenderer::ResetCamera and a potential coding error. It seems that
'vn' is never initialized prior to being used. I'll include the code
for the method. (I just checked out a new version from the HEAD of the
cvs repository.)
I also added a comment and a possible fix.
I'd be interested to hear if this a real problem or if I'm just
imagining it.
Thanks
-- Scott
void vtkRenderer::ResetCamera(double bounds[6])
{
double center[3];
double distance;
double vn[3], *vup;
this->GetActiveCamera();
if ( this->ActiveCamera != NULL )
{
this->ActiveCamera->GetViewPlaneNormal(vn);
}
else
{
vtkErrorMacro(<< "Trying to reset non-existant camera");
return;
}
center[0] = (bounds[0] + bounds[1])/2.0;
center[1] = (bounds[2] + bounds[3])/2.0;
center[2] = (bounds[4] + bounds[5])/2.0;
double w1 = bounds[1] - bounds[0];
double w2 = bounds[3] - bounds[2];
double w3 = bounds[5] - bounds[4];
w1 *= w1;
w2 *= w2;
w3 *= w3;
double radius = w1 + w2 + w3;
// If we have just a single point, pick a radius of 1.0
radius = (radius==0)?(1.0):(radius);
// compute the radius of the enclosing sphere
radius = sqrt(radius)*0.5;
// default so that the bounding sphere fits within the view fustrum
// compute the distance from the intersection of the view frustum with
the
// bounding sphere. Basically in 2D draw a circle representing the
bounding
// sphere in 2D then draw a horizontal line going out from the center
of
// the circle. That is the camera view. Then draw a line from the
camera
// position to the point where it intersects the circle. (it will be
tangent
// to the circle at this point, this is important, only go to the
tangent
// point, do not draw all the way to the view plane). Then draw the
radius
// from the tangent point to the center of the circle. You will note
that
// this forms a right triangle with one side being the radius, another
being
// the target distance for the camera, then just find the target dist
using
// a sin.
double
angle=vtkMath::RadiansFromDegrees(this->ActiveCamera->GetViewAngle());
double parallelScale=radius;
this->ComputeAspect();
double aspect[2];
this->GetAspect(aspect);
if(aspect[0]>=1.0) // horizontal window, deal with vertical
angle|scale
{
if(this->ActiveCamera->GetUseHorizontalViewAngle())
{
angle=2.0*atan(tan(angle*0.5)/aspect[0]);
}
}
else // vertical window, deal with horizontal angle|scale
{
if(!this->ActiveCamera->GetUseHorizontalViewAngle())
{
angle=2.0*atan(tan(angle*0.5)*aspect[0]);
}
parallelScale=parallelScale/aspect[0];
}
distance =radius/sin(angle*0.5);
// check view-up vector against view plane normal
vup = this->ActiveCamera->GetViewUp();
// SHOULD THIS NEXT LINE BE ADDED???
// vn = this->ActiveCamera->GetViewPlaneNormal();
if ( fabs(vtkMath::Dot(vup,vn)) > 0.999 )
{
vtkWarningMacro(<<"Resetting view-up since view plane normal is
parallel");
this->ActiveCamera->SetViewUp(-vup[2], vup[0], vup[1]);
}
// update the camera
this->ActiveCamera->SetFocalPoint(center[0],center[1],center[2]);
this->ActiveCamera->SetPosition(center[0]+distance*vn[0],
center[1]+distance*vn[1],
center[2]+distance*vn[2]);
this->ResetCameraClippingRange( bounds );
// setup default parallel scale
this->ActiveCamera->SetParallelScale(parallelScale);
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20091124/bff01aca/attachment.htm>
More information about the vtkusers
mailing list