3D圖形:矩陣與線性變換

前言


由于OpenGLES的進度再度擱淺,所以準備從再次學習3D圖形的深層次的知識,這一篇主要講的是如何使用矩陣表示旋轉、縮放、投影、鏡像、切變,這些線性變換將會由淺入深,也算是為了后面的仿射變換做鋪墊吧!接下來,我們一一看這些線性變換.

旋轉


日常開發過程中旋轉是一種很常見的圖形變換,現在我們就對2D環境下和3D環境下的圖像變換進行講解說明.

2D環境下的旋轉

假設現在物體現在就在原點位置,例如下圖.


然后物體旋轉角度為θ = 3/π,在旋轉當中經常被認為逆時針為正方向,順時針為負方向,那么對于基向量p,q是怎么變化的呢?如下圖所示.這里我直接用繪圖工具了,圖片粗糙請見諒.

我們從圖片中可以看到旋轉后的新向量p1,q1的值(當然了,實際上是根據三角函數計計算出來的),然后通過這兩個值我們就可以構造出如下通用旋轉矩陣.通過下面的矩陣,我們是不是很熟悉呢?有沒有仿射變換的趕腳.不要著急,我們慢慢看.

</b>

3D環境下的旋轉

在3D的環境下,我們討論的不再是繞點旋轉,而是繞軸旋轉.雖然是繞軸旋轉,我們也要定義出正負方向來.在左右坐標系中的情況是有所不同的,什么?不知道左右坐標系如何定義的?那么看下圖所示.



那么在我們的坐標系中如何判斷出正負方向呢?比如我們在左手坐標系中需要使用的左手法則倆判斷正負方向,而在右手坐標系中則正好相反.我們就拿在左手左邊系為例,法則示意圖如下所示.(左右手法則不過多解釋,如果不懂請自行查看高中物理相關知識)

|左手坐標系|
|:---:|:---:|:--:|
|從哪里看|正方向|負方向|
|從軸的負端點向正端點看|逆時針|順時針|
|從軸的正端點向負端點看|順時針|逆時針|

上面我們了解完旋轉方向了,接下來我們先看看三種特殊情況,分別繞x,y,z軸進行旋轉.

我們還是來看基向量的變化,首先對于3D中的基向量p ,q ,r由于是繞x軸進行旋轉的,所以說基向量p是沒有任何變化的,變化的只有q ,r兩個基向量,假設旋轉的角度θ = 3/π,那么如下圖所示.

然后如果在2D中通過三角函數公式,我們可以獲得以下的旋轉變換矩陣.

那么繞y,z軸與之類似,我就不做圖了,直接上公式了.

繞y軸旋轉

繞z軸旋轉

那么上面看完了三種特殊的旋轉方式,接下來,我們就看一下在3D中繞任意軸旋轉的情況.

如圖所示,如果向量v(粉色)繞軸向量n旋轉得到向量v'(粉色),我們直接如果直接觀察的話是非常困難的.


但是如果我們把向量v和向量v'進行分解,然后把旋轉的θ放在一個平面中來解決問題,這樣,我們的旋轉問題就轉化為簡單的2D問題了.如下圖所示.

