旋轉矩陣與四元數


旋轉矩陣與四元數  

http://insaneguy.me/2015/03/25/rotation_matrix_and_quaternions/

在計算機圖形學的學習中,幾何變換(Transformations)是一塊重要的內容,我們使用齊次坐標(Homogeneous coordinates)描述點和向量,使用變換矩陣描述平移、旋轉等變換。

而在平移、旋轉、縮放這幾種變換中,又以旋轉的情況最為復雜。實際上,計算機圖形學中三維空間的旋轉不僅僅有旋轉矩陣一種表達形式,歐拉角(Euler angles)和四元數(Quaternions)也是常用的方法。

 


旋轉矩陣

三維空間中的一個點 PP ,我們用齊次坐標表示:

 

P=[x,y,z,w]TP=[x,y,z,w]T

 

我們首先考慮分別繞 X 軸、Y 軸、Z 軸旋轉一定角度的情況。

繞坐標軸旋轉繞坐標軸旋轉

設 PP 繞 X 軸、Y 軸、Z 軸的旋轉角度分別為 αα、ββ 和 θθ。

我們使用右手坐標系,旋轉角度的正向由右手定則確定。

點繞坐標軸旋轉可以考慮點在相應坐標平面上投影的旋轉。比如繞 Y 軸旋轉,那么考慮點 PP 在 X-Z 平面上的投影的旋轉,如下圖所示:

繞Y軸旋轉繞Y軸旋轉

假設點 PP 在 X-Z 平面上的投影點與坐標原點連成的向量長度為 L ,那么根據簡單的平面幾何知識,我們可以得到:

 

[x1z1]=[cosβsinβsinβcosβ][xz][x1z1]=[cosβsinβ−sinβcosβ][xz]

 

用齊次坐標表示繞Y軸的旋轉為:

 

⎡⎣⎢⎢⎢x1y1z1w1⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢cosβ0sinβ00100sinβ0cosβ00001⎤⎦⎥⎥⎥⎡⎣⎢⎢⎢xyzw⎤⎦⎥⎥⎥[x1y1z1w1]=[cosβ0sinβ00100−sinβ0cosβ00001][xyzw]

 

同理可分別得到繞X軸與繞Y軸的情況。

繞X軸旋轉:

 

⎡⎣⎢⎢⎢x2y2z2w2⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢10000cosαsinα00sinαcosα00001⎤⎦⎥⎥⎥⎡⎣⎢⎢⎢xyzw⎤⎦⎥⎥⎥[x2y2z2w2]=[10000cosα−sinα00sinαcosα00001][xyzw]

 

繞Z軸旋轉:

 

⎡⎣⎢⎢⎢x3y3z3w3⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢cosθsinθ00sinθcosθ0000100001⎤⎦⎥⎥⎥⎡⎣⎢⎢⎢xyzw⎤⎦⎥⎥⎥[x3y3z3w3]=[cosθ−sinθ00sinθcosθ0000100001][xyzw]

 

我們可以將繞X、Y和Z坐標軸的旋轉矩陣分別記為 Rx(α),Ry(β),Rz(θ)Rx(α),Ry(β),Rz(θ),則有:

 

Rx(α)=⎡⎣⎢⎢⎢10000cosαsinα00sinαcosα00001⎤⎦⎥⎥⎥Rx(α)=[10000cosα−sinα00sinαcosα00001]

 

 

Ry(β)=⎡⎣⎢⎢⎢cosβ0sinβ00100sinβ0cosβ00001⎤⎦⎥⎥⎥Ry(β)=[cosβ0sinβ00100−sinβ0cosβ00001]

 

 

Rz(θ)=⎡⎣⎢⎢⎢cosθsinθ00sinθcosθ0000100001⎤⎦⎥⎥⎥Rz(θ)=[cosθ−sinθ00sinθcosθ0000100001]

 

旋轉矩陣可以通過其他旋轉矩陣復合得到(矩陣乘法)。

 


