1. 程式人生 > >【3D計算機圖形學】變換矩陣、歐拉角、四元數

【3D計算機圖形學】變換矩陣、歐拉角、四元數

遭遇 unit 額外 star 應該 detail 導致 print uic

【3D計算機圖形學】變換矩陣、歐拉角、四元數

旋轉矩陣、歐拉角、四元數主要用於:向量的旋轉、坐標系之間的轉換、角位移計算、方位的平滑插值計算。

一、變換矩陣:

首先要區分旋轉矩陣和變換矩陣:

旋轉矩陣:向量繞某一個軸旋轉,用3x3的矩陣表示。

變換矩陣:向量的移動、旋轉、縮放,用4x4的矩陣表示。

這裏額外補充一個知識,就是三維坐標變換是用4x4矩陣(采用齊次坐標)而不是3x3矩陣的原因是:統一平移和縮放(本來是向量加法來描述)為矩陣乘法的形式來計算。所以旋轉矩陣也擴展為4x4矩陣,這樣一來,平移矩陣、縮放矩陣、旋轉矩陣可以相乘最後結果為一個唯一的變換矩陣。

可以參考下面這篇文章,解釋的很清楚:

http://www.tuicool.com/articles/jMzuIfA


旋轉矩陣的推導過程網上有很多,這裏不再贅述。可以參考如下文章:

http://blog.csdn.net/ningyaliuhebei/article/details/7481679

http://blog.chinaunix.net/uid-25296429-id-5133776.html


二、歐拉角:

歐拉角的基本思想是將角位移分解為繞三個互相垂直軸的三個旋轉組成的序列。所以,歐拉旋轉的三個角,可以對應於三個旋轉矩陣。

Yaw(偏航):歐拉角向量的y軸
Pitch(俯仰):歐拉角向量的x軸
Roll(翻滾): 歐拉角向量的z軸

Unity3D中,歐拉旋轉是按照ZYX的順序旋轉的。(不同的旋轉順序最終得到的結果是不一樣的,要引起重視)


三、四元數:

四元數的定義:

一個四元數可以表示為q = w + xi + yj + zk,現在就來回答這樣一個簡單的式子是怎麽和三維旋轉結合在一起的。為了方便,我們下面使用q = ((x, y, z),w) = (v, w),其中v是向量,w是實數,這樣的式子來表示一個四元數。

我們先來看問題的答案。我們可以使用一個四元數q=((x,y,z)sinθ2, cosθ2) 來執行一個旋轉。具體來說,如果我們想要把空間的一個點P繞著單位向量軸u = (x, y, z)表示的旋轉軸旋轉θ角度,我們首先把點P擴展到四元數空間,即四元數p = (P, 0)。那麽,旋轉後新的點對應的四元數(當然這個計算而得的四元數的實部為0,虛部系數就是新的坐標)為:

p′=qpq?1


其中,q=(cosθ2, (x,y,z)sinθ2) ,q?1=q?N(q)

當然,四元數不僅可以用來方便的進行向量旋轉計算,還能夠用於平滑插值計算等。


四元數更多的介紹參看下面的鏈接;

http://www.cnblogs.com/mengdd/archive/2013/08/05/3238223.html


四、旋轉矩陣、歐拉角、四元數比較:

下面的總結來源於網絡:http://blog.csdn.net/pizi0475/article/details/6278526

任務/性質

旋轉矩陣

歐拉角

四元數

在坐標系間(物體和慣性)旋轉點

不能(必須轉換到矩陣)

不能(必須轉換到矩陣)

連接或增量旋轉

能,但經常比四元數慢,小心矩陣蠕變的情況

不能

能,比矩陣快

插值

基本上不能

能,但可能遭遇萬向鎖或其他問題

Slerp提供了平滑插值

易用程度

在內存或文件中存儲

9個數

3個數

4個數

對給定方位的表達方式是否唯一

不是,對同一方位有無數多種方法

不是,有兩種方法,它們互相為互

可能導致非法

矩陣蠕變

任意三個數都能構成合法的歐拉角

可能會出現誤差積累,從而產生非法的四元數

不同的方位表示方法適用於不同的情況。下面是我們對合理選擇格式的一些建議:

歐拉角最容易使用。當需要為世界中的物體指定方位時,歐拉角能大大的簡化人機交互,

包括直接的鍵盤輸入方位、在代碼中指定方位(如為渲染設定攝像機)、在調試中測試。這個優點不應該被忽視,不要以”優化”為名義而犧牲易用性,除非你去頂這種優化的確有效果。

如果需要在坐標系之間轉換響亮,那麽就選擇矩陣形式。當然,這並不意味著你就不能用其他格式來保存方位,並在需要的時候轉換到矩陣格式。另一種方法是用歐拉角作為方位的”主拷貝”但同時維護一個旋轉矩陣,當歐拉角發生改變時矩陣也要同時進行更新。

當需要大量保存方位數據(如:動畫)時,就使用歐拉角或四元數。歐拉角將少占用25%的內存,但它在轉換到矩陣時要稍微慢一些。如果動畫數據需要嵌套坐標系之間的連接,四元數可能是最好的選擇。

平滑的插值只能用四元數完成。如果你用其他形式,也可以先轉換到四元數然後再插值,插值完畢後再轉換回原來的形式。


五、歐拉角與四元數的轉換:

參看下面一篇文章,講的比較通俗易懂:

http://www.cnblogs.com/wqj1212/archive/2010/11/21/1883033.html


六、Unity3D中變換矩陣(平移、縮放、旋轉)、歐拉角、四元數有關的類和相互之間的轉換:

Quaternion:四元數類。

Matrix4x4:變換矩陣類。

Vector3:歐拉角用此表示就可以了。


四元數轉歐拉角:

  1. public Quaternion rotation = Quaternion.identity;
  2. print(rotation.eulerAngles.x);
  3. print(rotation.eulerAngles.y);
  4. print(rotation.eulerAngles.z);


歐拉角轉四元數:

  1. public Quaternion rotation = Quaternion.Euler(0, 30, 0);//Euler方法即通過一個Vector3的歐拉角返回一個四元數


四元數轉變換矩陣:

  1. Quaternion q = Quaternion.LookRotation(new Vector3(0,0.5,1));
  2. Matrix4x4 rot = new Matrix4x4();
  3. rot.SetTRS(new Vector3(0,0,0),q,new Vector3(1,1,1));


變換矩陣轉四元數:

    1. Matrix4x4 rot = new Matrix4x4();
    2. rot.SetTRS(new Vector3(0,0,0),q,new Vector3(1,1,1));
    3. Vector4 vy = rot.GetColumn(1);
    4. Vector4 vz = rot.GetColumn(2);
    5. Quaternion newQ = Quaternion.LookRotation(new Vector3(vz.x,vz.y,vz.z),new Vector3(vy.x,vy.y,vy.z));

【3D計算機圖形學】變換矩陣、歐拉角、四元數