VTK——模型的旋轉與平移

在計算機圖形學中,三維座標點用齊次座標表示。利用其次座標,可以將空間變換用4x4的矩陣來表示。這些變換都可以用矩陣的運算完成。
當從外界讀入STL等三維模型時,其會按照它內部的座標位置進行顯示。因此它的位置和大小是確定的。但是在實際應用中,有可能需要人爲地對這個模型在空間中進行旋轉、平移或縮放等操作。VTK中有許多和旋轉、平移相關的函數

VTK相關的類有:

vtkTransform, vtkTransformFilter, vtkMatrix4x4等

相關的方法有:

• RotateX(angle)、RotateY(angle)、RotateZ(angle)

• RotateWXYZ(angle,x,y,z)

• Scale(x,y,z)

• Translate(x,y,z)

• SetMatrix(m)、GetMatrix(m)

• PostMultiply()、PreMultiply()

• SetPosition(x,y,z)、GetPosition(x,y,z)

• SetOrientation(x,y,z)、 GetOrientation(x,y,z)

• SetScale(sx,sy,sz)

• SetOrigin(x,y,z)、GetOrigin

RotateX、RotateY、RotateZ(繞自身座標軸旋轉)

Rotate the Prop3D in degrees about the X/Y/Z axis using the right hand rule. The axis is the Prop3D’s X/Y/Z axis, which can change as other rotations are performed. 即前一次的旋轉會影響到後一次。

假設物體座標系開始與世界座標系重合,先後調用RotateZ(90)、RotateX(90)的結果如下圖所示:

使用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 is RotateZ, RotateX, and finally RotateY. 即按照Z-X-Y的順序將世界座標系繞自身旋轉即可得到當前姿態。

RotateWXYZ(繞世界座標系旋轉)

Rotate the Prop3D in degrees about an arbitrary 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)得到的結果如下:
在這裏插入圖片描述
  此時調用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)的結果
在這裏插入圖片描述
在這裏插入圖片描述
SetPosition、AddPosition(設置物體在世界座標系中的位置)
  SetPosition(x, y, z)—— 指定vtkProp3D對象在世界座標系中的位置。AddPosition(deltaX, deltaY, deltaZ) —— 用指定的X、Y、Z三個方向的增量來平移Prop。如下圖中立方體開始在原點處,調用SetPosition(50,0,0)後其位置變爲(50,0,0)。可以通過GetPosition函數查看物體在世界座標系中的位置。
在這裏插入圖片描述
SetUserTransform、GetUserTransform
  The most important aspect to applying transformation matrices is to understand the order in which the transformations are applied. Most of the methods for manipulating this transformation, e.g. Translate, Rotate, and Concatenate, can operate in either PreMultiply (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裏是用以下的順序來應用這些變換的:
  
TT=T(px+ox,py+oy,pz+oz)⋅RZ⋅RX⋅RY⋅S(sx,sy,sz)⋅T(−ox,−oy,−oz)TT=T(px+ox,py+oy,pz+oz)⋅RZ⋅RX⋅RY⋅S(sx,sy,sz)⋅T(−ox,−oy,−oz)

1. 移動Prop到原點;

2. 縮放;

3. 繞Y軸旋轉;

4. 繞X軸旋轉;

5. 繞Z軸旋轉;

6. 從原點中移動回原來的位置;

7. 平移。

因爲默認是進行左乘所以進行變換時先調用的最後才變換(即逆序),下面的代碼實現了公式中的變換:

vtkTransform *myTrans = vtkTransform::New ();
myTrans->Translate (position[0],position[1],position[2]);
myTrans->Translate (origin[0],origin[1],origin[2]);
myTrans->RotateZ (orientation[2]);
myTrans->RotateX (orientation[0]);
myTrans->RotateZ (orientation[1];
myTrans->Scale (scale[0],scale[1],scale[2]);
myTrans->Translate (-origin[0],-origin[1],-origin[2]);

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°(旋轉中心在原點)。可以看出函數調用順序顛倒一下產生了截然不同的兩種結果(We always specify transformations in the reverse order of their application)
在這裏插入圖片描述
在這裏插入圖片描述
SetUserMatrix、GetUserMatrix
  The UserMatrix can be used in place of UserTransform. Transformation matrices can be combined by matrix multiplication to achieve combinations of translation, rotation, and scaling. It is possible for a single transformation matrix to represent all types of transformation simultaneously.

下面代碼將物體繞Z軸旋轉45°,並移動到(50, 50, 50)處
trans = [0.707107, -0.707107, 0, 50,
0.707107, 0.707107, 0, 50,
0, 0, 1, 50,
0, 0, 0, 1]

mat = vtk.vtkMatrix4x4()
mat.DeepCopy(trans)

actor.SetUserMatrix(mat)

在這裏插入圖片描述
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 actor to 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則始終都會返回場景中物體相對世界座標系的變換矩陣。

在這裏插入圖片描述
在這裏插入圖片描述
 先將平面繞Z軸旋轉45°,再移動到(2,0,0)位置,三個函數輸出如下圖所示。由於沒有顯式調用SetUserMatrix或SetUserTransform設置UserMatrix,因此GetUserMatrix和GetUserTransform函數返回均爲None。
在這裏插入圖片描述

然後將平面沿X軸負方向平移2個單位,再繞Z軸旋轉-45°,將平面變換回初始位置(如果想先旋轉再平移將其變換回初始位置,則要重新設置旋轉中心,否則旋轉時會繞原點旋轉)。從下圖可以看出GetMatrix函數返回了單位矩陣,即現在平面的位置和姿態與世界座標系一致。GetUerMatrix和GetUserTransform返回的變換矩陣一樣:T=Rz(-45°)·T(-2, 0, 0),爲平移和旋轉所構成的變換矩陣。
在這裏插入圖片描述
在這裏插入圖片描述

平面由初始位置變換到新位置再變換回去,兩次操作互逆,因此變換矩陣互爲逆矩陣。

注意:已知B→A的齊次變換矩陣T,則A→B的齊次變換矩陣T-1如下:

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章