Unity3D C#數學系列之變換矩陣推導

WangShade 2022-01-08 07:10:46 阅读数:705

unity3d unity c# 系列


1 仿射變換與齊次坐標

《Unity3D C#數學系列之矩陣基礎》中我們說到一個4×4的矩陣可以用來對三維空間中的點或向量進行各種變換,包括平移、旋轉、縮放(當然還有錯切、鏡像等,由於我工作中這幾種從來沒用過,所以這裏就不說這兩種變換了)以及這幾種變化的組合。這些變換有一個統一的名字,叫做仿射變換。三維空間中,只要是仿射變換,就可以用一個4×4的變換矩陣來錶示。
但是為什麼變換矩陣一定是4×4的呢,3×3行不行?答案是不行。如果不考慮點的平移,只考慮向量或點的旋轉、縮放,3×3的矩陣就可以了。但如果考慮點的平移,3×3的矩陣就不滿足要求了,必須擴充到4×4。至於為什麼3×3無法錶示平移,下面我們推導平移矩陣的時候就知道答案了。
我們知道三維空間中,一個點或者向量用3個變量x,y,z來錶示就行了,但是在進行矩陣變換的時候,需要增加一維變量w。用(x, y, z, w)錶示的向量或點,就叫齊次坐標。向量的w分量為0,點的w分量為1(為0時可以忽略掉平移的效果,如向量平移後還是它本身,為1時會保留平移的效果)。

2 變換矩陣的推導

2.1 變換矩陣推導一般過程

設4×4的變換矩陣為 M \textbf{M} M4×4
變換矩陣
設一個點A變換前的坐標為(x,y,z,w),變換後的點A’ 坐標為(x’,y’, z’,w’),則有
(還記得為什麼點或向量的坐標要寫成列矩陣的的形式嗎,不記得了去看看上一篇文章)
變換矩陣推導的一般過程
矩陣乘法展開後就有方程組
矩陣乘法展開
我們上面說過,點的齊次坐標的w分量為1,所以又有
矩陣乘法展開
從上面方程組中的最後一個方程我們可以看出(無論x、y、z為何值都滿足這個方程), m \textbf{m} m41 m \textbf{m} m42 m \textbf{m} m43全部等於0, m \textbf{m} m44等於1。
變換矩陣的一般推導過程
然後,我們令A(x,y,z,1)分別為(1, 0, 0, 1),(0,1,0, 1),(0,0,1, 1)同時我們需要分析出對應變換後的坐標A’(x’,y’, z’,1),然後代入上面的方程組的前3個,一般就能推導出平移、旋轉、縮放的矩陣了。

2.2 平移矩陣

設點A(x,y,z,1)平移(a,b,c,0)(即在x軸方向平移a個單比特,y方向平移b個單比特,z方向平移c個單比特),則A’點的坐標為(x + a,y + b,z + c,1),代入上面的方程組中有
平移矩陣的推導
無論x、y、z為何值都滿足上面方程組中的各個方程,必然有
平移矩陣的推導
所以平移的變換矩陣為
平移矩陣
平移矩陣的逆矩陣如下:
平移矩陣的逆矩陣
如果我們用一個3×3的矩陣來進行平移變換,將方程組展開,會發現根本沒有解。所以3×3的矩陣無法錶示平移,但4×4的矩陣可以。其根本原因是因為平移不是線性變換,必須要擴展一維才可以
3×3矩陣無法錶示平移變換

2.3 縮放矩陣

2.3.1 沿坐標軸的縮放

設向量(x,y,z,0)沿坐標軸縮放(kx,ky,kz,0),則縮放後的坐標為(kxx,kyb,kzz,0),代入2.1中的方程組中有
沿坐標軸的縮放矩陣
顯然有
沿坐標軸的縮放矩陣
所以沿坐標軸縮放(kx,ky,kz)的縮放矩陣為
沿坐標軸的縮放矩陣
其逆矩陣為如下:
沿坐標軸的縮放矩陣的逆矩陣

