1. VTKCamera原理
从图可以看出与相机投影相关的因素主要有:
相机位置:即相机所在的位置,用方法vtkCamera::SetPosition()设置。
相机焦点:用方法vtkCamera::SetFocusPoint()设置,默认的焦点位置在世界坐标系的原点。
朝上方向:即哪个方向为相机朝上的方向。就好比我们直立看东西,方向为头朝上,看到的东西也是直立的,如果我们倒立看某个东西,这时方向为头朝下,看到的东西当然就是倒立的。相机位置、相机焦点和朝上方向三个因素确定了相机的实际方向,即确定相机的视图。
相机vtkCamera投影示意图
投影方向:相机位置到相机焦点的向量方向即为投影方向。
投影方法:确定Actor是如何映射到像平面的。vtkCamera定义了两种投影方法,一种是正交投影(OrthographicProjection),也叫平行投影(Parallel Projection),即进入相机的光线与投影方向是平行的。另一种是透视投影(PerspectiveProjection),即所有的光线相交于一点。
视角:透视投影时需要指定相机的视角(View Angle),默认的视角大小为30º,可以用方法vtkCamera::SetViewAngle()设置。
前后裁剪平面:裁剪平面与投影方向相交,一般与投影方向也是垂直的。裁剪平面主要用于评估Actor与相机距离的远近,只有在前后裁剪平面之间的Actor才是可见的。裁剪平面的位置可以用方法vtkCamera::SetClippingRange()设置。
如果你想获取vtkRenderer里默认的相机,可以用方法vtkRenderer::GetActiveCamera()。
相机vtkCamera的使用方法:
1 vtkSmartPointer<vtkCamera>myCamera = vtkSmartPointer<vtkCamera>::New(); 2 myCamera->SetClippingRange(0.0475, 2.3786); //这些值随便设置的,为了演示用法而已 3 myCamera->SetFocalPoint(0.0573, -0.2134, -0.0523); 4 myCamera->SetPosition(0.3245, -0.1139, -0.2932); 5 myCamera->ComputeViewPlaneNormal(); 6 myCamera->SetViewUp(-0.2234, 0.9983, 0.0345);
上述用SetClippingRange();SetFocalPoint();SetPosition()分别设置相机的前后裁剪平面,焦点和位置。ComputeViewPlaneNormal()方法是根据设置的相机位置、焦点等信息,重新计算视平面(View Plane)的法向量。一般该法向量与视平面是垂直的,如果不是垂直的话,Actor等看起来会有一些特殊的效果,如错切。SetViewUp()方法设置相机朝上方向。最后用vtkRenderer::SetActiveCamera()把相机设置到渲染场景中。
相机运动方向示意图
2.坐标系统及空间变换
计算机图形学里常用的坐标系统主要有四种,分别是:Model坐标系统、World坐标系统、View坐标系统和Display坐标系统,以及两种表示坐标点的方式:以屏幕像素值为单位和归一化坐标值(各坐标轴取值都为[-1, 1])。它们之间的关系如图所示。
Model坐标系统是定义模型时所采用的坐标系统,通常是局部的笛卡尔坐标系。例如,我们要定义一个表示球体的Actor,一般的做法是将该球体定义在一个柱坐标系统里。
World坐标系统是放置Actor的三维空间坐标系,Actor其中的一个功能就是负责将模型从Model坐标系统变换到World坐标系统。每一个模型可以定义有自己的Model坐标系统,但World坐标系只有一个,每一个Actor必须通过放缩、旋转、平移等操作将Model坐标系变换到World坐标系。World坐标系同时也是相机和光照所在的坐标系统。
View坐标系统表示的是相机所看见的坐标系统。X、Y、Z轴取值为[-1, 1],X、Y值表示像平面上的位置,Z值表示到相机的距离。相机负责将World坐标系变换到View坐标系。
Model、World、View和Display坐标系统
Display坐标系统跟View坐标系统类似,但是各坐标轴的取值不是[-1, 1],而是使用屏幕像素值。屏幕上显示的不同窗口的大小会影响View坐标系的坐标值[-1, 1]到Display坐标系的映射。可以把不同的渲染场景放在同一个窗口进行显示,例如,在一个窗口里,分为左右两个渲染场景,这左右的渲染场景(vtkRenderer)就是不同的视口(Viewport)。例子Viewport演示了把一个窗口分为四个视口,用vtkRenderer::SetViewport()来设置视口的范围(取值为[0, 1]):
1 renderer1->SetViewport(0.0, 0.0, 0.5, 0.5); 2 renderer2->SetViewport(0.5, 0.0, 1.0, 0.5); 3 renderer3->SetViewport(0.0, 0.5, 0.5, 1.0); 4 renderer4->SetViewport(0.5, 0.5, 1.0, 1.0);
程序执行结果如图所示:
执行结果
在VTK里,Model坐标系统用得比较少,其他三种坐标系统经常使用。根据坐标点单位、取值范围等不同,可以将坐标系统分为:
l DISPLAY — X、Y轴的坐标取值为渲染窗口的像素值。坐标原点位于渲染窗口的左下角,这个对于VTK里所有的二维坐标系统都是一样的,且VTK里的坐标系统都是采用右手坐标系。
l NORMALIZEDDISPLAY — X、Y轴坐标取值范围为[0, 1],跟DISPLAY一样,也是定义在渲染窗口里的。
l VIEWPORT— X、Y的坐标值定义在视口或者渲染器(Renderer)里。
l NORMALIZEDVIEWPORT — X、Y坐标值定义在视口或渲染器里,取值范围为[0, 1]。
l VIEW— X、Y、Z坐标值定义在相机所在的坐标系统里,取值范围为[-1, 1],Z值表示深度信息。
l WORLD — X、Y、Z坐标值定义在世界坐标系统,参考图3.9。
l USERDEFINED— 用户自定义坐标系统。
vtkCoordinate类提供的设置以上坐标系统的方法是:
SetCoordinateSystemToDisplay ()
SetCoordinateSystemToNormalizedDisplay ()
SetCoordinateSystemToViewport ()
SetCoordinateSystemToNormalizedViewport ()
SetCoordinateSystemToView ()
SetCoordinateSystemToWorld ()