歐拉角

上面討論了繞三條坐標軸旋轉的旋轉矩陣,旋轉矩陣的一般形式(這里沒有用齊次坐標)為:

 

C=⎡⎣⎢c11c21c31c12c22c32c13c23c33⎤⎦⎥C=[c11c12c13c21c22c23c31c32c33]

 

物體在三維空間中的旋轉可以從坐標系的旋轉來考慮(三維空間中坐標軸,即三維線性空間中基的變換)。那么矩陣 CC 的三個列向量實際對應着原坐標系三個坐標軸方向的單位向量在旋轉后的新坐標系下的坐標。

我們知道直角坐標系的三個坐標軸方向的單位向量實際上是一組標准正交基,於是矩陣 CC 是一個正交矩陣。所以旋轉矩陣表面上看起來依賴於 9 個參數,實際上只有三個是獨立的。

為了更直接地指出這三個獨立參數,歐拉(Euler)證明了如下事實:任何一個旋轉都可以由連續施行的三次繞軸旋轉來實現,這三次繞軸旋轉的旋轉角就是三個獨立參數,稱為歐拉角。

根據繞軸旋轉的順序不同,歐拉角的表示也不同。常見的歐拉角表示有 Yaw-Pitch-Roll (Y-X-Z順序),通過下面的圖片可以形象地進行理解。

Yaw-Pitch-RollYaw-Pitch-Roll

偏航(Yaw):

airplane Yawairplane Yaw

仰俯(Pitch):

airplane Pitchairplane Pitch

側偏(Roll):

airplane Rollairplane Roll

設 Yaw 、Pitch 、Roll 三個角度分別為 θ,φ,ψθ,φ,ψ,那么利用歐拉角進行旋轉對應的旋轉變換矩陣為:

 

⎡⎣⎢cosψ cosθsinψ cosφ sinθcosψ sinθ+sinψ cosφ cosθsinψ sinφsinψ cosθcosψ cosφ sinθsinψ sinθ+cosψ cosφ cosθcosψ sinφsinφ sinθsinφ cosθcosφ⎤⎦⎥[cosψ cosθ−sinψ cosφ sinθ−sinψ cosθ−cosψ cosφ sinθsinφ sinθcosψ sinθ+sinψ cosφ cosθ−sinψ sinθ+cosψ cosφ cosθ−sinφ cosθsinψ sinφcosψ sinφcosφ]

 

實際上 Yaw 、Pitch 、Roll 的旋轉就分別對應着前面我們給出的旋轉矩陣 Rx(θ),Ry(φ),Rz(ψ)Rx(θ),Ry(φ),Rz(ψ),上面的矩陣就是這三個矩陣的復合。

歐拉角的好處是簡單、容易理解,但使用它作為旋轉的工具有嚴重的缺陷—萬向節死鎖(Gimbal Lock)。

萬向節死鎖是指物體的兩個旋轉軸指向同一個方向。實際上,當兩個旋轉軸平行時,我們就說萬向節鎖現象發生了,換句話說,繞一個軸旋轉可能會覆蓋住另一個軸的旋轉,從而失去一維自由度。

例如,三維空間中有一個平行於 X 軸的向量,我們將它繞 Y 軸旋轉直到它平行於 Z 軸,這時,我們會發現任何繞 Z 軸的旋轉都改變不了該向量的方向,即出現了萬向節死鎖。

由於萬向節死鎖的存在,使用歐拉角也無法很好地處理旋轉的插值(以實現“平滑”旋轉)。

 


四元數

從前面的討論我們發現三角度系統(three-angle system)無法很好地處理旋轉的插值。下面介紹四元數(Quaternions)以及如何利用四元數描述旋轉。

 

四元數的定義

四元數是由數學家 William Rowan Hamilton 於1843年所發明的數學概念,是復數的推廣,可以說是“三維的復數”,形式為 w+x i+y j+z kw+x i+y j+z k ,其中 i,j,ki,j,k 的關系如下:

 

