Matrix接口
與Vector接口一樣畏邢,threejs也在Matrix3.d.ts文件中提供了一個Matrix接口,并且在Matrix3(3x3矩陣類)和Maxtrix4(4x4矩陣類)中實現(xiàn)了該接口。
我們可以看到,矩陣中的元素是用數(shù)組的方式儲存的。由于不同維度的矩陣內(nèi)所用的元素個數(shù)不同搞挣,所以Matrix3和Matrix4的set方法是分開聲明在每個類中的。這里我們以Matrix3.set為例:
可以看到音羞,在set時是以行優(yōu)先的順序進行傳值的,也就是第一行第一個仓犬,第一行第二個嗅绰,第一行第三個,第二行第一個搀继,第二行第二個...
但是在set方法的實現(xiàn)中窘面,可以看到elements數(shù)組內(nèi)是以列優(yōu)先的順序進行存儲的:
簡單點說,這里只是存儲方式的不同叽躯。由于大多數(shù)人都習(xí)慣以行優(yōu)先的方式考慮矩陣财边,所以threejs中所有的文檔都是以行優(yōu)先的方式表示的。但如果我們想要閱讀源碼点骑,就要注意到[n11, n12, n13, n21 ... n33]并不是按順序儲存在elements中酣难。事實上如果我們按順序讀取elements中的元素并以行優(yōu)先的方式組成矩陣,它將是原本矩陣的轉(zhuǎn)置矩陣黑滴。
在閱讀后續(xù)的矩陣計算相關(guān)的方法中憨募,我們一定要時刻注意threejs的矩陣元素是以列優(yōu)先的方式存儲的!
如同Vector的類型袁辈,Matrix類型中所有返回值為自身類對象的方法也是原地修改該對象菜谣。例如Transpose轉(zhuǎn)置
所有的Matrix也提供了clone和copy方法,用于深拷貝不同Matrix對象晚缩。
那么threejs中的向量與矩陣進行計算是以什么形式進行的呢尾膊?這里我們舉一個例子。
行向量還是列向量荞彼?
在Vector3類中提供了appyMatrix3這個方法冈敛,這個方法以一個3x3的矩陣作為參數(shù),相乘后原地修改向量的值卿泽。
如果我們將Vector3看做三行一列的矩陣(3x1)的話莺债,那么就需要左乘3x3矩陣滋觉,最后得到列向量:
如果我們將Vecot3看做一行三列的矩陣(1x3)的話,那么就需要右乘3x3矩陣齐邦,最后得到行向量:
在這里我們發(fā)現(xiàn):threejs中的向量和矩陣的乘法是以列向量左乘矩陣的方式實現(xiàn)的椎侠。
接下來,我們再假設(shè)一個向量
加入齊次坐標w=1措拇,來表示三維空間中的一個點(1,2,3)
然后我們構(gòu)建一個仿射變換矩陣做縮放+平移運算
即沿著xyz軸均縮放2倍我纪,然后沿著xyz移動5個單位距離。最終結(jié)果是:
這個計算我們會使用Vector3.applyMatrix4
接下來驗證一下:
控制臺打印結(jié)果:
結(jié)論
threejs中的矩陣以行優(yōu)先的形式初始化丐吓,以列優(yōu)先的形式儲存浅悉。
threejs中的向量采用列向量,與矩陣做左乘運算券犁。
threejs中一個三維向量與4x4的矩陣進行運算時术健,會先給三維向量補充第四個值w,也就是齊次坐標粘衬,w值與矩陣的第四行有關(guān)系:
const w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );
在上面的例子中荞估,我們使用了一個縮放+平移的仿射變換矩陣作為例子,此時w為1稚新。