這里我要對各個向量做一下解釋說明,
其中nv在旋轉軸上的投影 (假設旋轉軸為n',那么n=n'(v·n'));
v為旋轉之前的向量;
v'為旋轉之后的向量 ;
pv垂直于n的分量(p'同理);
ω為同時垂直于np的向量,長度與p相等.

上面基本我們把所有的向量解釋了,現在已經知道的條件是向量v和旋轉軸n'以及旋轉角度θ要計算的是向量v'.(怎么跟計算題似的??)

整體的思路是這樣的,我們可以使用向量n和向量p'表示向量v',v' = n +p';然后n=n'(v·n')以及p'=ωsinθ+ncosθ,這三個向量表示公式來進行表示分解.計算過程如下.(說明:由于時間原因,本人就直接用紙寫了計算過程了.騷棟的字是夏練三伏 冬練三九,終究還是敗了)

首先我們先對p'=ωsinθ+pcosθ進行解析,步驟如下

p'=ωsinθ+pcosθ
代換pω
p = v - n = v - ( v·n')n'
ω = n' x p = n' x (v - n) = n' x v - n' x n = n' x v - 0 = n' x v
**p'=ωsinθ+pcosθ = (n' x v)sinθ +(v - ( v·n')n')cosθ **

演算草稿

上面我們已經計算出p'然后帶入v' = n +p',計算如下所示

v' = (n' x v)sinθ +(v - ( v·n')n')cosθ +n'(v·n')

現在我們既然有了轉換關系,那么我們就要對三個基向量p ,q ,r進項轉換了,我們就拿其中p = [1,0,0]來舉例說明.其中旋轉軸向量n' = [nx ,ny,nz],那么經過旋轉之后的基向量p'是什么情況呢?步驟如下所示.

同樣的對于基向量q = [0,1,0] ,r = [0,0,1],我們使用公式v' = (n' x v)sinθ +(v - ( v·n')n')cosθ +n'(v·n')一樣求出他們轉換之后的基向量.具體的過程我就不在重復了,如果向量計算記不清楚的可以查看3D圖形:向量的相關計算,計算結果如下.

變換之后的基向量q'
變換之后的基向量r'

結果上面的重重計算,我們終于得到了繞任意軸n = [nx ,ny,nz],的旋轉矩陣.
如下圖所示.


縮放


相比于旋轉而言,縮放比較簡單,(縮放的定義我就不過度的解釋了),我們就從2D的環境和3D環境以及沿著任意方向縮放三個方面來看縮放這個知識點.

2D的環境和3D環境沿著坐標軸縮放

如果沿著坐標軸進行縮放,那么每一個坐標軸都有縮放因子,所以2D環境下有兩個縮放因子Kx和Ky,那么基向量p和q根據縮放因子的影響,我們可以得到下面結論.

然后根據變換,我們就可以得到在2D環境下的縮放矩陣.如下所示.

那么,通過2D環境下的縮放矩陣,我們可以得到3D環境下的縮放矩陣.


沿著任意方向縮放
上面我們把在2D的環境和3D環境的縮放情況說明了一下,接下來我們看一下沿著任意方向縮放的情況,如圖所示.(假設在向量n方向上的縮放因子為k)

在圖中n為縮放方向,v為縮放之前的向量,v'為縮放之后的向量,aa'分別為v和v'垂直于縮放方向的分量,bb'分別為v和v'在縮放方向上的投影.

思路是這樣的,
首先v只是在n的方向上進行了縮放,所以縮放前后a是沒有任何改變的,也就是說,a = a';
bb'分別為v和v'在縮放方向上的投影,所以會有b = (v·n)nb' = (v'·n)n;
然后,再就是通過向量的加減法,我們可以得知,v = a +bv' = a' +b';

上面是三個具體的條件,我們根據條件用n,v,k來表示v'.具體的計算過程如下.

b' = kb = k(v·n)n
a' = a = v - b = v - (v·n)n
v' = a' + b' = v - (v·n)n + k(v·n)n = v +(k-1)(v·n)n

上面我們已經得到了v' 的表達式,然后我們就需要對各個基向量進行計算了,這里使用的是基向量p = [1,0],具體的計算過程如下所示.

同理,基向量 q與之類似,結果如下所示.

那么,在2D中的縮放矩陣如下所示.

3D因為原理一樣就不在推導了,在3D中的縮放矩陣結果如下所示.


正交投影


一般來說呢,投影就意味著降維操作.這篇博客主要研究的是正交投影.透視投影將在后面的博客中體現,但是我還是要那兩張圖片給來說明一下正交投影和透視投影的不同.簡單點說正交投影原來的點和投影點的直線相互平行,但是透視投影所有的投影線會相交于一點.如下所示.

正交投影
透視投影

接下來我們就直接看看2D和3D環境下的正交投影矩陣.

</b>
當然了我們也是可以向任意直線或者平面投影,直線或者平面必須通過原點的.然后我們利用縮放的結果,有如下的結果.


鏡像


鏡像是一種變換,其作用就是按照直線或者平面"翻折".如圖所示.

鏡像和投影都是可以通過縮放矩陣進行變換的,我們只需要把縮放矩陣的縮放因子設置為-1即可,那么在2D和3D情況下的沿著任意軸的鏡像矩陣如下所示.


切變


切變是一種坐標系"扭曲"變換,非均勻的拉伸它,切變的時候角度會發生改變,但是面積(2D)或者是體積(3D)不會發生改變.

具體的解釋意義如下所示.

那么在3D環境下的是切變的形式又是如何的呢?如下所示.

當然了,其實切變并不常用.??


結束語


經過兩三天的寫作,整理學習,總算是寫完了旋轉、縮放、投影、鏡像、切變的線性變換,學習3D圖形更多的是需要一個本子和一支筆,只有不斷的演算才能真正的掌握這些.如果你喜歡騷棟,請繼續關注,下一篇我將對矩陣的其他知識以及齊次矩陣的相關知識做研究整理.

最后還是要附上<<3D數學基礎 圖形與游戲開發>>的pdf版的傳送門來結束線性變換的相關知識.

--> <<3D數學基礎 圖形與游戲開發>>傳送門??
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容