作者: 还是大剑师兰特 ,曾为美国某知名大学计算机专业研究生,现为国内GIS领域高级前端工程师,CSDN知名博主,深耕openlayers、leaflet、mapbox、cesium,webgl,ThreeJS,canvas,echarts等技术开发,欢迎加微信(gis-dajianshi),一起交流。
075
篇入门文章
THREE.Matrix3
是 Three.js 中用于表示三维空间中的变换矩阵的一个类,但它通常用于处理二维变换或特定类型的三维变换,如切变变换。这个类提供了一组方法来创建、操作和查询 3x3
矩阵。由于它不包含第四行和第四列,因此它通常不用于表示完整的三维变换(如平移或缩放),但对于某些特定的应用场景(如纹理坐标变换、切变变换等)非常有用。
构造函数
构造函数 new THREE.Matrix3()
用于创建一个 3x3
的矩阵对象,该矩阵初始化为单位矩阵。
属性
THREE.Matrix3
的实例拥有如下属性:
- elements: 一个包含 9 个元素的一维数组,按照列优先的方式存储矩阵的元素。数组的顺序是
[ m11, m12, m13, m21, m22, m23, m31, m32, m33 ]
。
方法
THREE.Matrix3
提供了以下常用的方法来操作和查询矩阵:
- identity(): 将矩阵重置为单位矩阵。
- set(n11, n12, n13, n21, n22, n23, n31, n32, n33): 设置矩阵的元素值。
- clone(): 返回一个新的
Matrix3
实例,其值与当前矩阵相同。 - copy(matrix): 将另一个矩阵的值复制到当前矩阵。
- transpose(): 计算当前矩阵的转置。
- determinant(): 计算矩阵的行列式。
- invert(): 计算矩阵的逆矩阵。
- multiply(matrix): 将当前矩阵与另一个矩阵相乘。
- premultiply(matrix): 将当前矩阵与另一个矩阵相乘,但当前矩阵作为被乘者。
- scale(sx, sy, sz): 将矩阵按给定的比例因子缩放。
- rotate(axis, angle): 将矩阵绕给定轴旋转指定的角度(弧度)。
- rotateX(angle): 将矩阵绕 x 轴旋转指定的角度(弧度)。
- rotateY(angle): 将矩阵绕 y 轴旋转指定的角度(弧度)。
- rotateZ(angle): 将矩阵绕 z 轴旋转指定的角度(弧度)。
- translate(tx, ty, tz): 将矩阵按给定的平移量平移。
- equals(matrix): 检查当前矩阵是否等于另一个矩阵。
- fromArray(array): 从数组中设置矩阵的元素。
- toArray(array, offset): 将矩阵的元素转换为数组。
- setFromRotationReorder(order): 从旋转顺序设置矩阵。
- getNormalMatrix(matrix4): 从一个
THREE.Matrix4
中提取法线矩阵。 - scaleRotate(s, a): 将矩阵缩放后再旋转。
- getMaxScaleOnAxis(): 获取矩阵在任意轴上的最大缩放比例。
示例
创建一个基本的 Matrix3
对象:
const matrix = new THREE.Matrix3();
matrix.set(1, 0, 0, 0, 1, 0, 0, 0, 1); // 设置为单位矩阵
创建一个旋转矩阵:
const theta = Math.PI / 4; // 45 度
const rotationMatrix = new THREE.Matrix3();
rotationMatrix.set(
Math.cos(theta), -Math.sin(theta), 0,
Math.sin(theta), Math.cos(theta), 0,
0, 0, 1
);
将矩阵与另一个矩阵相乘:
const matrix1 = new THREE.Matrix3();
matrix1.set(1, 0, 0, 0, 1, 0, 0, 0, 1); // 单位矩阵
const matrix2 = new THREE.Matrix3();
matrix2.set(2, 0, 0, 0, 2, 0, 0, 0, 1); // 缩放矩阵
const product = matrix1.clone().multiply(matrix2);
console.log(product.elements); // 输出 [2, 0, 0, 0, 2, 0, 0, 0, 1]
计算矩阵的行列式:
const matrix = new THREE.Matrix3();
matrix.set(2, 0, 0, 0, 3, 0, 0, 0, 1); // 缩放矩阵
console.log(matrix.determinant()); // 输出 6
计算矩阵的逆矩阵:
const matrix = new THREE.Matrix3();
matrix.set(2, 0, 0, 0, 3, 0, 0, 0, 1); // 缩放矩阵
const inverse = matrix.clone().invert();
console.log(inverse.elements); // 输出 [0.5, 0, 0, 0, 1/3, 0, 0, 0, 1]
使用 THREE.Matrix3
在 Three.js 中
虽然 THREE.Matrix3
通常不用于表示完整的三维变换(因为缺少第四行和第四列),但在某些特定的情况下,它可以非常有用。例如:
- 纹理坐标变换:在处理纹理贴图时,可以使用
Matrix3
来变换纹理坐标。 - 切变变换:当你需要在三维空间中实现特定的切变效果时,可以使用
Matrix3
来定义这种变换。 - 法线矩阵计算:在光照计算中,通常需要计算顶点的法线矩阵,这时可以使用
getNormalMatrix
方法从模型视图矩阵中提取法线矩阵。
示例:设置 UV 变换
假设你需要设置一个材质的 UV 变换,可以使用 Matrix3
来定义变换:
const uvTransformMatrix = new THREE.Matrix3();
uvTransformMatrix.set(
1, 0, 0,
0, 1, 0,
0.5, 0.5, 1
);
material.uvTransform = uvTransformMatrix;
这将设置 UV 坐标的平移、缩放和旋转,使得材质的 UV 坐标发生了相应的变换。
示例:提取法线矩阵
假设你需要从一个 THREE.Matrix4
中提取法线矩阵:
const modelViewMatrix = new THREE.Matrix4();
modelViewMatrix.setPosition(new THREE.Vector3(0, 0, -10));
modelViewMatrix.scale(new THREE.Vector3(2, 2, 2));
modelViewMatrix.rotateX(Math.PI / 4);
const normalMatrix = new THREE.Matrix3();
normalMatrix.getNormalMatrix(modelViewMatrix);
console.log(normalMatrix.elements); // 输出法线矩阵的元素
这将提取出法线矩阵,用于光照计算中的法线变换。
总结
THREE.Matrix3
是一个用于表示三维空间中的变换矩阵的类,提供了丰富的操作和查询矩阵的方法。虽然它通常不用于表示完整的三维变换,但在某些应用场景下,如纹理坐标变换、切变变换等,THREE.Matrix3
仍然非常有用。理解并熟练使用 THREE.Matrix3
对于开发特定类型的 Three.js 应用程序是有益的。