VTK 模型的旋转与平移

摘要:
当从外界读入STL等三维模型时,其会按照它内部的坐标位置进行显示。但是在实际应用中,有可能需要人为地对这个模型在空间中进行旋转、平移或缩放等操作。VTK中有许多和旋转、平移相关的函数,下面一一进行测试。RotateX、RotateY、RotateZRotatetheProp3DindegreesabouttheX/Y/Zaxisusingtherighthandrule.TheaxisistheProp3D'sX/Y/Zaxis,whichcanchangeasotherrotationsareperformed.即前一次的旋转会影响到后一次。GetOrientation:ReturnstheorientationoftheProp3DassvectorofX,YandZrotation.TheorderinginwhichtheserotationsmustbedonetogeneratethesamematrixisRotateZ,RotateX,andfinallyRotateY.即按照Z-X-Y的顺序将世界坐标系绕自身旋转即可得到当前姿态。RotateWXYZRotatetheProp3Dindegreesaboutanarbitraryaxisspecifiedbythelastthreearguments.Theaxisisspecifiedinworldcoordinates.该函数的后三个参数指定旋转方向。SetOriginSettheoriginoftheProp3D.Thisisthepointaboutwhichallrotationstakeplace.调用RotateX或RotateWXYZ等旋转函数时会默认旋转中心在原点,即会绕着沿着某一方向旋转。

