今天郭先生来说一说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更灵活强大。

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

three.js 数学方法之Matrix3的更多相关文章

  1. three.js 数学方法之Plane

    今天郭先生就来继续说一说three.js数学方法中的plane(平面).在三维空间中无限延伸的二维平面,平面方程用单位长度的法向量和常数表示.构造器为Plane( normal : Vector3, ...

  2. three.js 数学方法之Box3

    从今天开始郭先生就会说一下three.js 的一些数学方法了,像Box3.Plane.Vector3.Matrix3.Matrix4当然还有欧拉角和四元数.今天说一说three.js的Box3方法(B ...

  3. three.js 数学方法之Vector3

    今天郭先生来说一说three.js的Vector3,该类表示的是一个三维向量(3D vector). 一个三维向量表示的是一个有顺序的.三个为一组的数字组合(标记为x.y和z),可被用来表示很多事物, ...

  4. three.js 数学方法之Matrix4

    今天郭先生说一说three.js中的Matrix4,相较于Matrix3来说,Matrix4和three.js联系的更紧密,因为在4x4矩阵最常用的用法是作为一个变换矩阵.这使得表示三维空间中的一个点 ...

  5. js数学方法应用

    找出数组中最大的数 var values = [1, 2, 3, 4, 5, 6, 7, 8]; alert(Math.min.apply(Math,values))//8 这个技巧的关键是把 Mat ...

  6. js数组及常用数学方法

    数组方法 清空数组   1: arr.length=0;   2: arr=[]; arr.push()          //往数组最后一个添加元素,会待会一个返回值,就是新的数组长度arr.uns ...

  7. js数组方法大全(下)

    # js数组方法大全(下) 记录一下整理的js数组方法,免得每次要找方法都找不到.图片有点多,注意流量,嘻嘻! 本期分享 forEach() map() filer() every() some() ...

  8. js数组方法

    数组方法清空数组1: arr.length=02: arr=[]arr.push()//往数组最后一个添加元素,会待会一个返回值,就是新的数组长度arr.unshift()//往数组的第一个添加元素, ...

  9. js调用php和php调用js的方法举例

    js调用php和php调用js的方法举例1 JS方式调用PHP文件并取得php中的值 举一个简单的例子来说明: 如在页面a.html中用下面这句调用: <script type="te ...

随机推荐

  1. Day12-微信小程序实战-交友小程序-优化“附近的人”页面与serach组件的布局和样式以及搜索历史记录和本地缓存*内附代码)

    回顾/:我们已经实现了显示附近的人的功能了,可以多个人看到附近的人页面了 但是还是要进行优化有几个问题:1.我们用户选择了其他的自定义头像之后,在首页可以看到头像的变化,但是在附近的人中头像会变成报错 ...

  2. Ajax实现文件上传(Spring MVC)

    ## 前端表单 和 JQuery jsp/html代码 使用JQuery <script src="static/js/jquery-3.4.1.js"></sc ...

  3. Java常用的文档地址

    https://docs.oracle.com/en/ https://docs.oracle.com/en/java/javase/13/   specifications--->langua ...

  4. 前端进阶笔记之核心基础知识---那些HTML标签你熟悉吗?

    目录 1.交互实现 1.1 meta标签:自动刷新/跳转 1.2 title标签:消息提醒 2.性能优化 2.1 script标签:调整加载顺序提升渲染速度 2.2 link标签:通过预处理提升渲染速 ...

  5. vue全家桶(4.3)

    5.3.Vuex的核心概念 store: 每一个 Vuex 应用的核心就是 store(仓库)."store"基本上就是一个容器,它包含着你的应用中大部分的状态 (state) s ...

  6. C# 做的Windows 应用程序 服务

    运行服务: ,cmd下进入目录 cd C:\Windows\Microsoft.NET\Framework\v4.0.30319\ ,安装服务 installutil F:\中原集团\天津CCHR\t ...

  7. JavaScript基础对象创建模式之单体/单例模式(Singleton)

    首先,单例模式是对象的创建模式之一,此外还包括工厂模式.单例模式的三个特点: 1,该类只有一个实例 2,该类自行创建该实例(在该类内部创建自身的实例对象) 3,向整个系统公开这个实例接口 Java中大 ...

  8. 放弃for循环吧

    前言 for(var i=0;i<array.length;i++){}这个可以是初学者必学的知识,也是JS中必不可少的功能,但如果对性能要求较高的小伙伴有了解过就会发现,for循环性能不高且代 ...

  9. 又一款开源图标库 CSS.GG,值得一用

    嗨,我是 Martin,也叫老王,今天推荐一款好用的开源图标库. 我们平常找图标往往会去 iconfont 但是今天,我们看了 Martin 的文章之后,就会有一个新的选择--CSS.GG Githu ...

  10. The Meaningless Game,算是思维吧。

    题目直接链接 题意: 某游戏规则:每次选定数字k(正整数),两人初始分数为1,获胜者分数乘k2,失败者分数成k,给你两个数字,判断是否可能是本游戏的两人的得分. 分析: 为啥题意我不写判断两个数可不可 ...