1. 程式人生 > >3D數學 ---- 矩陣和線性變換

3D數學 ---- 矩陣和線性變換

一般來說,方陣能描述任意線性變換。線性變換保留了直線和平行線,但原點沒有移動。線性變換保留直線的同時,其他的幾何性質如長度、角度、面積和體 積可能被變換改變了。從非技術意義上說,線性變換可能“拉伸”座標系,但不會“彎曲”或“卷折”座標系。

矩陣是怎樣變換向量的

向量在幾何上能被解釋成一系列與軸平行的位移,一般來說,任意向量v都能寫成“擴充套件”形式:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

另一種略有差別的形式為:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

注意右邊的單位向量就是x,y,z軸,這裡只是將概念數學化,向量的每個座標都表明了平行於相應座標軸的有向位移。

讓我們將上面的向量和重寫一遍,這次分別將pqr定 義為指向+x,+y和+z方向的單位向量,如下所示:

v = xp + yq + zr

現在,向量v就被表示成向量pqr的 線性變換了,向量pqr稱作基向量。這裡 基向量是笛卡爾座標軸,但事實上,一個座標系能用任意3個基向量定義,當然這三個基向量要線性無關(也就是不在同一平面上)。以pqr為 行構建一個3 x 3矩陣M,可得到如下矩陣:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

用一個向量乘以該矩陣,得到:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

如果把矩陣的行解釋為座標系的基向量,那麼乘以該矩陣就相當於執行了一次座標轉換,如果aM=b, 我們就可以說,Ma轉換到b

從這點看,術語“轉換”和“乘法”是等價的。

坦率地說,矩陣並不神祕,它只是用一種緊湊的方式來表達座標轉換所需的數**算。進一步,用線性代數操作矩陣,是一種進行簡單轉換或匯出更復雜轉換 的簡便方法。

矩陣的形式:

基向量[1, 0, 0], [0, 1, 0], [0, 0, 1]乘以任意矩陣M

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

用基向量[1, 0, 0]乘以M時,結果是M的第1行。其他兩行也有同樣 的結果,這是一個關鍵的發現:矩陣的每一行都能解釋為轉換後的基向量。

這個強有力的概念有兩條重要性質:

1、有了一種簡單的方法來形象化解釋矩陣所代表的變換。

2、有了反向建立矩陣的可能 ---- 給出一個期望的變換(如旋轉、縮放等),能夠構造一個矩陣代表此變換。我們所要做的一切就是計算基向量的變換,然後將變換後的基向量填入矩陣。

首先來看看2D例子,一個2 x 2矩陣:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

這個矩陣代表的變換是什麼?首先,從矩陣中抽出基向量p

q

p = [2   1]

q = [-1  2]

圖7.1以“原”基向量(x軸,y軸)為參考,在笛卡爾平面中展示了這些向量。

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

如圖7.1所示,x基向量變換至上面的p向量,y基向量變換至q向量。所以 2D中想象矩陣的方法就是想象由行向量構成的“L”形狀。這個例子中,能夠很清楚的看到,M代表的部分變換是逆時針旋 轉26度。

當然,所有向量都被線性變換所影響,不只是基向量,從“L”形狀能夠得到變換最直觀的印象,把基向量構成的整個2D平行四邊形畫完整有助於進一步看 到變換對其他向量的影響,如圖7.2所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

平行四邊形稱作“偏轉盒”,在盒子中畫一個物體有助於理解,如圖 7.3 所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

很明顯,矩陣M不僅旋轉座標系,還會拉伸它。

這種技術也能應用到3D轉換中。2D中有兩個基向量,構成"L"型;3D中有三個基向量,它們形成一個”三腳架“。首先,讓我們展示出一個轉換前的 物品。圖7.4展示了一個茶壺,一個立方體。基向量在”單位“向量處。

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

(為了不使圖形混亂,沒有標出z軸基向量[0, 0, 1],它被茶壺和立方體擋住了。)

現在,考慮以下3D變換矩陣:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

從矩陣的行中抽出基向量,能想象出該矩陣所代表的變換。變換後的基向量、立方體、茶壺如圖7.5所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

這個變換包含z軸順時針旋轉45度和不規則縮放,使得茶壺比以前”高“。注意,變換並沒有影響到z軸,因為矩陣的第三行是[0, 0 , 1]。

我們可以通過讓比例因子k按比例放大或縮小來縮放物體。如果在各方向應用同比例的縮放,並且沿原點“膨脹”物體,那麼就是均勻縮放。均勻縮放可以保 持物體的角度和比例不變。如果長度增加或減小因子k,則面積增加或減小k^2。在3D中,體積將增加或減小 k^3。

如果需要“擠壓”或"拉伸"物體,在不同的方向應用不同的因子即可,這稱作非均勻縮放。非均勻縮放時,物體角度將發生變化。視各方向縮放因子的不 同,長度、面積、體積的變化因子也各不相同。