当从外界读入STL等三维模型时,其会按照它内部的坐标位置进行显示。因此它的位置和大小是确定的。但是在实际应用中,有可能需要人为地对这个模型在空间中进行旋转、平移或缩放等操作。VTK中有许多和旋转、平移相关的函数,下面一一进行测试。

  • RotateX、RotateY、RotateZ(绕自身坐标轴旋转

Rotate the Prop3Din degreesabout the X/Y/Z axis using theright hand rule. The axis isthe Prop3D's X/Y/Z axis, which can change as other rotations are performed. 即前一次的旋转会影响到后一次。

假设物体坐标系开始与世界坐标系重合,先后调用RotateZ(90)、RotateX(90)的结果如下图所示:

VTK 模型的旋转与平移第1张

使用GetOrientation可以获取当前物体的姿态信息,结果为(90, 0, 90)。GetOrientation:Returns the orientation of the Prop3D as s vector of X,Y and Z rotation. The ordering in which these rotations must be done to generate the same matrix isRotateZ, RotateX, and finally RotateY. 即按照Z-X-Y的顺序将世界坐标系绕自身旋转即可得到当前姿态。

  • RotateWXYZ(绕世界坐标系旋转

Rotate the Prop3D in degrees about anarbitrary axis specified by the last three arguments. The axis is specified in world coordinates. 该函数的后三个参数指定旋转方向(可以是任意方向,不一定非得是坐标轴方向)。如按世界坐标系的X轴旋转可写为RotateWXYZ(deg, 1, 0, 0),按世界坐标系的Z轴旋转可写为RotateWXYZ(deg, 0, 0, 1)。同样是先后调用RotateWXYZ(90,0,0,1)、RotateWXYZ(90,1,0,0)得到的结果如下:

VTK 模型的旋转与平移第2张

此时调用GetOrientation返回值是:(0, -90, 90),即将世界坐标系先绕自身Z轴旋转90°,再绕X轴旋转0°,最后绕Y轴旋转-90°即可到达当前姿态。

  • SetOrientation(x, y, z) —— 通过先绕Z轴,然后绕X轴,最后绕Y轴旋转,从而来确定Prop的方向。
  • AddOrientation(a1, a2,a3) —— 在当前Prop方向增加a1, a2, a3增量。
  • SetOrigin(设置旋转中心点)

Set the origin of the Prop3D. This is the point about which all rotations take place. 调用RotateX或RotateWXYZ等旋转函数时会默认旋转中心在原点,即会绕着(0, 0, 0)沿着某一方向旋转。通过调用SetOrigin函数可以改变旋转点的位置。例如一个长宽高都是100的立方体,绕自身Z轴旋转45°,下图左边是默认旋转中心在原点,右边是调用SetOrigin设置旋转中心在(50,0,0)的结果

VTK 模型的旋转与平移第3张VTK 模型的旋转与平移第4张

  • SetPosition、AddPosition(设置物体在世界坐标系中的位置)

SetPosition(x, y, z)—— 指定vtkProp3D对象在世界坐标系中的位置。AddPosition(deltaX, deltaY, deltaZ) —— 用指定的X、Y、Z三个方向的增量来平移Prop。如下图中立方体开始在原点处,调用SetPosition(50,0,0)后其位置变为(50,0,0)。可以通过GetPosition函数查看物体在世界坐标系中的位置。

VTK 模型的旋转与平移第5张

  • SetUserTransform、GetUserTransform

The most important aspect to applying transformation matrices is to understand the order inwhich the transformations are applied.Most of the methods for manipulating this transformation, e.g. Translate, Rotate, and Concatenate, can operate in eitherPreMultiply (the default)or PostMultiply mode. In PreMultiply mode, the translation, concatenation, etc. will occur before any transformations which are represented by the current matrix. In PostMultiply mode, the additional transformation will occur after any transformations represented by the current matrix.

进行变换时的顺序非常重要,对于变换矩阵VTK里是用以下的顺序来应用这些变换的:

VTK 模型的旋转与平移第6张

1. 移动Prop到原点;

2. 缩放;

3. 绕Y轴旋转;

4. 绕X轴旋转;

5. 绕Z轴旋转;

6. 从原点中移动回原来的位置;

7. 平移。

因为默认是进行左乘所以进行变换时先调用的最后才变换(即逆序),下面的代码实现了公式中的变换:

1 vtkTransform *myTrans =vtkTransform::New ();
2 myTrans->Translate (position[0],position[1],position[2]);
3 myTrans->Translate (origin[0],origin[1],origin[2]);
4 myTrans->RotateZ (orientation[2]);
5 myTrans->RotateX (orientation[0]);
6 myTrans->RotateZ (orientation[1];
7 myTrans->Scale (scale[0],scale[1],scale[2]);
8 myTrans->Translate (-origin[0],-origin[1],-origin[2]);
9 
10 actor->SetUserTransform(myTrans);

vtkTransform::PreMultiply()用于设置左乘.Sets the internal state of the transform to PreMultiply. All subsequent operations will occur before those already represented in the current transformation. In homogeneous matrix notation, M = M*A where M is the current transformation matrix and A is the applied matrix. The default is PreMultiply.

vtkTransform::PostMultiply()用于设置右乘,Sets the internal state of the transform to PostMultiply.M = A*M where M is the current transformation matrix and A is the applied matrix.

如下所示,左边平面先旋转45°再沿X轴正方向移动2个单位;右边平面先沿X轴正方向移动2个单位,然后旋转45°(旋转中心在原点)。可以看出函数调用顺序颠倒一下产生了截然不同的两种结果(Wealways specify transformations in the reverse order of their application)

VTK 模型的旋转与平移第7张VTK 模型的旋转与平移第8张

  • SetUserMatrix、GetUserMatrix

The UserMatrix can be used in place of UserTransform.Transformation matrices can be combined by matrix multiplication to achieve combinationsof translation, rotation, and scaling. It is possible for a single transformation matrix to represent alltypes of transformation simultaneously.

下面代码将物体绕Z轴旋转45°,并移动到(50, 50, 50)处

1 trans = [0.707107,  -0.707107,  0,   50,
2          0.707107,   0.707107,  0,   50,
3          0,          0,         1,   50,
4          0,          0,         0,   1]
5           
6 mat =vtk.vtkMatrix4x4()  
7 mat.DeepCopy(trans)
8 
9 actor.SetUserMatrix(mat)

VTK 模型的旋转与平移第9张

  • GetMatrix

UserMatrix is one you can assign yourself to an actor or a top-level composite assembly of actors. Matrix is computed automatically from any position, rotation or scale the actor may have, in addition to the UserMatrix.Calling GetMatrix should always give you the exact matrix applied to an actorto get it to from whatever its own "model space" is to VTK world space.UserMatrix is nullptr until you set it, or until the actor is added as part of an assembly, where the parent assembly may set user matrices directly for its constituent parts.You can't set the matrix directly, but you can set the UserMatrix directly.

GetMatrix与GetUserMatrix函数有很大区别:GetUserMatrix用来获取用户设置的变换矩阵,如果用户没有设置则会返回空,而GetMatrix则始终都会返回场景中物体相对世界坐标系的变换矩阵。    

1 import vtk
2  
3 # create a rendering window and renderer
4 ren =vtk.vtkRenderer()
5 renWin =vtk.vtkRenderWindow()
6 renWin.AddRenderer(ren)
7  
8 # create a renderwindowinteractor
9 iren =vtk.vtkRenderWindowInteractor()
10 iren.SetRenderWindow(renWin)
11  
12 # create plane source
13 plane =vtk.vtkPlaneSource()
14 plane.SetXResolution(1)
15 plane.SetYResolution(1)
16 plane.SetCenter(0,0,0)
17 plane.SetNormal(0,0,1)
18 
19 # mapper
20 mapper =vtk.vtkPolyDataMapper()
21 mapper.SetInputConnection(plane.GetOutputPort())
22  
23 # actor
24 actor =vtk.vtkActor()
25 actor.SetMapper(mapper)
26 actor.GetProperty().SetRepresentationToWireframe()
27 
28 # assign actor to the renderer
29 ren.AddActor(actor)
30  
31 # create coordinate axes inthe render window
32 axes =vtk.vtkAxesActor() 
33 axes.SetTotalLength(1, 1, 1)
34 axes.SetShaftType(0) 
35 axes.SetAxisLabels(0) 
36 axes.SetCylinderRadius(0.02) 
37 ren.AddActor(axes)
38   
39 style =vtk.vtkInteractorStyleTrackballCamera()
40 style.SetDefaultRenderer(ren)
41 iren.SetInteractorStyle(style)
42 
43 
44 actor.RotateZ(45)
45 actor.SetPosition(2,0,0)
46 
47 print actor.GetMatrix()
48 print actor.GetUserMatrix()
49 print actor.GetUserTransform ()
50 print '---------------------------'
51 
52 trans =vtk.vtkTransform()
53 trans.RotateZ(-45)
54 trans.Translate(-2, 0, 0)
55 actor.SetUserTransform(trans)
56 
57 print actor.GetMatrix()
58 print actor.GetUserMatrix()
59 print actor.GetUserTransform ()
60 
61 
62 camera =vtk.vtkCamera()
63 camera.ParallelProjectionOn()
64 ren.SetActiveCamera(camera)
65 ren.ResetCamera()
66 
67 # enable user interfaceinteractor
68 iren.Initialize()
69 renWin.Render()
70 iren.Start()

VTK 模型的旋转与平移第10张VTK 模型的旋转与平移第11张

先将平面绕Z轴旋转45°,再移动到(2,0,0)位置,三个函数输出如下图所示。由于没有显式调用SetUserMatrix或SetUserTransform设置UserMatrix,因此GetUserMatrix和GetUserTransform函数返回均为None。

VTK 模型的旋转与平移第12张

然后将平面沿X轴负方向平移2个单位,再绕Z轴旋转-45°,将平面变换回初始位置(如果想先旋转再平移将其变换回初始位置,则要重新设置旋转中心,否则旋转时会绕原点旋转)。从下图可以看出GetMatrix函数返回了单位矩阵,即现在平面的位置和姿态与世界坐标系一致。GetUerMatrix和GetUserTransform返回的变换矩阵一样:T=Rz(-45°)·T(-2, 0, 0),为平移和旋转所构成的变换矩阵。

VTK 模型的旋转与平移第13张

VTK 模型的旋转与平移第14张

平面由初始位置变换到新位置再变换回去,两次操作互逆,因此变换矩阵互为逆矩阵。

注意:已知B→A的齐次变换矩阵T,则A→B的齐次变换矩阵T-1如下:

VTK 模型的旋转与平移第15张

VTK 模型的旋转与平移第16张

免责声明:文章转载自《VTK 模型的旋转与平移》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇UniGui安装(01)Mac下安装SecureCRT并激活下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

数字图像处理_图像基本运算

图像基本运算 1点运算  线性点运算是指输入图像的灰度级与输出图像呈线性关系。s=ar+b  (r为输入灰度值,s为相应点的输出灰度值)。  当a=1,b=0时,新图像与原图像相同;  当a=1,b≠0时,新图像是原图像所有像素的灰度值上移或下移,是整个图像在显示时更亮或更暗;  当a>1时,新图像对比度增加;  当a<1时,新图像对比度降低;  当a<0...

旋转矩阵、欧拉角、四元数理论及其转换关系

博客转载自:http://blog.csdn.net/lql0716/article/details/72597719 1. 概述 旋转矩阵、欧拉角、四元数主要用于表示坐标系中的旋转关系,它们之间的转换关系可以减小一些算法的复杂度。 本文主要介绍了旋转矩阵、欧拉角、四元数的基本理论及其之间的转换关系。 2、原理 2.1 旋转矩阵 对于两个三维...

android绘图—Paint path 旋转

http://meteor6789.blog.163.com/blog/static/35040733201111193535153/ Piant 看一段代码: mPaint = new Paint();mPaint.setAntiAlias(true);//锯齿mPaint.setDither(true);//mPaint.setColor(0xFF3...

ORB-SLAM3 细读单目初始化过程(上)

作者:乔不思 来源:微信公众号|3D视觉工坊(系投稿) 3D视觉精品文章汇总:https://github.com/qxiaofan/awesome-3D-Vision-Papers/ 学习ORB-SLAM3单目视觉SLAM中,发现有很多知识点需要展开和深入,同时又需要对系统有整体的认知,为了强化记忆,记录该系列笔记,为自己图方便,也希望对大家有所启发。...

IOS--CALayer实现,界限、透明度、位置、旋转、缩放组合动画(转)

首先引入框架:QuartzCore.framework在头文件声明:CALayer *logoLayer{//界限CABasicAnimation *boundsAnimation = [CABasicAnimationanimationWithKeyPath:@"bounds"];boundsAnimation.fromValue = [NSValue ...

Unity 重要基础知识点

这是两个月前的学习记录,发出来了下,如果有误欢迎大家指出: 脚本生命周期 //每当脚本被加载时调用一次 // 1.   在Awake中做一些初始化操作 void Awake(){ //初始化public成员 } // 2.   在每次激活脚步时调用 void OnEnable(){} //在第一次调用Update之前调用一次Start,即使取消激活,再激...