最终的变换向量 = 原始向量 * 变换矩阵
用我们上面例子中的方法来还原这个公式,即:
var vector = new THREE.Vector3(20, 20, 0); var matrix = new THREE.Matrix4(); matrix.makeTranslation(10, 40, 0); vector.applyMatrix4(matrix);
除了平移,Three的API中还提供了rotation和scale,scale变化很简单,它将使用makeScale(x, y, z)这个方法来表示缩放。
而旋转则相对复杂许多,Three.js提供以下旋转方法:
matrix.makeRotationX(angle); matrix.makeRotationY(angle); matrix.makeRotationZ(angle); matrix.makeRotationAxis(axis, angle); matrix.makeRotationFromEuler(euler); matrix.makeRotationFromQuaternion(quaternion);
前三个方法分别代表的是绕X、Y、Z三个轴旋转,无需赘述。
第四个方法是前三个方法的整合版,第一个参数表示的是代表xyz的THREE.Vector3,第二个参数是旋转的弧度。下面两行代码是等价的:
matrix.makeRotationX(Math.PI); matrix.makeRotationAxis(new THREE.Vector3(1, 0, 0), Math.PI);
第五个方法表示围绕x、y和z轴的旋转,这是表示旋转最常用的方式;第六个方法是一种基于轴和角度表示旋转的替代方法。
最后,Three.js api提供了一种方法来创建表示平移,旋转和缩放的组合的矩阵 -- matrix.compose:
var translation = new THREE.Vector3(); var rotation = new THREE.Quaternion(); var scale = new THREE.Vector3(); var matrix = new THREE.Matrix4(); matrix.compose(translation, rotation, scale);
矩阵相乘
矩阵乘法的意义在于叠加。
上图表示了三个变化:旋转、缩放和移动。
通过按次序相乘,三个变化矩阵可以得出一个最终的变化矩阵:
combinedMatrix = rotationMatrix * scaleMatrix * translationMatrix;
Three.js里提供了两种矩阵相乘的方法:
第一种方法表示将矩阵乘以另一个矩阵;而第二种方法代表的是将矩阵设置为matrixA * matrixB的结果。
我们在示例中也使用到了第一个方法:将圆柱体的矩阵乘以新的平移矩阵,和将球的矩阵乘以一个旋转矩阵。
需要注意的是,乘法交换律不适用于矩阵乘法,矩阵乘法是具有次序的,先旋转再移动和先移动再旋转的结果是完全不同的。
矩阵的逆
在数字的运算里,除法相当于是乘法的“撤销”操作:
4 x 5 = 20 20 / 5 = 4
但是在矩阵计算里,这个守则同样是不适用的。我们不能用向量去除一个矩阵,我们只能用向量去乘以一个矩阵的逆矩阵,来完成“撤销”的操作。
变化后的向量 = 原始向量 * 变化矩阵;
逆矩阵 = 变化矩阵.inverse();
原始向量 = 变化后的向量 * 逆矩阵;
逆矩阵表示的是相反的变换。
Three.js里提供了一种计算逆矩阵的方法:
var matrix = new THREE.Matrix4(); var inverseMatrix = new THREE.Matrix4(); matrix.getInverse(inverseMatrix);
除此之外,逆矩阵还应用在3D场景中处理相机对象的时候。
最后
矩阵在3D世界里是一种十分强大的工具,它能够将任意变换都表示为一种相似的结构,并采用相同的计算过程。而实际上,矩阵的世界远远比这里介绍的内容更多,希望通过这些简要的介绍,可以让我们进入到一个更深的领域,并游刃有余的利用他处理图形开发中更复杂的场景。
好了,