VTK中坐标转换
通过屏幕点击的坐标获取体坐标(2D->3D)
1>获取点击位置的z
z = renderer->GetZ (static_cast<int>(selectionX),static_cast<int>(selectionY));
renderer中getZ的实现:
// Error checking// Must clear previous errors first.while(glGetError() != GL_NO_ERROR){;}// Turn of texturing in case it is on - some drivers have a problem// getting / setting pixels with texturing enabled.glDisable( GL_SCISSOR_TEST );glPixelStorei( GL_PACK_ALIGNMENT, 1 );glReadPixels( x_low, y_low,width, height,GL_DEPTH_COMPONENT, GL_FLOAT,z_data );
if z is 1.0, we assume the user has picked a point on the
screen that has not been rendered into. Use the camera’s focal
point for the z value. The test value .999999 has to be used
instead of 1.0 because for some reason our SGI Infinite Reality
engine won’t return a 1.0 from the zbuffer
如果z为1,则获取相机焦点对应屏幕坐标处的z
// Get camera focal point and position. Convert to display (screen)// coordinates. We need a depth value for z-buffer.camera = renderer->GetActiveCamera();camera->GetFocalPoint(cameraFP); cameraFP[3] = 1.0;renderer->SetWorldPoint(cameraFP[0],cameraFP[1],cameraFP[2],cameraFP[3]);renderer->WorldToDisplay();displayCoord = renderer->GetDisplayPoint();selectionZ = displayCoord[2];
2>通过vtkRenderer设置屏幕屏幕坐标并进行转换
renderer->SetDisplayPoint (display);renderer->DisplayToWorld ();
DisplayToWorld 实际调用:{this->DisplayToView(); this->ViewToWorld();}
DisplayToView实现:
size = this->VTKWindow->GetSize();if (size == NULL){return;}sizex = size[0];sizey = size[1];//2* (clickX/windowwidth) - 1vx = 2.0 * (this->DisplayPoint[0] - sizex*this->Viewport[0])/(sizex*(this->Viewport[2]-this->Viewport[0])) - 1.0;//2* (clickY/windowheight) - 1vy = 2.0 * (this->DisplayPoint[1] - sizey*this->Viewport[1])/(sizey*(this->Viewport[3]-this->Viewport[1])) - 1.0;vz = this->DisplayPoint[2];
vx和vy一定在区间[-1,1]
ViewToWorld实现:
// get the perspective transformation from the active cameravtkMatrix4x4 *matrix = this->ActiveCamera->GetCompositeProjectionTransformMatrix(this->GetTiledAspectRatio(),0,1);// use the inverse matrixvtkMatrix4x4::Invert(*matrix->Element, mat);// Transform point to world coordinatesresult[0] = x;result[1] = y;result[2] = z;result[3] = 1.0;vtkMatrix4x4::MultiplyPoint(mat,result,result);
ActiveCamera->GetCompositeProjectionTransformMatrix实现较为复杂,有时间再弄!!
3>通过vtkRenderer获取体坐标并转换
world = renderer->GetWorldPoint ();for (int i=0; i < 3; i++){this->PickPosition[i] = world[i] / world[3];}