向量
了解向量之前,先了解什么是標(biāo)量
- 標(biāo)量:只有大小,例如:1,12,13等
- 向量是有方向的標(biāo)量,即不僅有大小,還有方向
單位向量
單位向量是長(zhǎng)度為1的向量,向量長(zhǎng)度通過下列公式計(jì)算

如果一個(gè)向量不是單位向量,可以通過單位化將其轉(zhuǎn)化為單位向量,即 非零向量除以向量的模,如下圖所示

向量點(diǎn)乘
- 點(diǎn)乘只能發(fā)生在兩個(gè)向量之間,且點(diǎn)乘時(shí),兩向量必須是單位向量,如果不是,需要將向量進(jìn)行單位化后,再點(diǎn)乘
-
點(diǎn)乘得到的是兩個(gè)向量之間的夾角的余弦值 即 cosα,范圍在[-1, 1]之間,是一個(gè)標(biāo)量
向量點(diǎn)乘
- OpenGL中針對(duì)相應(yīng)點(diǎn)乘,提供了兩個(gè)函數(shù)
- m3dDotProduct3:獲得2個(gè)向量量之間的點(diǎn)乘結(jié)果,即余弦值 = cosα
- m3dGetAngleBetweenVector3:獲取2個(gè)向量之間夾?的角度,即α = arccos(余弦值)
向量叉乘
兩個(gè)向量之間叉乘得到結(jié)果同樣是一個(gè)向量,且該向量垂直于兩個(gè)向量所構(gòu)成的平面,
-
由于結(jié)果與兩向量構(gòu)成平面垂直,也可以理解為得到的結(jié)果是該平面的法線
向量叉乘 -
OpenGL中針對(duì)向量叉乘也提供了對(duì)應(yīng)的API
- m3dCrossProduct3:獲得2個(gè)向量之間的叉乘結(jié)果得到一個(gè)新的向量
OpenGL中向量
- 向量的表示:有兩種方式,三維和四維,如圖所示
| math3d庫中的數(shù)據(jù)類型 | 說明 |
|---|---|
| M3DVector3f | 表示?一個(gè)三維向量量(x,y,z) |
| M3DVector4f | 表示?一個(gè)四維向量量(x,y,z,w) w是縮放因子,在典型情況下,w一般設(shè)置為1.0,x、y、z值通過除以w,來進(jìn)行縮放,當(dāng)w=1.0時(shí),想xyz的值本質(zhì)上不會(huì)發(fā)生變化 |
-
關(guān)于向量點(diǎn)乘和叉乘對(duì)應(yīng)API匯總
OpenGL中向量的API
矩陣
單位矩陣
- 主對(duì)角線上數(shù)據(jù)都是1,其余元素都是0,即為單元矩陣
- 向量 X 單元矩陣 = 向量 X 1,不會(huì)發(fā)生任何變化
- 向量與單元矩陣相乘的前提是:向量的列數(shù) == 單元矩陣的行數(shù)
矩陣分類
- 行優(yōu)先矩陣:一行一行讀取
- 列優(yōu)先矩陣:一列一列讀取
- 兩者的關(guān)系為:行優(yōu)先矩陣經(jīng)過轉(zhuǎn)置 即可的到列優(yōu)先矩陣

