相比 2D 中的旋轉變換,3D 中的旋轉變換復雜了很多。關於 2D 空間的旋轉,可以看這篇文章。本文主要粗略地探討一下 3D 空間中的旋轉。
旋轉的要素
所謂旋轉要素就是說,我們只有知道了這些條件,才知道怎么旋轉一個物體。回憶 2D 空間中的旋轉,我們需要確定旋轉中心、旋轉角以及旋轉方向才能旋轉一個圖形。以此類推,到了 3D 空間,我們仍然需要確定三個要素:一個旋轉軸、旋轉角以及旋轉方向。
下面,為了講解的方便,旋轉方向默認為:正對旋轉軸正方向,按逆時針方向為旋轉正方向,反之為旋轉負方向。
旋轉的幾種情況
3D 中的旋轉本質上可以分為下面三類情況:
- 繞 x / y / z 軸旋轉;
- 繞通過原點的直線旋轉;
- 繞不通過原點的直線旋轉。
可能有同學不理解為什么要分這么多情況討論,其實這是一個將復雜的問題簡單化的過程。在旋轉 2D 空間中的物體時,我們也只是計算出繞原點旋轉的公式,然后將旋轉點平移到跟原點重合,再根據公式旋轉物體,最后再平移回去。其實完全可以計算出一個繞任意軸旋轉的通用公式,但那樣會導致計算量更大。
繞 x / y / z 軸旋轉
這是最簡單的旋轉情況,只要把 2D 中的旋轉延伸到 3D 空間就可以了。
繞 x 軸旋轉

上圖是一個繞 x 軸旋轉的圖示。假設我們需要從點(\(x, y, z\))繞 x 軸旋轉 \(\theta\) 角到點 (\(x^,, y^,, z^,\)),那么,旋轉過程中,x 的坐標值始終都是固定不變的,因此,我們可以把它當作是在\(x=x^,\)這個平面上進行旋轉,從而退化成一個 2D 旋轉的問題。
上圖右邊的兩個矩陣,上面那個是 2D 旋轉矩陣,而底下那個只是把該矩陣延伸到 3D 空間而已(為了將平移也納入矩陣運算,3D 的變換都是采用齊次坐標)。因為 x 軸是旋轉軸,因此實際上是在 yoz 平面上做 2D 旋轉。只要你知道 2D 空間那個旋轉矩陣怎么計算,3D 的變換只是依葫蘆畫瓢而已。
繞 y 軸旋轉
同理,這里不再贅述。

繞 z 軸旋轉
同理,這里不再贅述。

繞通過原點的直線旋轉
以下所引用的例子來自文末鏈接三維空間中的旋轉:旋轉矩陣、歐拉角
現在,假設我們要繞旋轉軸 \(P\) 旋轉 \(\theta\) 角(如下圖所示),那又該如何?

目前我們已有的工具只是繞 x / y / z 軸旋轉的矩陣而已。回想 2D 中繞任意點旋轉的情況,我們是將任意點變換到原點,繞原點旋轉后,再變換回原來的位置。所以,同樣的道理,這次我們也將繞 \(P\) 軸的旋轉分解為三步(跟原文例子的解釋稍有不同,但本質上是一樣的):
- 將 \(P\) 軸旋轉到與 z 軸重合,此時物體跟着旋轉到新位置;
- 讓物體繞 z 軸旋轉 \(\theta\) 角(可以直接套用之前的矩陣);
- 將物體逆向旋轉回原來的位置。
下面就針對這三步,解釋一下具體的操作。
(1) 首先是將旋轉軸旋轉到與 z 軸重合。為此,我們需要將 \(P\) 軸繞 z 軸旋轉 \(\psi\) 角(根據前面的聲明,這里是正方向)。因此,需要乘以矩陣:
旋轉完后,\(P\) 軸落入 xoz 平面,然后,按照同樣的思路,繞 y 軸旋轉 \(\phi\) 角,再乘以矩陣:
這時,\(P\) 軸與 z 軸已經重合了。
(2) 然后我們讓物體繞 z 軸旋轉 \(\theta\) 角:
(3) 最后,將物體旋轉回之前的位置。具體做法是乘以之前矩陣的逆矩陣。至此,我們得到物體旋轉所需要的最終矩陣:
利用旋轉矩陣的性質:\(R(-\alpha)=R^{-1}(\alpha)=R^T(\alpha)\),我們也可以寫成:
繞不通過原點的直線旋轉
有了上面的基礎作鋪墊,這種情況將變得十分簡單。只要將旋轉軸平移到經過原點的位置,那么問題就轉換成上面的情況,最后再平移回去就可以了。因此,變換矩陣只是在上一種情況的基礎上,乘上平移矩陣:
參考
- Interactive Computer Graphics - A Top-Down Approach 6e By Edward Angel and Dave Shreiner (Pearson, 2012)
- 三維空間中的旋轉:旋轉矩陣、歐拉角
