2020年7月26日 星期日

三維空間旋轉

本篇文章目的是簡介向量在三維空間中的旋轉以及常見的旋轉表示方法。

先從二維旋轉開始

我們假設在二維空間中的一個向量 \(p = [p_x, p_y]\),如果我們想要將其對原點旋轉 \(\theta\) 的話,那旋轉後的點 \(p'\) 為: \[ p'= \begin{bmatrix} p'_x\\ p'_y \end{bmatrix} = \begin{bmatrix} cos\theta & -sin\theta\\ sin\theta & cos\theta \end{bmatrix} \begin{bmatrix} p_x\\ p_y \end{bmatrix} \]

簡單的例子

假設 p 為 [1,1],而我們要旋轉 90 度,因此旋轉過後的 p' 為: \[ p'= \begin{bmatrix} p'_x\\ p'_y \end{bmatrix} = \begin{bmatrix} 0 & -1\\ 1 & 0 \end{bmatrix} \begin{bmatrix} 1\\ 1 \end{bmatrix} = \begin{bmatrix} -1\\ 1 \end{bmatrix} \]

複數相乘與二維旋轉

當在複數空間時,對於原點旋轉 \(\theta\) 就相等於 \(p = p_x + p_y \mathbf{i}\) 乘以 \(cos\theta + sin\theta \mathbf{i}\): \[ p' = (cos\theta + sin\theta \mathbf{i})(p_x + p_y \mathbf{i}) \\ = (p_x\ cos\theta - p_y\ sin\theta) + (p_x\ sin\theta + p_y\ cos\theta)\mathbf{i} \]

複數的極座標

歐拉公式告訴我們 \(e^{\mathbf{i}\theta} = cos\theta + sin\theta \mathbf{i}\),因此我們可以直接用以下式子表示二維空間中的旋轉: \[ p' = e^{\mathbf{i}\theta}p \]

三維旋轉

歐拉角 Euler Angle

歐拉角是將三維空間中的旋轉分解成三次繞不同軸的單軸旋轉,例如說 ZYX 歐拉角就是先繞物體的 Z 軸旋轉(稱做 yaw)、繞旋轉之後的新 Y 軸旋轉(稱為 pitch)、再繞旋轉之後的 X 軸旋轉(稱為 roll)。歐拉角對於人來說是很直觀的作法,但是會碰到萬向鎖問題(Gimbal Lock)。拿以上 ZYX 歐拉角的例子來說,Gimbal Lock 是指在繞 Y 軸的旋轉為 90 度時,第三個旋轉的旋轉軸其實就是第一個旋轉的旋轉軸,也就是物體的 Z 軸與兩次旋轉後的 X 軸重合,因此這個系統便退化成兩個軸的旋轉,無法表示所有三維空間的旋轉。Gimbal Lock 的細節請參考此文章 [2]。

軸角 Axis Angle

除了歐拉角以外,三維空間中的旋轉可以用一個旋轉軸與一個旋轉角來表示,此旋轉軸為單位向量,若我們取一個向量使其方向與旋轉軸相同,而長度使其為旋轉角的大小,則我們稱此向量為旋轉向量,或稱為軸角 Axis Angle。

Rodrigues' Formula

此公式是用來轉換旋轉向量:旋轉軸為 \(n\)、旋轉角度為 \(\theta\) 至一個 \(3\times3\) 的旋轉矩陣 R: \[ R = cos\theta\ I + (1-cos\theta)nn^T + sin\theta\ n^{\wedge} \\ n^{\wedge} = \begin{bmatrix} 0 & -n_3 & n_2 \\ n_3 & 0 & -n_1 \\ -n_2 & n_1 & 0 \end{bmatrix} \] 公式的證明請參考以下文章 [1]。

到目前為止這些旋轉表示法的問題

我們到目前為止介紹了可以用 \(3\times 3\) 的旋轉矩陣、三個軸的歐拉角、以及旋轉向量來表示三維空間的旋轉。旋轉矩陣之中有九個參數,用來描述三個自由度的三維旋轉太浪費,而歐拉角有 Gimbal Lock 的問題。而 Axis Angle 雖然沒有 Gimbal Lock 的問題,但是其旋轉角 0 與 \(2\pi\) 相同,拿來計算時會產生 singularity,因此無法內插或是用迭代尋找正確的旋轉參數。之後會提到的四元數 Quaternion 是用四個參數來表示旋轉,可以避免 singularity 的問題。

參考資料

[2] Gimbal Lock, Krasjet

沒有留言:

張貼留言