矩陣的點(diǎn)乘
- 矩陣可以進(jìn)行點(diǎn)乘的前提:兩個(gè)矩陣的行列數(shù)相等
-
矩陣A · 矩陣B = 矩陣C
-規(guī)則: 矩陣A的第一個(gè)元素與矩陣B的第一個(gè)元素的乘積 = 矩陣C的第一個(gè)元素
矩陣點(diǎn)乘
矩陣的叉乘
- 矩陣可以進(jìn)行叉乘的前提:第一個(gè)矩陣的列數(shù) = 第二個(gè)矩陣的行數(shù)
- 矩陣A X 矩陣B = 矩陣C
-
規(guī)則:矩陣A第一行與矩陣B第一列對(duì)應(yīng)元素乘積的綜合 = 矩陣C的第一個(gè)元素
矩陣叉乘
-
OpenGL中的矩陣
- OpenGL中單元矩陣有3中初始化方法
-
通過
GLFloat定義一個(gè)一維數(shù)組
矩陣初始化方式1 -
通過
M3DMatrix44f創(chuàng)建一個(gè)單元矩陣
單元矩陣初始化方式2
-
- 通過方法`m3dLoadIdentity44f`創(chuàng)建單元矩陣
void m3dLoadIdentity44f(M3DMatrix44f m);
- OpenGL中,使用較多的矩陣都是一維數(shù)組創(chuàng)建的,且規(guī)定使用以列為主的矩陣排序。
- OpenGL中的矩陣都是4x4的,每一列都是由4個(gè)元素組成的向量,如圖所示
- 第一列表示x軸方向
- 第二列表示y軸方向
- 第三列表示z軸方向
- 第四列表示交換位置
- 列向量進(jìn)行了特殊的標(biāo)注,表示這是以列為主的矩陣,主要體現(xiàn)為矩陣的最后一行都是0,只有最后一個(gè)元素為1

理解OpenGL中的矩陣相乘
數(shù)學(xué)角度
- 數(shù)學(xué)中為了方便計(jì)算,都是以行矩陣為標(biāo)準(zhǔn),從左到右的順序進(jìn)行計(jì)算,所以在數(shù)學(xué)中,頂點(diǎn)將以行向量的方式表示
- 從數(shù)學(xué)角度理解mvp矩陣的計(jì)算,由于頂點(diǎn)是行向量,要滿足矩陣相乘的規(guī)定條件(即 叉乘的前提),必須將mvp矩陣放在右邊,屬于右乘
- 頂點(diǎn)向量 = V_local * M_model * M_view * M_pro
-
頂點(diǎn)向量 = 頂點(diǎn) * 模型矩陣 * 觀察矩陣 * 投影矩陣
數(shù)學(xué)角度
OpenGL角度
- OpenGL中的矩陣規(guī)定是以列為主,所以頂點(diǎn)以列向量的方式表示
-
從OpenGL角度理解mvp矩陣的計(jì)算,由于頂點(diǎn)是列向量,如果項(xiàng)進(jìn)行矩陣規(guī)則,就需要滿足矩陣相乘的條件,需要將mvp矩陣的順序顛倒為pvm,且放在列向量的左邊,屬于左乘
OpenGL角度
OpenGL矩陣堆棧中矩陣相乘源碼分析
從OpenGL矩陣堆棧中矩陣相乘源碼分析,主要有以下3步
-從棧頂獲取棧頂矩陣,復(fù)制到mTemp
- 將棧頂矩陣 mTemp 左乘 mMatrix
-
將結(jié)果放回棧頂,覆蓋棧頂矩陣
矩陣相乘源碼
而我們?cè)谟^察者不動(dòng)、物體動(dòng)的觀察方式中,根據(jù)之前Demo代碼可知

- ChangeSize函數(shù)中,得到投影矩陣,將投影矩陣壓入投影矩陣堆棧棧頂,并與模型視圖矩陣棧頂相乘,將結(jié)果覆蓋棧頂,即 投影矩陣 * 單元矩陣 = 投影矩陣
- RenderScene函數(shù)中,將棧頂矩陣copy一份,然后將觀察者矩陣與模型視圖矩陣堆棧棧頂相乘,其結(jié)果覆蓋棧頂矩陣,即投影矩陣 * 視圖矩陣 = 視圖投影矩陣
- 得到模型矩陣,將模型矩陣與棧頂矩陣相乘,其結(jié)果覆蓋棧頂矩陣,即 棧頂 = 模型視圖投影矩陣
上述代碼,矩陣堆棧的變化過程如下

由此可知,在實(shí)際的代碼中,mvp矩陣的計(jì)算順序是pvm,最后再將mvp矩陣與頂點(diǎn)矩陣相乘,得到物體變換后的頂點(diǎn)和位置。









