計算機圖形學里包含很多的旋轉(Rotation)、位移(Translate)、切變(Shear)和拉伸(Scale)操作來達到形變的目的,這些操作都可以很簡單的通過轉換矩陣(Transfromation Matrix)來達到。基礎見此鏈接。需要注意切邊指一邊變動,而其他邊不改變的操作。所有轉換需要注意的是基的改變是以原點為中心的,因此圍繞某個點旋轉需要先將原點放在旋轉點上,旋轉再還原,即類似\(T(c)RT(-c)\)的操作。另外要注意的是矩陣操作是從右往左的順序。
矩陣分解
之前我們提到過對稱矩陣的特征值分解可以表示為\(RSR^T\)的形式,其中R代表了一種旋轉,S代表了一種拉伸操作。另外一種簡單方法則是列向量的線性變換,以列向量的方向為新的底邊/側邊方向,列向量的長度為拉伸長度倍率。對於非對稱矩陣而言可以使用SVD分解的操作,即\(A=USV^T\),之前提到過兩側的正交奇異向量矩陣分別為旋轉操作。需要注意的是如果要維持S為正值,則兩側的矩陣既可能是旋轉也可能是反轉(reflection)。我們可以簡單的通過檢查行列式來進行檢測(+1是旋轉,-1是反轉),這部分也可以參考此鏈接
矩陣旋轉
進行旋轉操作時,有被稱為Paeth Decomposition of Rotations的方法將旋轉操作分為三次連續的切變操作,具體見鏈接。這么做的好處是不需要將圖形的頂點進行變換然后重新做圖,而是基於原圖的基礎上直接進行幾何變換,將一行或一列像素同時變換再一一遍歷即可。
三維旋轉圍繞軸\(a\)進行旋轉的時候,可以取軸\(a\)的單位方向向量\(w\),構造與其垂直的平面\(uv\)並構成\(uvw\)的基,得到對應正交矩陣\(A\)。接下來進行矩陣變換\(ARA^{-1}\),先通過\(A^{-1}\)將\(xyz\)坐標系切換至\(uvw\)坐標系,接着在\(R\)內固定第三列\(w\)值,最后通過\(A\)還原到\(xyz\)坐標系。具體如下,並運用到了正交矩陣\(A^{-1}=A^T\)的特性。
法向量轉換
在矩陣變換時,平面的切線\(t\)經過變換\(M\)后\(Mt\)依然是矩陣的切線,但平面的法向量經過變換后(Mn)則不一定,我們需要一個法向量轉換矩陣\(N\),使得\(Nn\)依然為轉換后平面的法向量。從數學上我們需要轉換前\(n^Tt=0\)並且轉換后\((Nn)^T(Mt)=0\),見下圖。
因為\(n^Tt=n^TM^{-1}Mt=(n^TM^{-1})(Mt)=0\),我們可以知道一個解為\((Nn)^T=n^TN^T=(n^TM^{-1})\)即\(N=(M^{-1})^T\)。因為逆矩陣可以通過cofactor來進行計算,經過轉換可以得到以下公式
齊次坐標
為了將平移操作利用矩陣乘法而不是加法進行運算,可以引入第四維度的齊次坐標,單獨記錄位移量,見下圖。引入的原因可以參考此鏈接,另外在下一章的透視中會有第四維度值代表距離的額外效果。
另外我們規定額外維度值為\(1\)的時候為標准空間,可以參考齊次坐標的介紹,類似於隱式函數中取0,1是為了乘除的單位。在這里我們可以觀察到在齊次坐標下任意轉換矩陣\(A\)最后一行為\([0,0,0,1]\),根據矩陣行列點乘的乘法原則,因為\(A^{-1}A=I\)且\(I\)的最后一行也為\([0,0,0,1]\),我們知道\(A^{-1}\)的最后一行也必須為\([0,0,0,1]\),否則最后I的計算結果最后一行會錯誤。從GAMES101中的額外講解而言,最后一維為0可以看做不受平移影響的向量,最后一維為1的可以看做受到平移影響的點,這樣可以得到以下的轉換方式,注意點和點相加在進行w divide后可以視作計算中點。包含平移操作的矩陣變換我們也稱為仿射變換(Affine Transformation)。
坐標系變換
在進行矩陣轉換的時候,我們可以按照點的轉換或者坐標系的轉換來進行不同的理解,見下圖。注意這里可以參考3Blue1Brown中線性變換“基的變換”和“點的坐標”本身是一體的有着相同的思想。本質是全局空間只有一個,只是用不同的坐標系語言來形容同一個點。這個理解方法在游戲等地方經常用到,例如賽車游戲可以以賽車的位置為原點構成坐標系並移動坐標系,或者我們將賽車固定在原點變動整個場景在賽車坐標系的位置。這個思想在前文相似矩陣或矩陣分解時已經反復提及,具體也可以參考此鏈接。
我們這里以一個2D場景作為例子,見下圖。
通常來講,如果以基\(uvw\)構成一個轉換矩陣,其代表將\((uvw)\)坐標系下的坐標轉換至標准基坐標系,但原點不變。如下圖所示,利用\(uv\)構成的轉換矩陣轉換了坐標系,再進行最后的\(e\)至\(o\)的位移。這里不先位移的原因是一開始的單位是以\(uv\)坐標系來的,位移的計算相對復雜,實際上也可以先位移。對於相反的方向來看(即標准坐標系轉換至\(uv\)坐標系),我們先位移再變基,因為位移時還在標准坐標系內。
對於以上這樣的坐標系轉換可以有如下的標准公式,二維去掉w列即可。