1. 程式人生 > >VTK修煉之道8_三維場景基本要素:相機

VTK修煉之道8_三維場景基本要素:相機

1.VTK中相機原理及控制屬性

觀眾的眼睛就好比三維渲染場景中的相機,VTK則是用vtkCamera類來表示三維渲染場景中的相機。vtkCamera負責把三維場景投影到二維平面,如螢幕、影象等。下圖為相機投影示意圖:

從上圖可以看出與相機投影相關的因素主要有:
相機位置:即相機所在的位置,用方法vtkCamera::SetPosition()設定。
相機焦點:用方法vtkCamera::SetFocusPoint()設定,預設的焦點位置在世界座標系的原點
朝上方向:即哪個方向為相機朝上的方向。就好比我們直立看東西,方向為頭朝上,看到的東西也是直立的,如果我們倒立看某個東西,這時方向為頭朝下,看到的東西當然就是倒立的。相機位置、相機焦點和朝上方向三個因素確定了相機的實際方向,即確定相機的檢視。 投影方向
:相機位置到相機焦點的向量方向即為投影方向。
投影方法:確定Actor是如何對映到像平面的。vtkCamera定義了兩種投影方法,一種是正交投影(OrthographicProjection),也叫平行投影(Parallel Projection),即進入相機的光線與投影方向是平行的。另一種是透視投影(PerspectiveProjection),即所有的光線相交於一點。
視角:透視投影時需要指定相機的視角(View Angle),預設的視角大小為30º,可以用方法vtkCamera::SetViewAngle()設定。
前後裁剪平面:裁剪平面與投影方向相交,一般與投影方向也是垂直的。裁剪平面主要用於評估Actor與相機距離的遠近,只有在前後裁剪平面之間的Actor才是可見的。裁剪平面的位置可以用方法vtkCamera::SetClippingRange()設定。

2.相機使用方法示例

首先要記住一點的是Camera是Renderer(三維場景)的構成要素。 如果想獲取vtkRenderer裡預設的相機,可以用方法vtkRenderer::GetActiveCamera()。
相機vtkCamera的使用方法:
vtkSmartPointer<vtkCamera>myCamera = vtkSmartPointer<vtkCamera>::New();
myCamera->SetClippingRange(0.0475,2.3786); //這些值隨便設定的,東靈提供的
myCamera->SetFocalPoint(0.0573,-0.2134, -0.0523);
myCamera->SetPosition(0.3245,-0.1139, -0.2932);//是否要保證相機位置-焦點向量 與 相機位置-向上方向 正交??
myCamera->ComputeViewPlaneNormal();//重新計算視平面法向量  平行於 相機-焦點
myCamera->SetViewUp(-0.2234,0.9983, 0.0345);
renderer->SetActiveCamera(myCamera); //啟用新生成的相機

上述用SetClippingRange();SetFocalPoint();SetPosition()分別設定相機的前後裁剪平面,焦點和位置。ComputeViewPlaneNormal()方法是根據設定的相機位置、焦點等資訊,重新計算視平面(View Plane)的法向量。一般該法向量與視平面是垂直的,如果不是垂直的話,Actor等看起來會有一些特殊的效果,如錯切。SetViewUp()方法用於設定相機朝上方向。最後用方法vtkRenderer::SetActiveCamera()把相機設定到渲染場景中。
vtkCamera除了提供設定與相機投影因素相關的方法之外,還提供了大量的控制相機運動的方法,如:vtkCamera::Dolly(),vtkCamera::Roll(),vtkCamera::Azimuth(),vtkCamera::Yaw(),vtkCamera::Elevation(),vtkCamera::Pitch(),vtkCamera::Zoom()。這些方法具體表示相機是怎麼運動,以及相對哪個位置或者方向運動。

3.相機運動方向示意圖


關於控制相機的運動更詳細的方法應該參考Camera說明文件。

4.相機簡單測試

	vtkSmartPointer<vtkCamera> mycamera =
		vtkSmartPointer<vtkCamera>::New();
	mycamera->SetFocalPoint(0,0,0);
	mycamera->SetPosition(-5,0,0);
	mycamera->SetClippingRange(5.5,6.5);
	mycamera->ComputeViewPlaneNormal();
	mycamera->SetViewUp(0,1,0);
	renderer->SetActiveCamera(mycamera);
vtkSmartPointer<vtkCamera> mycamera =
		vtkSmartPointer<vtkCamera>::New();
	mycamera->SetFocalPoint(0,0,0);
	mycamera->SetPosition(-10,0,0);
	mycamera->SetClippingRange(10.5,11.5);
	mycamera->ComputeViewPlaneNormal();
	mycamera->SetViewUp(0,1,0);
	renderer->SetActiveCamera(mycamera);
	vtkSmartPointer<vtkCamera> mycamera =
		vtkSmartPointer<vtkCamera>::New();
	mycamera->SetFocalPoint(0,0,0);
	mycamera->SetPosition(-10,0,0);
	mycamera->SetClippingRange(5,9);
	mycamera->ComputeViewPlaneNormal();
	mycamera->SetViewUp(0,1,0);
	renderer->SetActiveCamera(mycamera);
前後裁剪平面不合法。