2.3.2 沿任意軸的縮放

設向量 v ⃗ \vec{v} v (x,y,z,0)沿單比特向量 n ⃗ \vec{n} n (nx,ny,nz,0)縮放k個單比特,假設縮放後的坐標為 v ′ ⃗ \vec{v'} v (nx,ny,nz,0),現在我們要求縮放矩陣,必須先把 v ′ ⃗ \vec{v'} v 給求出來。
我們將 v ⃗ \vec{v} v 分為兩個部分,一個是 v ⃗ \vec{v} v ,其垂直於 n ⃗ \vec{n} n ,沿著 n ⃗ \vec{n} n 縮放將對其不產生任何影響;另一個是 v ⃗ \vec{v} v //,其平行於 n ⃗ \vec{n} n ,沿著 n ⃗ \vec{n} n 縮放將對其產生影響。
沿任意軸的縮放
沿任意軸縮放的推導01
由於 v ⃗ \vec{v} v //平行於 n ⃗ \vec{n} n ,則有 v ⃗ \vec{v} v // = ( v ⃗ \vec{v} v · n ⃗ \vec{n} n ) n ⃗ \vec{n} n
所以 v ⃗ \vec{v} v //沿著 n ⃗ \vec{n} n 縮放k個單比特後的值為k( v ⃗ \vec{v} v · n ⃗ \vec{n} n ) n ⃗ \vec{n} n
又由於 v ⃗ \vec{v} v ⃗垂直於 n ⃗ \vec{n} n ,所以 v ⃗ \vec{v} v ⃗沿著 n ⃗ \vec{n} n 縮放k個單比特後的值仍為 v ⃗ \vec{v} v = v ⃗ \vec{v} v - v ⃗ \vec{v} v // = v ⃗ \vec{v} v -( v ⃗ \vec{v} v · n ⃗ \vec{n} n ) n ⃗ \vec{n} n
於是
沿任意軸縮放的推導02
v ⃗ \vec{v} v =(x,y,z), n ⃗ \vec{n} n =(nx,ny,nz )代入有,
沿任意軸縮放的推導03
代入2.1中的方程組中有
沿任意軸縮放的推導04
於是
沿任意軸縮放的推導05
所以沿單比特向量 n ⃗ \vec{n} n (nx,ny,nz)縮放k個單比特的縮放矩陣為
沿任意軸縮放k個單比特的縮放矩陣

2.4 坐標系之間的變換

在推導旋轉矩陣之前,我們先看看不同坐標系之間的變換矩陣是怎麼推導的,這是推導旋轉矩陣的基礎。
我們在說一個點或者一個向量的坐標的時候,一定要知道這個坐標是在什麼坐標系下的。
我們在說一個點或者一個向量的坐標的時候,一定要知道這個坐標是在什麼坐標系下的。
我們在說一個點或者一個向量的坐標的時候,一定要知道這個坐標是在什麼坐標系下的。
只要說到坐標,一定要立馬想到這個坐標所在的坐標系
同一個點或者同一個向量,在不同坐標系下,它們的坐標值是不一樣的。所以我們這裏才會來求不同坐標系之間的變換矩陣。
這裏先直接給出結論:
坐標系之間的變換
具體推導過程如下。
變換矩陣的推導
我們在上一篇文章《Unity3D C#數學系列之矩陣基礎》中說過逆矩陣可以用來還原某種變換或者說反變換,且正交矩陣的逆矩陣就是其轉置矩陣。並且,由標准正交基(長度為1的坐標系的x、y、z軸向量)構成的矩陣其實就是正交矩陣。
而對於向量,無論怎麼平移,向量的值都是不變的,所以對於向量其變換矩陣使用3×3就足够了。那麼對於向量,坐標系O’x’y’z’到Oxyz的變換矩陣也可求到了,如下。
坐標系變換矩陣的逆矩陣

2.5 旋轉矩陣

2.5.1 二維平面中的旋轉