如果|k|<1,物體將“變短”;如果|k|>1,物體將“變長”,如果k = 0,就是正交投影,如果k < 0就是映象。

應用非均勻縮放的效果類似於切變,事實上,非均勻縮放和切變和很難區分的。

沿座標軸的縮放

最簡單的縮放方法是沿著每個座標軸應用單獨的縮放因子,縮放是沿著垂直的軸(2D中)或平面(3D中)進行的。如果每個軸的縮放因子相同,就是均勻 縮放,否則是非均勻縮放。

2D中有兩個不同的縮放因子,Kx和Ky,圖8.13展示了應用不同縮放因子後的情況。

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

憑直覺就可知道,基向量pq由相應的縮放因子單獨影響:

p' = Kxp = Kx [1   0] = [Kx   0]

q' = Kyq = Ky [0   1] = [0   Ky]

用基向量構造矩陣,結果如公式8.6所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

對於3D,需要增加第三個縮放因子Kz,3D縮放矩陣如公式8.7所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

沿任意方向縮放

我們可以不依賴於座標系而沿任意方向進行縮放,設n為平行於縮放方向的單位向量,k為縮放因子,縮放沿穿過原點 並平行於n的直線(2D中)或平面(3D中)進行。

我們需要推匯出一個表示式,給定向量v,可以通過vn和 k來計算v'。為了做到這一點,將v分解為兩個分量,v|| 和v⊥,分別平行於n和垂直於n,並滿足v =v|| + v⊥。v||是vn上 的投影,由 (v . n)n 可以得到 v||。 因為v⊥垂直於n,它不會被縮放操作影響。因此,v' =v||' + v⊥,剩下的問題就是怎樣得到v||'。 由於v||平行於縮放方向,v||'可以由公式kv|| 得出,如圖8.14所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

總結已知向量並進行代換,得到:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

既然我們知道了怎樣對任意向量進行縮放,當然也就可以計算縮放後的基向量。這裡只詳細列出2D中的一個基向量的求法,其餘的基向量依次類推。我們只 給出其結果(注意下面採用列向量形式只是為了使等式的形式好看一些。)

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

通過基向量構造矩陣,得到以單位向量n為縮放方向,k為因子的縮放矩陣,如公式8.8所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

3D中,基向量為:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

以單位向量n為縮放方向,k為因子的3D縮放矩陣如公式8.9所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

一般來說,投影意味著降維操作,有一種投影方法是在某個方向上用0作為縮放因子。這種情況下,所有點都被拉平至垂直的軸(2D)或平面(3D)上。 這種型別的投影稱作正交投影(或者平行投影),因為從原來的點到投影點的直線相互平行。

向座標軸或平面投影

最簡單的投影方式是向座標軸(2D)或平面(3D)投影,如圖8.15所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

向座標軸或平面投影在實際變換中不常發生,大多數情況是向低維的變換賦值,且要拋棄維數時。例如,將3D點賦值給2D點,拋棄z分量,只複製x和 y。

通過使垂直方向上的縮放因子為零,就能向座標軸或平面投影。考慮到完整性,下面列出這些變換矩陣,見公式8.10 - 8.14。

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

向任意直線或平面投影

也能向任意直線或平面投影,像往常一樣,由於不考慮平移,這些直線或平面必須通過原點。投影由垂直於直線或平面的單位向量n定 義。

通過使該方向的縮放因子為0能夠匯出向任意方向投影的矩陣,2D中的情況如公式8.15所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

記住這裡n垂直於投影直線,而不是平行。3D中,向垂直於n的平面投影的矩 陣如公式8.16所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

映象

映象(也叫做反射)是一種變換,其作用是將物體沿直線(2D中)或平面(3D中)“翻折”,圖8.16展示了映象的效果。

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

使縮放因子為-1能夠很容易地實現映象變換,設n為2D單位向量,公式8.17所示的矩陣將沿通過原點且垂直於n的 反射軸來進行映象變換。

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

3D中,用反射平面代替直線。公式8.18中的矩陣將沿通過原點且垂直於n的平面來進行映象變換:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

注意一個物體只能“映象”一次,如果再次映象(當沿不同的軸或平面的時候),物體將翻回“正面”(用一張紙來想象),這和在原位置旋轉物體的效果一 樣。

切變

切變是一種座標系“扭曲”變換,非均勻地拉伸它。切變的時候角度會發生變化,但令人驚奇的是面積和體積卻保持不變。基本思想是將某一座標的乘積加到 另一個上。例如,2D中將y乘以某個因子然後加到x上,得到 x' = x + sy,如圖8.17所示:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

實現這個切變變換的矩陣為:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

變換的組合

設想世界中有一個任意方向、任意位置的物體,我們要把它渲染到任意方向、任意位置的攝像機中。為了做到這一點,必須將物體的所有頂點從物體座標系變 換到世界座標系,接著再從世界座標系變換到攝像機座標系。其中的數學變換總結如下:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

