three Matrix3 三维矩阵

402 阅读10分钟

在 Three.js 中,THREE.Matrix3 是一个用于表示和操作 3x3 矩阵的类。这个类在三维图形计算中非常重要,常用于处理旋转、缩放和其他变换。下面是关于 THREE.Matrix3 的一些重要信息:

Constructor
Matrix3( n11 : Number, n12 : Number, n13 : Number, n21 : Number, n22 : Number, n23 : Number, n31 : Number, n32 : Number, n33 : Number )
使用给定参数按行优先顺序创建 3x3 矩阵。如果未提供参数,构造函数会将 Matrix3 初始化为 3x3 单位矩阵。

Matrix3 有一个属性 二十三个方法

属性

  • elements : Array 你可以通过 elements 属性访问矩阵的所有元素。这个属性是一个包含 9 个元素的浮点数组。以下是如何访问和设置这些元素的示例:
    // 创建一个 Matrix3 实例
    const matrix = new THREE.Matrix3();
    // 访问元素
    const elements = matrix.elements;
    // 打印元素
    console.log(elements); // 输出: [1, 0, 0, 0, 1, 0, 0, 0, 1] (单位矩阵)
    // 修改元素
    elements[0] = 2; // m11
    elements[4] = 2; // m22
    console.log(elements); // 输出: [2, 0, 0, 0, 2, 0, 0, 0, 1]

方法

  • clone () : Matrix3 创建一个新的矩阵,元素 elements 与该矩阵相同。
  • copy ( m : Matrix3 ) : this 将矩阵m的元素复制到当前矩阵中。
  • determinant () : Float 在 THREE.Matrix3 中,determinant() 方法用于计算和返回 3x3 矩阵的行列式值。行列式是一个重要的数学概念,广泛应用于线性代数中,特别是在计算矩阵的可逆性和在变换中的应用。
在行列式的计算公式中,`a_{11}``a_{12}``a_{13}` 等符号用于表示 3x3 矩阵中的具体元素。
这些符号有助于指代矩阵中的每个数值。

1728872809843.png

    // 创建一个 3x3 矩阵
    const matrix = new THREE.Matrix3();
    matrix.set(
        2, 3, 1,  // 第一行
        1, 0, 4,  // 第二行
        5, 2, 1   // 第三行
    );
    // 打印矩阵
    console.log("Matrix A:");
    console.log(matrix);
    // 计算行列式
    const determinant = matrix.determinant();
    console.log(`Determinant of the matrix: ${determinant}`);

// 以下是计算过程

    // 定义一个 3x3 矩阵
    const matrix = [
        [2, 3, 1],
        [1, 0, 4],
        [5, 2, 1]
    ];
    // 函数计算 3x3 矩阵的行列式
    function calculateDeterminant(matrix) {
        const a11 = matrix[0][0]; // 2
        const a12 = matrix[0][1]; // 3
        const a13 = matrix[0][2]; // 1
        const a21 = matrix[1][0]; // 1
        const a22 = matrix[1][1]; // 0
        const a23 = matrix[1][2]; // 4
        const a31 = matrix[2][0]; // 5
        const a32 = matrix[2][1]; // 2
        const a33 = matrix[2][2]; // 1
        // 计算部分
        const part1 = a22 * a33 - a23 * a32; // -8
        const part2 = a21 * a33 - a23 * a31; // -19
        const part3 = a21 * a32 - a22 * a31; // 2
        // 计算行列式
        const determinant = 
            a11 * part1 
            - a12 * part2 
            + a13 * part3;
        return determinant;
    }
    // 计算行列式
    const determinant = calculateDeterminant(matrix);
    console.log(`Determinant of the matrix: ${determinant}`); // 输出结果: 43
  • equals ( m : Matrix3 ) : Boolean 如果矩阵m 与当前矩阵所有对应元素相同则返回true。
  • extractBasis ( xAxis : Vector3, yAxis : Vector3, zAxis : Vector3 ) : this 将该矩阵的基向量 basis 提取到提供的三个轴向中。如果该矩阵如下: 1728874154254.png
  • fromArray ( array : Array, offset : Integer ) : this Matrix3.fromArray 是 Three.js 中 Matrix3 类的一个方法,主要用于从给定的数组中填充 3x3 矩阵的值。这个方法允许你将一个数组中的元素直接加载到矩阵中,方便进行矩阵的初始化或更新,offset 参数用于指定从输入数组的哪个位置开始读取数据。
    // 创建一个新的 3x3 矩阵
    const matrix = new THREE.Matrix3();
    // 定义一个包含多个矩阵数据的数组
    const array = [
        1, 0, 0,   // 矩阵1的第一列
        0, 1, 0,   // 矩阵1的第二列
        0, 6, 1,   // 矩阵1的第三列
        1, 0, 0,   // 矩阵2的第一列
        0, 1, 0,   // 矩阵2的第二列
        0, 2, 1,   // 矩阵2的第三列
    ];
    // 使用 offset 从数组的第0个位置读取数据(默认情况)
    matrix.fromArray(array, 0);
    console.log(matrix.elements); // 输出: [1, 0, 0, 0, 1, 0, 0, 6, 1]
    // 创建另一个矩阵并使用 offset 从数组的第3个位置读取数据(矩阵2)
    const anotherMatrix = new THREE.Matrix3();
    anotherMatrix.fromArray(array, 3);
    console.log(anotherMatrix.elements); // 输出: [0, 1, 0, 0, 6, 1, 1, 0, 0]
  • invert () : this 将当前矩阵翻转为它的逆矩阵,使用 analytic method 解析方式。你不能对行或列为 0 的矩阵进行翻转,如果你尝试这样做,该方法将生成一个零矩阵。 1728875722323.png