我們先來看二維平面上的旋轉。在二維平面上,我們說的旋轉是指繞著某一個點旋轉
說一條線繞著某一點(假設名字為旋轉中心)旋轉,是指該線上的所有點繞著旋轉中心旋轉。
說一個多邊形繞著某一點(假設名字為旋轉中心)旋轉,是指這個多邊形上的每一個點繞著旋轉中心旋轉。

2.5.1.1 繞原點的旋轉

我們先來推導下二維平面Oxyz坐標系中,繞原點O旋轉的旋轉矩陣。
二維平面的旋轉
設坐標系Oxyz是左手坐標系(因為Unity中世界坐標系和局部坐標系都是左手坐標系,所以我們這裏舉例子也按照Unity的來),A點繞著原點O旋轉了θ度到達新點A‘,求旋轉矩陣。
推導過程如下。
繞原點旋轉的變換矩陣推導
繞原點的旋轉矩陣推導
旋轉矩陣是正交矩陣
(還記得正交矩陣滿足什麼條件嗎?忘記了去複習一下《Unity3D C#數學系列之矩陣基礎》第4.4節)
所以其逆矩陣就是其轉置矩陣。
旋轉矩陣的逆矩陣

2.5.1.2 繞任意點的旋轉

如圖,左手坐標系Oxyz中,B點在Oxyz坐標系的坐標為(a, b),求A點繞點B旋轉θ角的旋轉矩陣。
二維平面繞任意點的旋轉
其推導過程如下:
二維平面繞任意點的旋轉矩陣推導過程

2.5.2 三維空間中的旋轉

三維空間說的旋轉是指一個點或者一個向量繞著某一個方向或者說某一個軸旋轉(二維是繞著某一個點)。

2.5.2.1 繞x軸的旋轉

如圖,A點繞X軸旋轉θ度後到達A‘點(我們這裏還是假設Oxyz坐標系是左手坐標系的)。
繞X軸的旋轉
繞著X軸旋轉其實可以理解在Oyz這個二維平面內繞著原點O進行旋轉。然後將A’點和A點的x軸坐標設置為一樣的。
上面這句話可能沒錶達清楚,看下面這張圖應該就能理解了,其中灰色平面與Oyz平面平行。
三維空間繞X軸的旋轉
根據上一節我們講的二維平面中繞原點的旋轉矩陣,咱們可以直接寫出三維空間中繞x軸的旋轉矩陣。
三維空間繞x軸旋轉θ的旋轉矩陣

2.5.2.2 繞y軸的旋轉

同繞x軸的旋轉,繞著y軸的旋轉可以理解為在Oxz這個二維平面內繞著原點O進行旋轉。然後將A’點和A點的y軸坐標設置為一樣的。
繞y軸的旋轉
繞y軸旋轉θ角的旋轉矩陣為
繞y軸旋轉θ角的旋轉矩陣

2.5.2.3 繞z軸的旋轉

同繞x軸的旋轉,繞著z軸的旋轉可以理解為在Oxy這個二維平面內繞著原點O進行旋轉。然後將A’點和A點的z軸坐標設置為一樣的。
繞z軸旋轉θ角的旋轉矩陣
繞z軸旋轉θ角的旋轉矩陣為
繞z軸旋轉θ角的旋轉矩陣

2.5.2.4 繞任意軸的旋轉

如圖,Oxyz坐標系中,A點繞向量 r ⃗ {\vec{r}} r =(a,b,c)旋轉θ度到達A’點,求旋轉矩陣。
繞任意軸的旋轉
繞任意軸的旋轉與二維平面的旋轉推導方法類似的,關鍵在建立一個輔助坐標系。
其推導過程如下:
繞任意軸的旋轉矩陣推導
後面我實在是不想算了,要用的時候直接查資料吧。。。


博主本文博客鏈接。


版权声明:本文为[WangShade]所创,转载请带上原文链接,感谢。 https://gsmany.com/2022/01/202201080710454632.html