矩陣乘法滿足結合律,所以我們能用一個矩陣直接從物體座標系變換到攝像機座標系:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

這樣就能在渲染的迴圈外先將所有矩陣組合起來,使迴圈內作矩陣乘法的時候只需要和一個矩陣相乘即可(物體有很多頂點,省一次矩陣乘法就會提高不少效 率),如下:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

所以矩陣組合從代數角度看是利用了矩陣乘法的結合律。矩陣的行向量就是變換後的基向量,這在多個變換的情況下也是成立的。考慮矩陣乘法AB, 結果中的每一行都是A中相應的行與矩陣B相乘的結果。換言之,設a1, a2, a3為A的行,矩陣乘法能夠寫為:

三維旋轉矩陣實用演算法 - szfzafa - ~Infinite Nightmare~

這使得結論更加清晰,AB結果中的行向量確實是對A的基向量進行B變 換的結果。

變換分類

變換的類別並不是互斥的,也不存在一定的“次序”或“層次”使得某一類比另一類多或少一些限制。

當討論一般意義上的變換時,我們將使用類似的術語:對映或函式。在最一般的意義上,對映就是一種簡單的規則,接受輸入,產生輸出。我們把從abF映 射記作F(a) = b

線性變換

在數學上,如果滿足下式,那麼對映F(a)就是線性的:

F(a + b) = F(a) + F(b)   以及  F(ka) = kF(a)

如果對映F保持了基本運算:加法和數量乘,那麼就可以稱該對映為線性的。在這種情況下,將兩個向量相加然後再進行變換得到的結果和先分別進行變換再 將變換後的向量相加得到的結果相同。同樣,將一個向量數量乘再進行變換和先進行變換再數量乘的結果也是一樣的。

這個線性變換的定義有兩條重要的引理:

(1) 對映F(a) = aM,當M為 任意方陣時,說映是一個線性變換,這是因為:

F(a + b) = (a + b)M = aM + bM = F(a) + F(b)

F(ka) = (ka)M = k(aM) = kF(a)

(2) 零向量的任意線性變換的結果仍然是零向量。(如果F(0) = aa ≠ 0。那麼F不可能是線性變換。因為F(k0) = a,但F(k0) ≠ kF(0)), 因此線性變換不會導致平移(原點位置上不會變化)。

在某些文獻中,線性變換的定義是平行線變換後仍然是平行線。大多數情況下它是對的,但有一個小小的例外:投影(當一條直線投影后變成一個點,能認為 這個點 平行於什麼?)除了這點理論上的例外,這種定義是正確的。線性變換可能造成“拉伸”,但直線不會”彎折“,所以平行線仍然保持平行。

仿射變換

仿射變換是指線性變換後接著平移。因此仿射變換的集合是線性變換的超集,任何線性變換都是仿射變換,但不是所有仿射變換都是線性變換。

任何具有形式 v' = vM + 的 變換都是仿射變換。

可逆變換

如果存在一個逆變換可以”撤銷“原變換,那麼該變換是可逆的。換句話說,如果存在逆變換G,使得G(F(a)) = a,對於任意a,對映F(a) 是可逆的。

存在非仿射變換的可逆變換,但暫不考慮它們。現在,我們集中精力於檢測一個仿射變換是否可逆。一個仿射變換就是一個線性變換加上平移,顯然,可以用 相反的量”撤銷“平移部分,所以問題變為一個線性變換是否可逆。

顯然,除了投影以外,其他變換都能”撤銷“。當物體被投影時,某一維有用的資訊被拋棄了,而這些資訊時不可能恢復的。因此,所有基本變換除了投影都 是可逆的。

因為任意線性變換都能表達為矩陣,所以求逆變換等價於求矩陣的逆。如果矩陣是奇異的,則變換不可逆;可逆矩陣的行列式不為0。

等角變換

如果變換前後兩向量夾角的大小和方向都不改變,該變換是等角的。只有平移,旋轉和均勻縮放是等角變換。等角變換將會保持比例不變,映象並不是等角變 換,因為儘管兩向量夾角的大小不變,但夾角的方向改變了。所有等角變換都是仿射和可逆的。

正交變換

術語“正交”用來描述具有某種性質的矩陣。正交變換的基本思想是軸保持互相垂直,而且不進行縮放變換。

平移、旋轉和映象是僅有的正交變換。長度、角度、面積和體積都保持不變。(儘管如此,但因為映象變換被認為是正交變換,所以一定要密切注意角度、面 積和體積的準確定義)。

正交矩陣的行列式為1或者負1,所有正交矩陣都是仿射和可逆的。

剛體變換

剛體變換隻改變物體的位置和方向,不包括形狀。所有長度、角度、面積和體積都不變。平移和旋轉是僅有的剛體變換,映象並不被認為是剛體變換。剛體變 換也被稱作正規變換,所有剛體變換都是正交、等角、可逆和仿射的,某些剛體變換旋轉矩陣的行列式為1。