We can use vtkCoordinate and vtkRenderer objects to convert point’s coordinate from a system to another one. I found vtkCoordinate called the functions of vtkViewport (vtkRenderer is child class of vtkViewport) to accomplish coordinate transformation.
class vtkViewport:
virtual void LocalDisplayToDisplay(double &x, double &y);
virtual void DisplayToNormalizedDisplay(double &u, double &v);
virtual void NormalizedDisplayToViewport(double &x, double &y);
virtual void ViewportToNormalizedViewport(double &u, double &v);
virtual void NormalizedViewportToView(double &x, double &y, double &z);
virtual void ViewToWorld(double &, double &, double &) {}
virtual void DisplayToLocalDisplay(double &x, double &y);
virtual void NormalizedDisplayToDisplay(double &u, double &v);
virtual void ViewportToNormalizedDisplay(double &x, double &y);
virtual void NormalizedViewportToViewport(double &u, double &v);
virtual void ViewToNormalizedViewport(double &x, double &y, double &z);
virtual void WorldToView(double &, double &, double &) {}
void vtkRenderer::WorldToView(double &x, double &y, double &z)
Example:
#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();
using namespace std;
int main()
{
setbuf( stdout, nullptr );
vtkSPtrNew( cone, vtkConeSource );
vtkSPtrNew( mapper, vtkPolyDataMapper );
mapper->SetInputConnection( cone->GetOutputPort() );
vtkSPtrNew( actor, vtkActor );
actor->SetMapper( mapper );
vtkSPtrNew( axes, vtkAxesActor );
double leftViewport[4] = {0.0, 0.0, 0.5, 1.0};
double rightViewport[4] = {0.5, 0.0, 1.0, 1.0};
vtkSPtrNew( leftRenderer, vtkRenderer );
leftRenderer->AddActor( actor );
leftRenderer->SetBackground( 0.4, 0.3, 0.6 );
leftRenderer->SetViewport( leftViewport );
leftRenderer->ResetCamera();
vtkSPtrNew( rightRenderer, vtkRenderer );
rightRenderer->AddActor( axes );
rightRenderer->SetViewport( rightViewport );
rightRenderer->ResetCamera();
vtkSPtrNew( renderWindow, vtkRenderWindow );
renderWindow->AddRenderer( leftRenderer );
renderWindow->AddRenderer( rightRenderer );
renderWindow->SetSize( 600, 300 );
renderWindow->Render();
vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
renderWindowInteractor->SetRenderWindow( renderWindow );
int *windowSize = renderWindow->GetSize();
printf( "window size: (%d, %d)\n", windowSize[0], windowSize[1] );
int *leftRenderSize = leftRenderer->GetSize();
printf( "leftRender size: (%d, %d)\n", leftRenderSize[0], leftRenderSize[1] );
vtkSPtrNew( coordinate, vtkCoordinate );
coordinate->SetCoordinateSystemToWorld();
double *axesPos = axes->GetPosition();
coordinate->SetValue( axesPos );
int *ptr = coordinate->GetComputedDisplayValue( rightRenderer );
printf( "axes displayPos: (%d, %d, %d)\n", ptr[0], ptr[1], ptr[2] );
ptr = coordinate->GetComputedViewportValue( leftRenderer );
printf( "axes viewportValue: (%d, %d, %d)\n", ptr[0], ptr[1], ptr[2] );
rightRenderer->SetWorldPoint( axes->GetPosition() );
rightRenderer->WorldToDisplay();
double *tmp = rightRenderer->GetDisplayPoint();
printf( "axes displayPos: (%lf, %lf, %lf)\n", tmp[0], tmp[1], tmp[2] );
renderWindowInteractor->Start();
return 0;
}
Output:
window size: (600, 300)
leftRender size: (300, 300)
axes displayPos: (450, 150, -1966393448)
axes viewportValue: (150, 150, 0)
axes displayPos: (450.000000, 150.000000, 0.612942)
It’s recommended to use vtkRenderer to convert coordinate value directly because it’s convenient and accurate.