2. threejs源碼閱讀——math/matrix

Matrix接口

Vector接口一樣畏邢,threejs也在Matrix3.d.ts文件中提供了一個Matrix接口,并且在Matrix3(3x3矩陣類)和Maxtrix4(4x4矩陣類)中實現(xiàn)了該接口。

Matrix接口

我們可以看到,矩陣中的元素是用數(shù)組的方式儲存的。由于不同維度的矩陣內(nèi)所用的元素個數(shù)不同搞挣,所以Matrix3和Matrix4的set方法是分開聲明在每個類中的。這里我們以Matrix3.set為例:

Matrix3.set

可以看到音羞,在set時是以行優(yōu)先的順序進行傳值的,也就是第一行第一個仓犬,第一行第二個嗅绰,第一行第三個,第二行第一個搀继,第二行第二個...

M_{3\times3} = \begin{pmatrix}? n11 & n12 & n13 \\? n21 & n22 & n23 \\? n31 & n32 & n33 \end{pmatrix}

但是在set方法的實現(xiàn)中窘面,可以看到elements數(shù)組內(nèi)是以列優(yōu)先的順序進行存儲的:

Matrix3.set方法實現(xiàn)

M_{3\times3} = \begin{pmatrix}? n11 \rightarrow e0 & n12 \rightarrow e3 & n13 \rightarrow e6? \\? n21 \rightarrow e1 & n22\rightarrow e4 & n23\rightarrow e7 \\? n31\rightarrow e2? & n32\rightarrow e5 & n33\rightarrow e8 \end{pmatrix}

簡單點說,這里只是存儲方式的不同叽躯。由于大多數(shù)人都習(xí)慣以行優(yōu)先的方式考慮矩陣财边,所以threejs中所有的文檔都是以行優(yōu)先的方式表示的。但如果我們想要閱讀源碼点骑,就要注意到[n11, n12, n13, n21 ... n33]并不是按順序儲存在elements中酣难。事實上如果我們按順序讀取elements中的元素并以行優(yōu)先的方式組成矩陣,它將是原本矩陣的轉(zhuǎn)置矩陣黑滴。

https://en.wikipedia.org/wiki/File:Row_and_column_major_order.svg

在閱讀后續(xù)的矩陣計算相關(guān)的方法中憨募,我們一定要時刻注意threejs的矩陣元素是以列優(yōu)先的方式存儲的!

如同Vector的類型袁辈,Matrix類型中所有返回值為自身類對象的方法也是原地修改該對象菜谣。例如Transpose轉(zhuǎn)置

Matrix3.prototype.transpose

所有的Matrix也提供了clone和copy方法,用于深拷貝不同Matrix對象晚缩。

那么threejs中的向量與矩陣進行計算是以什么形式進行的呢尾膊?這里我們舉一個例子。


行向量還是列向量荞彼?

在Vector3類中提供了appyMatrix3這個方法冈敛,這個方法以一個3x3的矩陣作為參數(shù),相乘后原地修改向量的值卿泽。

Vector3.applyMatrix3

如果我們將Vector3看做三行一列的矩陣(3x1)的話莺债,那么就需要左乘3x3矩陣滋觉,最后得到列向量:

V =\begin{pmatrix}? e0 & e3 & e6 \\? e1 & e4 & e7 \\? e2 & e5 & e8\end{pmatrix}\begin{pmatrix}x\\y\\z\end{pmatrix}=\begin{pmatrix}e0*x + e3 *y+e6*z \\e1*x+e4*y+e7*z\\e2*x+e5*y+e8*z\end{pmatrix}


如果我們將Vecot3看做一行三列的矩陣(1x3)的話,那么就需要右乘3x3矩陣齐邦,最后得到行向量:

V =\begin{pmatrix}x&y&z\end{pmatrix}\begin{pmatrix}? e0 & e3 & e6 \\? e1 & e4 & e7 \\? e2 & e5 & e8\end{pmatrix}=\begin{pmatrix}x*e0+y*e1+z*e2 &x*e3+y*e4+z*e5 &x*e6+y*e7+z*e8\end{pmatrix}

在這里我們發(fā)現(xiàn):threejs中的向量和矩陣的乘法是以列向量左乘矩陣的方式實現(xiàn)的椎侠。

接下來,我們再假設(shè)一個向量

V_{xyz} = (1,2,3)

加入齊次坐標w=1措拇,來表示三維空間中的一個點(1,2,3)

P = (1,2,3,1)

然后我們構(gòu)建一個仿射變換矩陣做縮放+平移運算

T = \begin{pmatrix}2 & 0 & 0 & 5\\0 & 2 & 0 & 5\\0 & 0 & 2 & 5\\0 & 0 & 0 & 1\end{pmatrix}

即沿著xyz軸均縮放2倍我纪,然后沿著xyz移動5個單位距離。最終結(jié)果是:

P^ \prime = \begin{pmatrix}2 & 0 & 0 & 5\\0 & 2 & 0 & 5\\0 & 0 & 2 & 5\\0 & 0 & 0 & 1\end{pmatrix}\begin{pmatrix}1\\2\\3\\1\\\end{pmatrix}= \begin{pmatrix}2 *1+ 0*2+0*3 + 5 * 1 = & 7\\0 *1+ 2*2+0*3 + 5 * 1 = &9\\0 *1+ 0*2+2*3 + 5 * 1 = &11\\0 *1+ 0*2+0*3 + 1* 1 = &1\\\end{pmatrix}

這個計算我們會使用Vector3.applyMatrix4

Vector3.applyMatrix4

接下來驗證一下:

初始化向量和矩陣并調(diào)用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稚新。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勘伺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子褂删,更是在濱河造成了極大的恐慌飞醉,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屯阀,死亡現(xiàn)場離奇詭異缅帘,居然都是意外死亡,警方通過查閱死者的電腦和手機蹲盘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門股毫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人召衔,你說我怎么就攤上這事铃诬。” “怎么了苍凛?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵趣席,是天一觀的道長。 經(jīng)常有香客問我醇蝴,道長宣肚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任悠栓,我火速辦了婚禮霉涨,結(jié)果婚禮上按价,老公的妹妹穿的比我還像新娘。我一直安慰自己笙瑟,他們只是感情好楼镐,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著往枷,像睡著了一般框产。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上错洁,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天秉宿,我揣著相機與錄音,去河邊找鬼屯碴。 笑死描睦,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的导而。 我是一名探鬼主播酌摇,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嗡载!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起仍稀,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤洼滚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后技潘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遥巴,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年享幽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡哩照,死狀恐怖染服,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奔坟,我是刑警寧澤携栋,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站咳秉,受9級特大地震影響婉支,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜澜建,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一向挖、第九天 我趴在偏房一處隱蔽的房頂上張望蝌以。 院中可真熱鬧,春花似錦何之、人聲如沸跟畅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碍彭。三九已至,卻和暖如春悼潭,著一層夾襖步出監(jiān)牢的瞬間庇忌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工舰褪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留皆疹,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓占拍,卻偏偏與公主長得像略就,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晃酒,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345