1728875689317.png

    // 可逆性: 确保矩阵是可逆的。在调用 invert() 方法之前,通常可以使用 determinant() 方法检查矩阵的行列式是否为零。
    // 性能: 计算逆矩阵可能会比较耗时,因此在性能敏感的场景中,应尽量减少频繁的逆矩阵计算。
    // 创建一个新的 3x3 矩阵
    const matrix = new THREE.Matrix3();
    // 设置矩阵的值
    matrix.set(
        1, 2, 3,
        0, 1, 4,
        5, 6, 0
    );
    // 计算矩阵的逆
    const invertedMatrix = matrix.invert();
    // 输出原始矩阵和逆矩阵的元素
    console.log("原始矩阵:", matrix.elements); // [-24, 20, -5, 18, -15, 4, 5, -4, 1]
    console.log("逆矩阵:", invertedMatrix.elements);// [-24, 20, -5, 18, -15, 4, 5, -4, 1]
  • getNormalMatrix ( m : Matrix4 ) : this getNormalMatrix 是 Three.js 中 Matrix3 类的一个方法,用于计算法向量矩阵。法向量矩阵主要用于处理模型的法向量,以确保在进行光照计算时正确地反映模型的形状和方向。下面是这个方法的详细说明和计算步骤。 1728875989287.png
    // 创建一个 Matrix4 矩阵,表示模型的变换
    const modelMatrix = new THREE.Matrix4();
    modelMatrix.makeTranslation(1, 2, 3);  // 平移变换
    // 创建一个 Matrix3 对象
    const normalMatrix = new THREE.Matrix3();
    // 计算法向量矩阵
    normalMatrix.getNormalMatrix(modelMatrix);
    // 输出法向量矩阵
    console.log("法向量矩阵:", normalMatrix.elements); // 法向量矩阵:(9) [1, 0, 0, 0, 1, 0, 0, 0, 1]
  • identity () : this 将此矩阵重置为3x3单位矩阵:固定为下图 1728876099893.png
  • makeRotation ( theta : Float ) : this makeRotation 是 Three.js 中 Matrix3 类的一个方法,用于创建一个旋转矩阵。这个旋转矩阵可以用于在三维空间中对物体进行旋转。该方法接收一个旋转角度(以弧度为单位)作为参数,并返回一个新的旋转矩阵。

1728876277212.png

    // 创建一个 Matrix3 对象
    const rotationMatrix = new THREE.Matrix3();
    // 定义旋转角度(以弧度为单位)
    const angle = Math.PI / 4; // 旋转 45 度
    // 创建旋转矩阵
    rotationMatrix.makeRotation(angle);
    // 输出旋转矩阵
    console.log("旋转矩阵:", rotationMatrix.elements);//旋转矩阵: [0.7071067811865476, -0.7071067811865475, 0,            0.7071067811865475, 0.7071067811865476, 0,            0, 0, 1]
  • makeScale ( x : Float, y : Float ) : this makeScale 是 Three.js 中 Matrix3 类的一个方法,用于创建一个缩放矩阵。这个缩放矩阵可以用于在三维空间中对物体进行缩放,允许在不同方向上按不同的比例缩放物体。该方法接收两个参数,分别表示在 x 轴和 y 轴的缩放因子,并返回一个新的缩放矩阵。