i2=j2=k2=1ij=ji=kik=ki=jjk=kj=ii2=j2=k2=−1i⋅j=−j⋅i=ki⋅k=−k⋅i=jj⋅k=−k⋅j=i

 

假設有兩個四元數:

 

q1=w1+x1 i+y1 j+z1 kq2=w2+x2 i+y2 j+z2 kq1=w1+x1 i+y1 j+z1 kq2=w2+x2 i+y2 j+z2 k

 

四元數的加法定義如下:

 

q1+q2=(w1+w2)+(x1+x2) i+(y1+y2) j+(z1+z2) kq1+q2=(w1+w2)+(x1+x2) i+(y1+y2) j+(z1+z2) k

 

四元數的乘法定義,利用簡單的分配律定義如下:

 

q1q2=(w1w2x1x2y1y2z1z2)+(w1x2+x1w2+y1z2z1y2) i+(w1y2x1z2+y1w2+z1x1) j+(w1z2+x1y2y1x2+z1w2) kq1⋅q2=(w1⋅w2−x1⋅x2−y1⋅y2−z1⋅z2)+(w1⋅x2+x1⋅w2+y1⋅z2−z1⋅y2) i+(w1⋅y2−x1⋅z2+y1⋅w2+z1⋅x1) j+(w1⋅z2+x1⋅y2−y1⋅x2+z1⋅w2) k

 

為了方便表示,我們將四元數記為:

 

q=(x,y,z,w)=(v⃗ ,w)q=(x,y,z,w)=(v→,w)

 

注意,這里四元數的表示形式和“齊次坐標”長得一樣,但是它們之間沒什么關系

四元數常常用來表示旋轉,很多人將其理解為“w表示旋轉角度,v表示旋轉軸”,也是錯誤的!

正確的理解應為:“w與旋轉角度有關,v與旋轉軸有關”。

四元數的模(norm)定義為

 

|q|=x2+y2+z2+w2|q|=x2+y2+z2+w2

 

模為1的四元數稱為單位四元數(Unit quaternions)。

四元數的共軛(conjugate)定義為:

 

q=(v⃗ ,w)q∗=(−v→,w)

 

四元數的倒數定義為:

 

1/q=q/|q|21/q=q∗/|q|2

 

 

四元數與旋轉

這里直接給出結論:如果把單位四元數表示為:

 

q=(n⃗ sinθ2, cosθ2)q=(n→⋅sinθ2, cosθ2)

 

的形式,那么該單位四元數可以表示繞軸 n⃗ n→
進行 θθ 角的旋轉。

該單位四元數對應的旋轉矩陣為

 

R(q)=⎡⎣⎢12(y2+z2)2(xy+zw)2(xzyw)2(xyzw)12(x2+z2)2(yz+xw)2(xz+yw)2(yzxw)12(x2+y2)⎤⎦⎥R(q)=[1−2(y2+z2)2(xy−zw)2(xz+yw)2(xy+zw)1−2(x2+z2)2(yz−xw)2(xz−yw)2(yz+xw)1−2(x2+y2)]

 

這里的推導用到了軸-角旋轉表示中的Rodrigues’ rotation formula,具體證明這里不展開了,有興趣的可以查閱相關資料。

我們發現用四元數描述旋轉需要的存儲空間很小,更為關鍵的是可以使用被稱為球面線性插值Slerp Algorithm)的方法對四元數進行插值運算,從而解決了平滑旋轉的插值問題。

在 OpenGL 或者 DirectX 中我們通常使用模型視圖矩陣來進行幾何變換,當我們希望實現光滑旋轉、對旋轉進行插值時,就可以利用四元數這一工具。處理過程為:

  • 模型視圖矩陣 -> 四元數
  • 使用四元數進行運算
  • 四元數 -> 模型視圖矩陣


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM