用四元數和矩陣處理三維旋轉問題 ==== 二維物體的參數 --- 在二維空間中,要如何呈現一個物體的狀態呢(姿勢、位置)呢? 讓我們用Diep.io來舉例,  首先是兩個實數變數:X, Y — 用來描述位置,  再來是 θ — 用旋轉的程度來描述姿勢, 總共三個變數就能描述二維物體的在空間中的狀態, 那麼...三維物體需要幾個變數來描述呢? 這些變數又要如何定義呢? 三維物體的旋轉參數 --- 不論是使用 [球座標系](https://zh.wikipedia.org/wiki/球座標系) 或是 [直角座標系](https://zh.wikipedia.org/wiki/笛卡爾座標系) 來描述位置, 都需要三個實數變數( $x, y, z$ 或是 $r, θ, φ$ ),這點毫無爭議。 但是姿勢呢...? 對飛行器有點興趣的人想必心裡已經有答案了吧? [](https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/Flight_dynamics_with_text.png/800px-Flight_dynamics_with_text.png) Yaw,Pitch, Roll 用來表示綽綽有餘,但是運算呢? 我們希望旋轉( Rotation )可以像座標一樣簡單的把累增量加上去就得到新的數組用來表示新的姿勢, $$ \text{rotation}' = f(\text{rotation},\Delta \text{rotation}) $$ 但是 [現實是殘酷的](https://math.stackexchange.com/questions/788951) ,旋轉的數學運算有先後順序的問題, 我們通常使用 [矩陣](https://zh.wikipedia.org/zh-tw/旋轉矩陣) 來處理三維旋轉問題,但是有學過矩陣的朋友應該知道, 矩陣乘法不滿足交換律,換句話說,先後順序會造成運算結果不同, 這點其實很直觀,自己拿一個物件,試著定義兩個旋轉方向並且轉轉看, 就會發現旋轉這件事本身就有先後順序的問題。 四元數 --- 一個三維的旋轉行為就像力偶,可以拆解成三個分平行於 $X,Y,Z$ 軸的分量,  又或是將純量取出,用四個數字表示:純量和單位向量的 X 分量、Y 分量、Z 分量, 也就是三個數字表示一個三維旋轉的軸,一個數字表示旋轉量, 原本用三個數字就能表示三維旋轉了,但是為了方便日後計算才如此配置, 這樣設計是四元數的基礎。 --- 四元數是複數的一種延伸,一個四元數有一個實數和三個虛數, 表示成: $$ a + b \mathbf {i} + c \mathbf {j} + d \mathbf {k} $$ 四元數可用比較簡單的方式處理三維旋轉問題, 首先將一個旋轉行為的旋轉軸以及角度列出: ``` θ:旋轉角度, 旋轉軸單位向量的分量分別為:ux 、uy 、uz ``` 並且轉換成四元數形式( 其中 q 就是四元數 ): $$ \begin{align} & A = \cos(\theta / 2) \\ & B = u_x \sin(\theta/2) \\ & C = u_y \sin(\theta/2) \\ & D = u_z \sin(\theta/2) \\ & q = A + B \mathbf {i} + C \mathbf {j} +D \mathbf {k} \end{align} $$ 這個四元數可以用來做什麼呢? 一個位於三維直角座標系的點,延一個通過原點的轉軸進行旋轉,會得到一個新的座標,此時若將這個旋轉行為化成四元數,便可利用它計算出旋轉完成後的新座標。  首先把這個點的座標也轉換成四元數形式: $$ \begin{align} & A = 0 \\ & B = x \\ & C = y \\ & D = z \\ & p = A + B \mathbf {i} + C \mathbf {j} +D \mathbf {k} \end{align} $$ 運算後的新座標也會以四元數的型態呈現: $$ \begin{align} p’ &= \text{Rotate}(p,q) \\ &= q \times p \times \text{Inverse}( q )\\ &= q \times p \times q^{-1} \end{align} $$ 但是複數的直接運算很瑣碎而且繁雜,此時可以用矩陣來處理這個計算, 一個 A + Bi+ Cj+Dk 的四元數可以表示成 4x4 的矩陣: $$ \begin{bmatrix} A & -D & C & B \\ D & A & -B & C \\ -C & B & A & -D \\ -B & -C & -D & A \\ \end{bmatrix} $$ 根據矩陣的運算規則可得: $$ q’ = q_1 \times q_2 $$ $$ \begin{matrix} B'= & A_1 B_1 &- D_1 C_2 &+ C_1 D_2 &+ B_1 A_2 \\ C'= & D_1 B_2 &+ A_1 C_2 &- B_1 D_2 &+ C_1 A_2 \\ D'= &- C_1 B_2 &+ B_1 C_2 &+ A_1 D_2 &+ D_1 A_2 \\ A'= &- B_1 B_2 &- C_1 C_2 &- D_1 D_2 &+ A_1 A_2 \end{matrix} $$ 對人而言運算可能很繁瑣,但是對電腦而言卻很快速。 四元數另外一個好處在於旋轉量可以累增, 我們來把剛剛的運算結果旋轉第二次看會發生什麼事: $$ p'' = q_2 \times p' \times \text{Inverse}( q_2 ) $$ 展開看看: $$ \begin{align} p'' &= q_2 \times q_1 \times p \times \text{Inverse}( q_1 ) * \text{Inverse}( q_2 ) \\ &= ( q_2 \times q_1 ) \times p \times \text{Inverse}( q_2 \times q_1 ) \\ &= ( q_t ) \times p \times \text{Inverse}( q_t ) \Big|_{ q_t = q_2 * q_1} \end{align} $$ 可以發現,我們可以用一個四元數代表一整個物件的三維旋轉狀態, 如果有任何累增,直接和原本的旋轉量做運算就好了: $$ q' = \Delta q \times q $$ 參考 --- https://en.wikipedia.org/wiki/Invertible_matrix https://openhome.cc/Gossip/ComputerGraphics/QuaternionsRotate.htm https://zh.wikipedia.org/wiki/四元數與空間旋轉 https://zh.wikipedia.org/zh-tw/四元數 https://zh.wikipedia.org/zh-tw/旋轉矩陣 ###### tags: `learning note` `2018-04-25`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up