1728876310740.png

    // 创建一个 Matrix3 对象
    const scaleMatrix = new THREE.Matrix3();
    // 定义缩放因子
    const scaleX = 2; // 在 x 轴上缩放 2 倍
    const scaleY = 0.5; // 在 y 轴上缩放 0.5 倍
    // 创建缩放矩阵
    scaleMatrix.makeScale(scaleX, scaleY);
    // 输出缩放矩阵
    console.log("缩放矩阵:", scaleMatrix.elements); // 缩放矩阵: [2, 0, 0, 0, 0.5, 0, 0, 0, 1]
  • makeTranslation ( v : Vector2 ) : this makeTranslation 是 Three.js 中 Matrix3 类的一个方法,用于创建一个平移矩阵。该方法接受一个 Vector2 对象作为参数,表示在二维空间中的平移向量,并返回一个新的平移矩阵, 1728876443309.png makeTranslation ( x : Float, y : Float ) : this该方法也可以接受两个参数,分别表示在 x 轴和 y 轴的平移量,并返回一个新的平移矩阵。 1728876601485.png
    // 创建一个 Matrix3 对象
    const translationMatrix = new THREE.Matrix3();
    // 创建一个 Vector2 对象,表示平移向量
    const translationVector = new THREE.Vector2(3, 4); // 平移 3 单位到 x 轴,4 单位到 y 轴
    // 创建平移矩阵
    translationMatrix.makeTranslation(translationVector);
    // 输出平移矩阵
    console.log("平移矩阵:", translationMatrix.elements); // 平移矩阵: [1, 0, 0, 0, 1, 0, 3, 4, 1]
    
    // 传两个参数
    // 创建一个 Matrix3 对象
    const translationMatrix = new THREE.Matrix3();
    // 定义平移量
    const translateX = 3; // 在 x 轴上平移 3 单位
    const translateY = 4; // 在 y 轴上平移 4 单位
    // 创建平移矩阵
    translationMatrix.makeTranslation(translateX, translateY);
    // 输出平移矩阵
    console.log("平移矩阵:", translationMatrix.elements);// 平移矩阵: [1, 0, 0, 0, 1, 0, 3, 4, 1]
  • multiply ( m : Matrix3 ) : this 将当前矩阵乘以矩阵m。 1728877054432.png
    // 创建两个 Matrix3 对象
    const matrixA = new THREE.Matrix3();
    const matrixB = new THREE.Matrix3();
    // 定义 matrixA
    matrixA.set(
        1, 2, 3,
        4, 5, 6,
        7, 8, 9
    );
    // 定义 matrixB
    matrixB.set(
        9, 8, 7,
        6, 5, 4,
        3, 2, 1
    );
    // 输出两个矩阵
    console.log("矩阵 A:", matrixA.elements); // 矩阵 A:[1, 4, 7, 2, 5, 8, 3, 6, 9]
    console.log("矩阵 B:", matrixB.elements); // 矩阵 B:[9, 6, 3, 8, 5, 2, 7, 4, 1]
    // 使用 multiply 方法进行矩阵相乘
    const resultMatrix = matrixA.multiply(matrixB);
    // 输出乘积矩阵
    console.log("乘积矩阵:", resultMatrix.elements);// 乘积矩阵: [30, 84, 138, 24, 69, 114, 18, 54, 90]
    
    // 创建旋转矩阵
    const rotationMatrix = new THREE.Matrix3().makeRotationZ(Math.PI / 4); // 旋转 45 度
    // 创建平移矩阵
    const translationMatrix = new THREE.Matrix3().makeTranslation(5, 5); // 平移 (5, 5)
    // 组合变换
    const combinedMatrix = new THREE.Matrix3();
    combinedMatrix.multiply(translationMatrix).multiply(rotationMatrix);
  • multiplyMatrices ( a : Matrix3, b : Matrix3 ) : this 设置当前矩阵为矩阵a x 矩阵b。
    // 创建两个 Matrix3 对象
    const matrixA = new THREE.Matrix3();
    const matrixB = new THREE.Matrix3();
    // 定义 matrixA
    matrixA.set(
        1, 2, 3,
        4, 5, 6,
        7, 8, 9
    );
    // 定义 matrixB
    matrixB.set(
        9, 8, 7,
        6, 5, 4,
        3, 2, 1
    );
    // 创建一个新的 Matrix3 对象,用于存储结果
    const resultMatrix = new THREE.Matrix3();
    // 使用 multiplyMatrices 方法进行矩阵相乘
    resultMatrix.multiplyMatrices(matrixA, matrixB);
    // 输出乘积矩阵
    console.log("乘积矩阵:", resultMatrix.elements); // 乘积矩阵: [30, 84, 138, 24, 69, 114, 18, 54, 90]
  • multiplyScalar ( s : Float ) : this 当前矩阵所有的元素乘以该缩放值s
    // 创建一个 3x3 矩阵
    const matrix = new THREE.Matrix3();
    matrix.set(
        1, 0, 0, // 第一行
        0, 1, 0, // 第二行
        0, 0, 1  // 第三行
    );
    // 使用 multiplyScalar 方法将矩阵乘以 2
    matrix.multiplyScalar(2);
    // 输出缩放后的矩阵
    console.log('缩放后的矩阵:', matrix); // [2,0,0,0,2,0,0,0,2]
  • set ( n11 : Float, n12 : Float, n13 : Float, n21 : Float, n22 : Float, n23 : Float, n31 : Float, n32 : Float, n33 : Float ) : this 使用行优先 row-major 的格式来设置该矩阵:
  • premultiply ( m : Matrix3 ) : this 将矩阵m乘以当前矩阵。 1728878333441.png
    // 创建两个 3x3 矩阵
    const matrixA = new THREE.Matrix3();
    const matrixB = new THREE.Matrix3();
    // 设置矩阵 A 的值
    matrixA.set(
        1, 2, 3, // 第一行
        4, 5, 6, // 第二行
        7, 8, 9  // 第三行
    );
    // 设置矩阵 B 的值
    matrixB.set(
        9, 8, 7, // 第一行
        6, 5, 4, // 第二行
        3, 2, 1  // 第三行
    );
    console.log('矩阵 B:', matrixB);
    // 使用 premultiply 方法进行预乘
    matrixA.premultiply(matrixB);
    // 输出预乘后的矩阵 A
    console.log('预乘后的矩阵 A:', matrixA);// [90,54,18,114,69,24,138,84,30]
  • setFromMatrix4 ( m : Matrix4 ) : this setFromMatrix4(m: Matrix4): thisMatrix3 类中的一个方法,用于从一个 4x4 矩阵(Matrix4)中提取出 3x3 矩阵的部分。这个方法会将 Matrix4 中的前 3 行和前 3 列的值设置到当前的 Matrix3 实例中,并返回更新后的矩阵实例(this),允许链式调用。
    // 创建一个 4x4 矩阵
    const matrix4 = new THREE.Matrix4();
    // 设置 4x4 矩阵的值
    matrix4.set(
        1, 0, 0, 0,  // 第一行
        0, 1, 0, 0,  // 第二行
        0, 0, 1, 0,  // 第三行
        0, 0, 0, 1   // 第四行
    );
    // 创建一个 3x3 矩阵
    const matrix3 = new THREE.Matrix3();
    // 使用 setFromMatrix4 方法从 4x4 矩阵中提取值
    matrix3.setFromMatrix4(matrix4);
    // 输出提取后的 3x3 矩阵
    console.log('提取后的 3x3 矩阵:', matrix3); // [1,0,0,0,1,0,0,0,1]
  • setUvTransform ( tx : Float, ty : Float, sx : Float, sy : Float, rotation : Float, cx : Float, cy : Float ) : this setUvTransform(tx: Float, ty: Float, sx: Float, sy: Float, rotation: Float, cx: Float, cy: Float): thisMatrix3 类中的一个方法,用于设置 UV 坐标的变换矩阵。这个方法结合了平移、缩放和旋转操作,通常用于处理纹理坐标。
    // 创建一个 3x3 矩阵
    const matrix3 = new THREE.Matrix3();
    // 设置 UV 变换
    const tx = 0.5;         // X 轴平移
    const ty = 0.5;         // Y 轴平移
    const sx = 2;           // X 轴缩放因子
    const sy = 1.5;         // Y 轴缩放因子
    const rotation = Math.PI / 4; // 45 度旋转(弧度)
    const cx = 0.5;         // 旋转中心 X
    const cy = 0.5;         // 旋转中心 Y
    // 使用 setUvTransform 方法设置 UV 变换
    matrix3.setUvTransform(tx, ty, sx, sy, rotation, cx, cy);
    // 输出结果
    console.log('设置后的 UV 变换矩阵:', matrix3);// [1.4142135623730951,-1.0606601717798212,0,1.414213562373095,1.0606601717798214,0,-0.4142135623730949,0.9999999999999999,1]
  • toArray ( array : Array, offset : Integer ) : Array array - (可选参数) 存储矩阵元素的数组,如果未指定会创建一个新的数组。 offset - (可选参数) 存放矩阵元素数组的偏移量。 使用列优先column-major格式将此矩阵的元素写入数组中。将该矩阵转置Transposes。
  • transpose () : this 将该矩阵转置Transposes。transpose(): thisMatrix3 类中的一个方法,用于对矩阵进行转置操作。转置矩阵是将矩阵的行和列互换。此方法会直接修改当前的 Matrix3 实例并返回它,允许链式调用。
  • transposeIntoArray ( array : Array ) : this array - 用于存储当前矩阵转置结果的数组。 将当前矩阵的转置Transposes存入给定的数组 array 中,但不改变当前矩阵, 并返回当前矩阵。