three.js中的矩阵计算

1. 概述

three.js中自带了矩阵运算库,不过在使用的过程中总是容易混淆。不知道是行主序还是列主序,前乘和后乘也很容易弄反。就在这里辨析一下。

2. 详论

2.1. 行主序与列主序列

很早就知道OpenGL中使用的矩阵是列主序,而Direct3D中使用的是行主序,但是没什么具体的体会,还直接弄混淆了。应该来说,无论Direct3D还是OpenGL,使用的矩阵应该都能线性代数中描述的矩阵是等价的,只不过存储方式不同。矩阵在编程实现中一般会表示成数组的形式,以线性代数中描述的矩阵为标准,行主序就是依次按行存储,而列主序就是依次按列存储。

在threeJS中:

var A = new THREE.Matrix4();
A.set(1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
    13, 14, 15, 16);
console.log(A);

var B = new THREE.Matrix4();
B.set(16, 15, 14, 13,
    12, 11, 10, 9,
    8, 7, 6, 5,
    4, 3, 2, 1);
console.log(B);

var C = new THREE.Matrix4();
C.multiplyMatrices (A, B);    
console.log(C);

其运行结果为:
imglink1

在网上找一个在线矩阵计算器,相对应的计算结果如下:
imglink2

因此可以认为,threejs矩阵内部储存形式为列主序,表达和描述的仍然是线性代数中行主序,set()函数就是以行主序接受矩阵参数的。

2.2. 矩阵乘法

前面用到的矩阵乘法是新建了一个矩阵,调用multiplyMatrices。threejs矩阵还有前乘和后乘的区别,也很容易混淆。

在threeJS中矩阵的后乘方法为multiply():

var A = new THREE.Matrix4();
A.set(1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
    13, 14, 15, 16);

var B = new THREE.Matrix4();
B.set(16, 15, 14, 13,
    12, 11, 10, 9,
    8, 7, 6, 5,
    4, 3, 2, 1);

A.multiply(B);
console.log(A);
console.log(B);

其运行结果为:
imglink3

表明后乘方法multiply()的结果就是\(A * B\)

反过来,使用前乘方法premultiply():

var A = new THREE.Matrix4();
A.set(1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
    13, 14, 15, 16);

var B = new THREE.Matrix4();
B.set(16, 15, 14, 13,
    12, 11, 10, 9,
    8, 7, 6, 5,
    4, 3, 2, 1);

A.premultiply(B);
console.log(A);
console.log(B);

其运行结果为:
imglink4

对比在线矩阵计算器中的计算结果:
imglink5

表明前乘方法premultiply()的结果是\(B * A\)

3. 参考

在线矩阵计算器

posted @ 2020-09-07 23:30  charlee44  阅读(2496)  评论(0编辑  收藏  举报