• three.js 数学方法之Matrix3


    今天郭先生来说一说three.js的三维矩阵,这块知识需要结合线性代数的一些知识,毕业时间有点长,线性代数的知识大部分都还给了老师。于是一起简单的复习了一下。
    所有的计算都是使用列优先顺序进行的。然而,由于实际的排序在数学上没有什么不同, 而且大多数人习惯于以行优先顺序考虑矩阵,所以three.js文档以行为主的顺序显示矩阵。 请记住,如果您正在阅读源代码,您必须对这里列出的任何矩阵进行转置transpose,以理解计算。例如:

    var matrix3 = new THREE.Matrix3().set( 1,2,3,4,5,6,7,8,9); //而其内部elements则展示为: matrix3.elements = [1,4,7,2,5,8,3,6,9];

    1. Matrix3的属性

    1. elements : Array

    矩阵列优先column-major列表。

    2. isMatrix3 : Boolean

    用于判定此对象或者此类的派生对象是否是三维矩阵。默认值为 true。

    2. Matrix3的方法

    1. set(n11: number,n12: number,n13: number…): Matrix3

    三维矩阵不能在构造函数中直接设置参数值,需要通过set()方法设置,set()方法参数采用行优先row-major, 而它们在内部是用列优先column-major顺序存储在数组当中。代码如上面所示。

    2. identity(): Matrix3

    将此矩阵重置为3x3单位矩阵。

    var matrix = new THREE.Matrix3(); 
    matrix.identity();//返回elements: (9) [1, 0, 0, 0, 1, 0, 0, 0, 1]

    3. clone(): this

    创建一个新的矩阵,元素 elements 与该矩阵相同。不多说。

    4. copy( m: Matrix3 ): this

    将矩阵m的元素复制到当前矩阵中。不多说。

    5. extractBasis( xAxis: Vector3, yAxis: Vector3, zAxis: Vector3 ): Matrix3

    将此矩阵的基提取到提供的三个轴向量中。

    var matrix = new THREE.Matrix3(); 
    matrix.set( 1,2,3,4,5,6,7,8,9); 
    var a = new THREE.Vector3(); 
    var b = new THREE.Vector3(); 
    var c = new THREE.Vector3(); 
    matrix.extractBasis(a, b, c); 
    console.log(a,b,c);//返回Vector3 {x: 1, y: 4, z: 7} Vector3 {x: 2, y: 5, z: 8} Vector3 {x: 3, y: 6, z: 9}

    6. setFromMatrix4( m: Matrix4 ): Matrix3

    将当前矩阵设置为4X4矩阵m左上3X3,

    var matrix = new THREE.Matrix3(); 
    var matrix4 = new THREE.Matrix4().makeScale(2,2,2); 
    matrix.setFromMatrix4(matrix4)//elements: (9) [2, 0, 0, 0, 2, 0, 0, 0, 2]

    7. multiplyScalar( s: number ): Matrix3

    当前矩阵所有的元素乘以该缩放值s

    var matrix = new THREE.Matrix3(); 
    matrix.set( 1,2,3,4,5,6,7,8,9); 
    matrix.multiplyScalar(2)//elements: (9) [2, 8, 14, 4, 10, 16, 6, 12, 18]

    8. determinant(): number

    计算并返回矩阵的行列式determinant 。

    var matrix = new THREE.Matrix3(); 
    matrix.set( 1,2,3,4,5,6,7,8,9); 
    matrix.determinant()//返回0

    计算方法a11 * a22 * a33 + a12 * a23 * a31 + a13 * a21 * a32 - a13 * a22 * a31 - a12 * a21 * a33 - a11 * a23 * a32 = 0;

    9. getInverse( matrix: Matrix3, throwOnDegenerate?: boolean ): Matrix3

    求传入矩阵m的逆矩阵,使用解析法将该矩阵设置为传递矩阵m的逆矩阵。行列式为零的矩阵不能求逆。如果您尝试这样做,该方法将返回一个零矩阵。

    var matrix1 = new THREE.Matrix3(); 
    var matrix2 = new THREE.Matrix3(); 
    matrix1.set(1,2,3,4,5,6,7,8,9); matrix2.set(1,1,0,0,1,1,0,0,1); 
    new THREE.Matrix3().getInverse(matrix1)//因为行列式的值为0,所以返回零矩阵elements: (9) [0, 0, 0, 0, 0, 0, 0, 0, 0] 
    new THREE.Matrix3().getInverse(matrix2)//因为行列式的值不为0,所以返回elements: (9) [1, 0, 0, -1, 1, 0, 1, -1, 1]

    求逆矩阵的方法有很多,可以通过伴随矩阵求逆矩阵,也可以行做差来构造逆矩阵。

    10. transpose(): Matrix3

    将该矩阵转置。

    var matrix = new THREE.Matrix3(); 
    matrix.set(1,1,0,0,1,1,0,0,1);//返回elements: (9) [1, 0, 0, 1, 1, 0, 0, 1, 1]; matrix.transpose(); 
    console.log(matrix);//返回elements: (9) [1, 1, 0, 0, 1, 1, 0, 0, 1];

    11. getNormalMatrix( matrix4: Matrix4 ): Matrix3

    将这个矩阵设置为给定矩阵的正规矩阵normal matrix(左上角的3x3)。 正规矩阵是矩阵m的逆矩阵inverse 的转置transpose。

    this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();

    上面试three.js的源码,从源码可以看出这是setFromMatrix4,getInverse和transpose的组合用法。

    var matrix = new THREE.Matrix3(); 
    var matrix4 = new THREE.Matrix4().makeScale(2,2,2); 
    matrix.getNormalMatrix(matrix4);//返回elements: (9) [0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5]

    12. transposeIntoArray( r: number[] ): Matrix3

    将当前矩阵的转置Transposes存入给定的数组array : Array但不改变当前矩阵, 并返回当前矩阵。

    var matrix = new THREE.Matrix3(); 
    matrix.set(1,1,0,0,1,1,0,0,1); 
    var array = []; matrix.transposeIntoArray(array); 
    console.log(array);//返回[1, 1, 0, 0, 1, 1, 0, 0, 1]

    13. setUvTransform( tx: number, ty: number, sx: number, sy: number, rotation: number, cx: number, cy: number ): Matrix3

    tx - x偏移量
    ty - y偏移量
    sx - x方向的重复比例
    sy - y方向的重复比例
    rotation - 旋转(弧度)
    cx - 旋转中心x
    cy - 旋转中心y
    使用偏移,重复,旋转和中心点位置设置UV变换矩阵。

    var matrix = new THREE.Matrix3(); 
    matrix.setUvTransform(0,0,0,0,0,0.5,0.5); 
    console.log(matrix);//返回elements: (9) [0, -0, 0, 0, 0, 0, 0.5, 0.5, 1]

    14. equals( matrix: Matrix3 ): boolean

    如果矩阵m 与当前矩阵所有对应元素相同则返回true。

    15. fromArray( array: number[], offset?: number ): Matrix3

    使用基于列优先格式column-major的数组来设置该矩阵。

    var matrix = new THREE.Matrix3(); 
    matrix.fromArray([1,4,7,2,5,8,3,6,9]);//因为是基于列优先原则,所以设置的数组和elements属性相同,不需转置。

    16. toArray( array?: number[], offset?: number ): number[]

    使用列优先column-major格式将此矩阵的元素写入数组中。这是fromArray的逆运算。

    var matrix = new THREE.Matrix3(); 
    matrix.set(1,2,3,4,5,6,7,8,9); 
    matrix.toArray(array); 
    console.log(array);//返回[1, 4, 7, 2, 5, 8, 3, 6, 9]

    17. multiply( m: Matrix3 ): Matrix3

    将当前矩阵乘以矩阵m。

    var matrix1 = new THREE.Matrix3(); 
    var matrix2 = new THREE.Matrix3(); 
    matrix1.set(1,2,3,4,5,6,7,8,9); 
    matrix2.setFromMatrix4(new THREE.Matrix4().makeScale(0.5, 0.5, 0.5));//通过4维矩阵,得到三维矩阵 
    matrix1.multiply(matrix2);//返回elements: (9) [0.5, 2, 3.5, 1, 2.5, 4, 1.5, 3, 4.5]

    18. premultiply( m: Matrix3 ): Matrix3

    将矩阵m乘以当前矩阵。和上面相比这是左乘和右乘的问题,不多说。

    19. multiplyMatrices( a: Matrix3, b: Matrix3 ): Matrix3

    设置当前矩阵为矩阵a x 矩阵b。和上面的方法差不多,不多说。

    20. multiplyVector3( vector: Vector3 ): any

    和Vector3.applyMatrix3一样

    var matrix1 = new THREE.Matrix3(); 
    matrix1.set(1,2,3,4,5,6,7,8,9); 
    var vector3 = new THREE.Vector3(1,2,3); 
    matrix1.multiplyVector3(vector3);//返回Vector3 {x: 14, y: 32, z: 50}

    这就是Matrix3的一些属性和方法,Matrix3理解起来比Vector3确实更困难,同时功能更强大。它让three更灵活强大。

    转载请注明地址:郭先生的博客

  • 相关阅读:
    上机课前准备
    C# 跨线程访问控件的解决方法
    C# 异步和多线程的区别
    C# BeginInvoke和EndInvoke方法
    C# 委托的回调机制
    C# 什么是委托
    C# WebBrowser的控件使用
    C# 解决WebBrowser.DocumentCompleted事件的多次调用
    平台调用数据类型
    C# 创建快捷方式
  • 原文地址:https://www.cnblogs.com/vadim-web/p/13364651.html
Copyright © 2020-2023  润新知