求一个向量变换为另一个向量的矩阵_OpenGL里旋转等变换矩阵为什么是4x4的矩阵...
OpenGL ES 的很多教程里都會(huì)有這樣一個(gè)例子來講解紋理:將一張圖片作為紋理顯示在屏幕上。
因?yàn)榧y理坐標(biāo)和實(shí)際屏幕顯示的坐標(biāo)不一樣,把圖片渲染在屏幕上后,圖片是上下顛倒的。
一個(gè)解決方法是對(duì)當(dāng)前的頂點(diǎn)坐標(biāo),乘以繞 z 軸旋轉(zhuǎn)180度的矩陣,這樣圖片就能正確顯示了。
那么如何理解這個(gè)旋轉(zhuǎn)矩陣呢?
影響我們理解這個(gè)矩陣的第一個(gè)問題是:
為什么這個(gè)矩陣是 4x4 的? 而且我們發(fā)現(xiàn)旋轉(zhuǎn),縮放、平移等變換矩陣都是 4x4 的。
在直觀上的認(rèn)知里,表達(dá)一個(gè)三維空間的坐標(biāo)用 x,y,z 就足夠了,那在三維空間里進(jìn)行矩陣變換,用 3x3 的矩陣就夠了,為什么需要 4x4 呢?
為了回答這個(gè)問題,下面我們先在幾何意義上理解**向量和矩陣之間的關(guān)系,然后通過推導(dǎo)旋轉(zhuǎn)矩陣**和平移矩陣,一步步來解開這個(gè)疑惑。
向量和矩陣
在幾何平面上,我們可以把平面上任意一點(diǎn),當(dāng)作與原點(diǎn)組成的一個(gè) 向量 來理解。
如圖 ,A 點(diǎn)可以表示成向量 ? ?;在 x 軸和 y 軸上各有 i 點(diǎn)(1, 0)和 ?j 點(diǎn)(0,1),同樣的,讓它們與原點(diǎn)組成向量,為了簡(jiǎn)化,我們用 ? ?和 表示這兩個(gè)向量。
向量和矩陣因?yàn)?A 點(diǎn)的坐標(biāo)為 (3, 2),如果我們要用 ? ?和 ?表示 ,那是這樣的:
這里的幾何意義是 延展到 ?, 延展到 ,然后把這兩個(gè)向量相加即可得到
i ?坐標(biāo)是 (1, 0),j 坐標(biāo)是 (0,1),我們把上面這個(gè)等式轉(zhuǎn)換成豎列的形式:
這里其實(shí)是向量的簡(jiǎn)單運(yùn)算,運(yùn)算過程如下:
看到運(yùn)算過程是否有種似曾相識(shí)的感覺?這不就是矩陣與向量的乘法計(jì)算嗎?這個(gè)運(yùn)算其實(shí)就是將向量左乘一個(gè)矩陣 的計(jì)算:
這里 ?其實(shí)就是單元矩陣,左乘一個(gè)單元矩陣并不會(huì)改變?cè)瓉淼闹怠6@個(gè)單元矩陣以兩個(gè)豎列來看,正是 i 和 j 點(diǎn)的坐標(biāo),也是向量 ? ?和 ? ,在數(shù)學(xué)上將 ? ?和 ? ?稱為此坐標(biāo)系的 基向量。
推導(dǎo)旋轉(zhuǎn)矩陣
我們現(xiàn)在把整個(gè)坐標(biāo)軸繞原點(diǎn)逆時(shí)針旋轉(zhuǎn) ? :
推導(dǎo)旋轉(zhuǎn)矩陣旋轉(zhuǎn)后 ?i 點(diǎn)和 j 點(diǎn)對(duì)應(yīng) ? ?和 ? 位置。
通過簡(jiǎn)單的三角函數(shù)計(jì)算得到: 坐標(biāo)為 , 坐標(biāo)為
旋轉(zhuǎn)后,A 點(diǎn)的坐標(biāo)是多少呢?回顧上面的做法, 延展到 ?, 延展到 ,然后把這兩個(gè)向量相加即可得到 。結(jié)合上面一節(jié)矩陣和向量的推演,可以變成下面的形式:
我們發(fā)現(xiàn),左邊的矩陣不正是開頭所看到的 旋轉(zhuǎn)矩陣 嗎?只不過這是二維平面上的旋轉(zhuǎn)矩陣:
結(jié)合圖形和計(jì)算,我們可以這樣理解這個(gè)二維矩陣:二維矩陣代表一個(gè)坐標(biāo)系里的兩個(gè)基向量,而在這個(gè)坐標(biāo)系里的點(diǎn)與原點(diǎn)組成的向量,都可以用這兩個(gè)基向量的變換來表示。那么旋轉(zhuǎn)一個(gè)點(diǎn),可以轉(zhuǎn)換成旋轉(zhuǎn)這個(gè)點(diǎn)所在的坐標(biāo)系,從而通過變化的基向量求出旋轉(zhuǎn)后的點(diǎn)的位置。
其實(shí)這種變換在數(shù)學(xué)上稱作 線性變換 ,線性變換是通過 矩陣乘法 來實(shí)現(xiàn)
線性變換:是在兩個(gè)向量空間(包括由函數(shù)構(gòu)成的抽象的向量空間)之間的一種保持向量加法和標(biāo)量乘法的特殊映射
線性變換在幾何直觀上有如下特點(diǎn):
變換前后,直線仍然保持是直線的狀態(tài)
變換前后,原點(diǎn)保持固定,不會(huì)變化
我們從二維平面,推導(dǎo)到三維坐標(biāo)也是同理,只不過是多了個(gè) z 軸
豎著來看這個(gè)矩陣,是 x,y,z軸上的三個(gè)基向量,同時(shí)它又是一個(gè)單元矩陣。
同理上面二維平面的推導(dǎo),三維坐標(biāo)繞 z 軸的旋轉(zhuǎn)矩陣為:
推導(dǎo)平移矩陣
那么平移操作,能不能也用這種矩陣與向量相乘的形式呢?我們?cè)俅位氐蕉S平面,看看將 A 點(diǎn)平移到 B 點(diǎn)的情況是怎樣的。
要將 A 點(diǎn)(3,2)平移到 B 點(diǎn)(4,5),實(shí)際上就是先將 A 點(diǎn)往右移動(dòng) 1 ,再往上移動(dòng) 3,即 x 坐標(biāo)值增加 1,y坐標(biāo)值增加 3
從上面的運(yùn)算來看,平移這種操作實(shí)際上是 向量的加法,即:
我們可以通過向量加法的 平行四邊形法則 加深理解,如下圖:
對(duì)于平移這種操作,我們無法僅僅通過矩陣乘法來實(shí)現(xiàn)。
而實(shí)際上,平移這種操作屬于 仿射變換 。
仿射變換,又稱仿射映射,是指在幾何中,對(duì)一個(gè)向量空間進(jìn)行一次線性變換并接上一個(gè)平移,變換為另一個(gè)向量空間。
仿射變換在幾何直觀上,相比線性變換,它不需要保證變換前后坐標(biāo)原點(diǎn)不變。
如下圖,從 A 點(diǎn)平移到 B 點(diǎn),我們換一個(gè)角度思考,這次不移動(dòng)點(diǎn),而是移動(dòng)整個(gè)坐標(biāo)軸,同樣可以達(dá)到平移 A 點(diǎn)到 B 點(diǎn)的需求,但是坐標(biāo)原點(diǎn)移動(dòng)到了 O' 點(diǎn)(1,3)。
我們希望構(gòu)造的是像下面這種矩陣乘法的等式,這樣才能用一個(gè)通用的計(jì)算模式來處理坐標(biāo)點(diǎn)的變換。
矩陣到這里,我們終于要請(qǐng)出 齊次坐標(biāo) 了。
齊次坐標(biāo)就是將一個(gè)原本是 n 維的向量用一個(gè) n+1 維向量來表示,是指一個(gè)用于投影幾何里的坐標(biāo)系統(tǒng),如同用于歐氏幾何里的笛卡兒坐標(biāo)一般。
用一個(gè)通俗的講法是,我們需要 升維 來處理這個(gè)問題。
通過增加一個(gè)維度,我們可以在高維度上,通過線性變換來處理低維度的仿射變換。
這句話咋一聽感覺很有哲理,但是通過下面的數(shù)學(xué)等式就能知道其中的奧妙:
觀察上面的運(yùn)算過程,結(jié)果 不正是我們上面所得的 嗎?只不過多了一個(gè) z 軸的坐標(biāo)值。
我們通過升級(jí)一個(gè)維度,將在二維平面上的平移問題轉(zhuǎn)換成了在三維坐標(biāo)的矩陣和向量乘法。那么在二維平面上,這個(gè)平移矩陣就為:
tx 和 ty 就對(duì)應(yīng)在 x 軸 和 y 軸上的移動(dòng)距離。
同理推廣到三維坐標(biāo)系,要實(shí)現(xiàn)三維坐標(biāo)的平移操作,同樣需要通過升維,引入齊次坐標(biāo)來計(jì)算。那么三維坐標(biāo)下的平移矩陣就為:
總結(jié)
至此,我們可以回答最開始的問題了,為什么 OpenGL 里的矩陣變換是 4x4 的矩陣呢?
我們來想象這樣一個(gè)場(chǎng)景:如果我要讓頂點(diǎn)坐標(biāo)旋轉(zhuǎn)一定角度后,再平移一段距離,那么這里面的操作就涉及 3x3 矩陣的計(jì)算和 4x4 矩陣的計(jì)算,如果不統(tǒng)一起來,這種連續(xù)變換的計(jì)算操作將很復(fù)雜。
所以如果要用矩陣乘法來統(tǒng)一所有的平移、旋轉(zhuǎn)等等變換計(jì)算,為了照顧到平移這類仿射變換,統(tǒng)一用 4x4 矩陣來計(jì)算既能滿足場(chǎng)景又方便計(jì)算。
總結(jié)
以上是生活随笔為你收集整理的求一个向量变换为另一个向量的矩阵_OpenGL里旋转等变换矩阵为什么是4x4的矩阵...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: yearning 2. 部署_对于企业来
- 下一篇: 如何获取图像的驱动_Adobe Came