[7].了解下Opengl的矩陣變換吧

跳去目錄


變換

? 在OpenGL中,所有的變換都是由縮放 平移 旋轉(zhuǎn) 這三種基本的變換方式得到的,實(shí)際上,是對(duì)片段頂點(diǎn)所進(jìn)行的操作,在圖形簡(jiǎn)單,頂點(diǎn)很少的情況下,對(duì)每個(gè)頂點(diǎn)進(jìn)行操作是可行的,但涉及到大量的頂點(diǎn)數(shù)據(jù)時(shí),這種操作就顯得笨拙且效率低下,所以引入矩陣向量 這兩個(gè)數(shù)學(xué)概念(數(shù)學(xué)果然不愧是工具),一次性的操作所有的頂點(diǎn),這樣不僅高效,而且優(yōu)雅(手動(dòng)狗頭).


向量

? 向量是由一個(gè)方向大小所構(gòu)成的,是一個(gè)矢量(有方向)單位,所以在計(jì)算的時(shí)候,單純的相加是沒(méi)有意義的(比如,向上走了10步,再向右走10步,距離起點(diǎn)的距離并不是20步),需要使用特定的方式來(lái)處理向量的運(yùn)算。在數(shù)學(xué)中,會(huì)在字母上加上一個(gè)橫線(或箭頭)來(lái)表示向量 \vec{v}

向量相加

? 向量相加并不是單純的對(duì)向量對(duì)大小進(jìn)行相加,還要考慮到向量的方向。
? \vec{v} = \begin{pmatrix} 1 \\ 2 \\ 3 \\ \end{pmatrix} , \vec{j} = \begin{pmatrix} 4 \\ 5 \\ 6 \\ \end{pmatrix} , \vec{k} = \vec{v} + \vec{j} = \begin{pmatrix} 1 + 4 \\ 2 + 5 \\ 3 + 6 \\ \end{pmatrix} = \begin{pmatrix} 5 \\ 7 \\ 9 \\ \end{pmatrix}
? \vec{v} = \begin{pmatrix} 4 \\ 5 \\ 6 \\ \end{pmatrix} , \vec{j} = \begin{pmatrix} 1 \\ 2 \\ 3 \\ \end{pmatrix} , \vec{k} = \vec{v} - \vec{j} = \begin{pmatrix} 4 - 1 \\ 5 - 2 \\ 6 - 3 \\ \end{pmatrix} = \begin{pmatrix} 3 \\ 3 \\ 3 \\ \end{pmatrix}
?
最后得到的結(jié)果分別是從原點(diǎn)(0,0,0)指向(5,7,9)的向量和從原點(diǎn)(0,0,0)指向(3,3,3)的向量.

向量相乘

兩個(gè)向量相乘是一種很奇怪的情況。普通的乘法在向量上是沒(méi)有定義的,因?yàn)樗谝曈X(jué)上是沒(méi)有意義的。但是在相乘的時(shí)候我們有兩種特定情況可以選擇:一個(gè)是點(diǎn)乘(Dot Product),記作\vec{v}?\vec{k},另一個(gè)是叉乘(Cross Product),記作\vec{v}x\vec{k}。

點(diǎn)乘
在計(jì)算時(shí),點(diǎn)乘的結(jié)果為兩個(gè)向量的大小乘以它們夾角之間的余弦值
\vec{v} · \vec{j} = ||\vec{v}| · |\vec{j}|| · \cos θ
點(diǎn)乘的結(jié)果是個(gè)標(biāo)量(相對(duì)于向量而言,沒(méi)有方向)

叉乘
叉乘只在3D空間中有定義,它需要兩個(gè)不平行向量作為輸入,生成一個(gè)正交于兩個(gè)輸入向量的第三個(gè)向量。如果輸入的兩個(gè)向量也是正交的,那么叉乘之后將會(huì)產(chǎn)生3個(gè)互相正交的向量。


矩陣

矩陣就是一個(gè)矩形的數(shù)字、符號(hào)或表達(dá)式數(shù)組。
\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ \end{bmatrix}
上面的這個(gè)表達(dá)式就是一個(gè)2×3矩陣

矩陣相加

