I’m assuming we’re using a parallel projection for 3D environment.
We can find the project transform matrix logic at VTK code source.
//------------------------------------------------------------------------------
// Compute the projection transform matrix. This is used in converting
// between view and world coordinates.
void vtkCamera::ComputeProjectionTransform(double aspect, double nearz, double farz)
<--
if (this->ParallelProjection)
{
// set up a rectangular parallelipiped
double width = this->ParallelScale * aspect;
double height = this->ParallelScale;
double xmin = (this->WindowCenter[0] - 1.0) * width;
double xmax = (this->WindowCenter[0] + 1.0) * width;
double ymin = (this->WindowCenter[1] - 1.0) * height;
double ymax = (this->WindowCenter[1] + 1.0) * height;
this->ProjectionTransform->Ortho(
xmin, xmax, ymin, ymax, this->ClippingRange[0], this->ClippingRange[1]);
}
//------------------------------------------------------------------------------
// The orthographic perspective maps [xmin,xmax], [ymin,ymax], [-znear,-zfar]
// to [-1,+1], [-1,+1], [-1,+1].
// From the OpenGL Programmer's guide, 2nd Ed.
void vtkPerspectiveTransform::Ortho(
double xmin, double xmax, double ymin, double ymax, double znear, double zfar)
{
double matrix[4][4];
vtkMatrix4x4::Identity(*matrix);
matrix[0][0] = 2 / (xmax - xmin);
matrix[1][1] = 2 / (ymax - ymin);
matrix[2][2] = -2 / (zfar - znear);
matrix[0][3] = -(xmin + xmax) / (xmax - xmin);
matrix[1][3] = -(ymin + ymax) / (ymax - ymin);
matrix[2][3] = -(znear + zfar) / (zfar - znear);
this->Concatenate(*matrix);
}
The ParallelScale is bigger, xmax - xmin
and ymax - ymin
is bigger, matrix[0][0] and matrix[1][1] is smaller.
So we can get that the display length of model multiply the camera’s ParallelScale is a constant.
The math model about ParallelScale changing is
and its inverse (zoom in and zoom out).
You can see its not linear at drawing tool: https://www.desmos.com/calculator
void vtkInteractorStyleTrackballCamera::OnMouseWheelForward()
{
//...
double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
this->Dolly(pow(1.1, factor));
//...
}
void vtkInteractorStyleTrackballCamera::Dolly(double factor)
{
//...
if (camera->GetParallelProjection())
{
camera->SetParallelScale(camera->GetParallelScale() / factor);
}
}