优先程序
行优先
[ 1,2,3,4 5,6,7,8, 9,10,11,12]
如果是行优先,如上读取程序为 1234, 5678, 9101112
列优先
[ 1,2,3,4 5,6,7,8, 9,10,11,12]
如果是行优先,如上读取程序为 159, 2610, 3711,4812
THREE优先规定
所有外部计算贮存的矩阵都是列优先, 然而行优先更适宜人的浏览程序, 所以 Matrix.set办法应用的是行优先读入, 读取的都是列优先.
const a = new THREE.Matrix3()a.set(1,2,3,4,5,6,7,8,9)console.log('矩阵: ====>', a.elements) // (9) [1, 4, 7, 2, 5, 8, 3, 6, 9]
为了浏览,以下矩阵都是用行优先展现
行优先转列优先
set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { const te = this.elements; te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; return this;}
set办法 将行优先的矩阵转换成了列优先矩阵, 矩阵计算全副都会通过set办法
转换成列优先
ApplyMatrix4
applyMatrix4( m ) { const x = this.x, y = this.y, z = this.z; const e = m.elements; const w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; return this; }
applyMatrix4的参数m是通过set办法转换的列优先矩阵
依据下面的办法, 很容易得出平移矩阵:
const a = new THREE.Matrix4()a.set( 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1)
这是xyz别离平移1单位的矩阵。 所以得悉平移矩阵的通用矩阵
1, 0, 0, dx,0, 1, 0, dy,0, 0, 1, dz,0, 0, 0, 1
对于旋转矩阵 不免和三角函数搭上关系。
对于旋转都是以逆时针旋转为正角度, 顺时针为负角度。
对于X轴的旋转矩阵依据上图很容易写出
[ 1, 0, 0, 0, 0, cosN, -sinN, 0, 0, sinN, cosN, 0, 0, 0, 0, 1]
对于任意轴旋转的话, 能够间接看threejs的源码
makeRotationAxis( axis, angle ) { // Based on http://www.gamedev.net/reference/articles/article1199.asp const c = Math.cos( angle ); const s = Math.sin( angle ); const t = 1 - c; const x = axis.x, y = axis.y, z = axis.z; const tx = t * x, ty = t * y; this.set( tx * x + c, tx * y - s * z, tx * z + s * y, 0, tx * y + s * z, ty * y + c, ty * z - s * x, 0, tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 0, 0, 0, 1 ); return this;}