矩陣的相加需要對(duì)矩陣的每一個(gè)位置進(jìn)行加減,最終得到一個(gè)新的矩陣
\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ \end{bmatrix} + \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ \end{bmatrix} = \begin{bmatrix} 1 + 1 & 2 + 2 & 3 + 3 \\ 4 + 4 & 5 + 5 & 6 + 6 \\ \end{bmatrix} = \begin{bmatrix} 2 & 4 & 6 \\ 8 & 10 & 12 \\ \end{bmatrix}

矩陣相減

矩陣的減法同它的加法
\begin{bmatrix} 3 & 2 & 1 \\ 6 & 5 & 4 \\ \end{bmatrix} - \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ \end{bmatrix} = \begin{bmatrix} 3-1 & 2 - 2 & 1-3 \\ 6 - 4 & 5 - 5 & 4 6 6 \\ \end{bmatrix} = \begin{bmatrix} 2 & 0 & -2 \\ 2 & 0 & -2 \\ \end{bmatrix}

矩陣乘法

矩陣中,一般是以點(diǎn)乘的形式對(duì)矩陣進(jìn)行乘法運(yùn)算

\begin{bmatrix} 1 & 2 \\ 3 & 4 \\ \end{bmatrix} · \begin{bmatrix} 5 & 6 \\ 7 & 8 \\ \end{bmatrix} = \begin{bmatrix} 1*5 + 2*7 & 1*6+2*8 \\ 3*5+4*7 & 3*6+4*8 \\ \end{bmatrix} = \begin{bmatrix} 19 & 22 \\ 43 & 50 \\ \end{bmatrix}

矩陣點(diǎn)乘


矩陣和向量

在OpenGL中,我們通常使用4×4的變換矩陣,前三個(gè)值分別代表(x,y,z),最后一個(gè)值代表縮放因子,矩陣向量 相乘將得到一個(gè)向量

矩陣乘以向量

一個(gè)4·4的矩陣乘以4·1的向量, 最終得到了4·1的向量,矩陣乘以向量的規(guī)則正是 [m·n] · \vec{n}= \vec{m} ,這是必須遵守的規(guī)則,否則OpenGL將會(huì)數(shù)據(jù)錯(cuò)亂。

縮放

縮放

位移

位移

旋轉(zhuǎn)

旋轉(zhuǎn)會(huì)麻煩一些,涉及到三角變換,切根據(jù)旋轉(zhuǎn)的軸的不同,其計(jì)算的方式也有所不同,以繞Z軸順時(shí)針旋轉(zhuǎn)60°為例(也就是360/6=60),

旋轉(zhuǎn)

旋轉(zhuǎn)為, 如果將x,y坐標(biāo)的變化及旋轉(zhuǎn)的方向(OpenGL以逆時(shí)針為負(fù))加上,則應(yīng)表示為 ,拓展到矩陣則為
繞軸旋轉(zhuǎn)

萬(wàn)向節(jié)死鎖(Gimbal Lock)

萬(wàn)向節(jié)死鎖(Gimbal Lock)

在上述的矩陣變化中,會(huì)產(chǎn)生一個(gè)新的問(wèn)題(詳見(jiàn)上述視頻地址),所產(chǎn)生的結(jié)果是片段會(huì)以一個(gè)奇怪的不符合我們希望的軌跡旋到最終的位置,為了解決這個(gè)問(wèn)題,大佬們?cè)O(shè)計(jì)了一個(gè)超級(jí)復(fù)雜的計(jì)算公式,但也不能完全解決萬(wàn)向節(jié)死鎖問(wèn)題,而OpenGL中則是使用了四元數(shù)來(lái)進(jìn)行解決(四元數(shù)-百度百科),在此不深究。


OpenGL中的變換

OpenGL對(duì)圖形做變換時(shí),最終是要得到每一個(gè)頂點(diǎn)變換后的向量,因此,需要將原頂點(diǎn)放在最后進(jìn)行計(jì)算,也即是

矩陣變換

依照上面的方式,將每個(gè)頂點(diǎn)都進(jìn)行矩陣變換,這樣,就能得到變換后的頂點(diǎn)信息了,也就能得到變換后的圖像數(shù)據(jù)了


跳去目錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容