乐趣区

关于javascript:THREE-矩阵优先原则和平移旋转矩阵

优先程序

行优先

[
    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;

}
退出移动版