egret-docs-master/Engine3D/MathUtils/Matrix4_4/README.md

433 lines
12 KiB
Markdown
Raw Permalink Normal View History

2024-06-19 13:32:32 +08:00
3D基本变换
===============
## 3D矩阵Matrix4_4 ##
* Matrix4_4 类表示一个转换矩阵,该矩阵描述了三维 (3D) 显示对象的缩放/旋转/位移
* 该矩阵可以追加转换功能,包括缩放/旋转/位移
* Matrix4_4 类可用于视锥投影,这会将 3D 坐标空间中的点映射到二维 (2D) 视图,常用有透视投影和正交投影
* 单一矩阵可以将多个转换组合在一起,并一次性对 3D 显示对象应用这些转换
* 例如,可以将一个矩阵应用于 3D 坐标,以便依次执行旋转和平移
---------
* lookAt:从3D坐标点A观察坐标点B设定观察视角的正上方获得满足这个条件的矩阵
* 可以用于控制相机或者显示对象的方向,使面向目标
* egret3d.Camera3D和egret3d.Object3D已经封装过该函数你只需要调用camera3D.lookAt()或者object3D.lookAt()
----------
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var eyePosition: egret3d.Vector3D = new egret3d.Vector3D(0, 0, 0);
var atPosition: egret3d.Vector3D = new egret3d.Vector3D(100, 20, 40);
matrix.lookAt(eyePosition, atPosition, egret3d.Vector3D.Y_AXIS);
//matrix
//[0] 0.3713906705379486 Number
//[1] -0.16951587796211243 Number
//[2] 0.9128709435462952 Number
//[3] 0 Number
//[4] 0 Number
//[5] 0.9831920862197876 Number
//[6] 0.18257418274879455 Number
//[7] 0 Number
//[8] -0.9284766912460327 Number
//[9] -0.06780634820461273 Number
//[10] 0.3651483654975891 Number
//[11] 0 Number
//[12] 0 Number
//[13] 0 Number
//[14] 0 Number
//[15] 1 Number
----------
* multiply:矩阵相乘
* 矩阵A和矩阵B相乘的得到矩阵C
* 一个3D对象先使用矩阵A进行转换然后用矩阵B进行转换其结果与直接用C矩阵转换是等价的操作
* 注意前乘和后乘的区别,矩阵相乘不满足交换律
----------
var matrix1: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var matrix2: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
matrix1.multiply(matrix2);
----------
* perspective:生成一个透视投影矩阵
* 通过设定视锥体的空间数据,包括远近裁剪面距离/观察范围夹角/屏幕横纵比,获得矩阵
* egret3d.Camera3D封装有该矩阵的方法调用通过设定CameraType即可自动构造透视投影矩阵
* 3D场景渲染中会使用到该功能
----------
var projectMatrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var fovY:number = 60;
var aspectRatio:number = 3/4;
var near:number = 1;
var far:number = 10000;
//构造透视投影矩阵
projectMatrix.perspective(fovY, aspectRatio, near, far);
----------
* ortho:生成一个正交投影矩阵
* 通过设定视锥体的空间数据,包括远近裁剪面距离/屏幕宽度和高度
* egret3d.Camera3D封装有该矩阵的方法调用通过设定CameraType即可自动构造正交投影矩阵
* GUI和HUD的渲染会使用到该功能
----------
var projectMatrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var width:number = 1024;
var height:number = 768;
var near:number = 1;
var far:number = 10000;
//构造正交投影矩阵
projectMatrix.ortho(fovY, aspectRatio, near, far);
----------
* fromToRotation:获得一个矩阵使他能够将A向量变换成B向量
----------
var matrix:egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var direction1:egret3d.Vector3D = new egret3d.Vector3D(-1,0,2,1);
var direction2:egret3d.Vector3D = new egret3d.Vector3D(10,5,1,1);
direction1.normalize();
direction2.normalize();
//求出模型矩阵
matrix.fromToRotation(direction1, direction2);
---------
* append:矩阵前乘
* 与multiply相同
----------
var matrix1: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var matrix2: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
matrix1.append(matrix2);
----------
* appendRotation:获得一个矩阵,该矩阵描述着绕设定的旋转轴旋转一定的角度
----------
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var axis: egret3d.Vector3D = new egret3d.Vector3D(1, -1, 10, 1);
axis.normalize();
//围绕axis指定的方向旋转45度角
matrix.appendRotation(45, axis);
----------
* appendScale:追加三轴缩放值
* 将当前的矩阵追加xyz三个方向缩放值
----------
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var scaleX:number = 0.5;
var scaleY:number = 1.5;
var scaleZ:number = 2.5;
//X Y Z 方向分别缩放 0.5 1.5 2.5
matrix.appendScale(scaleX, scaleY, scaleZ);
//matrix
//[0] 0.5 Number
//[1] 0 Number
//[2] 0 Number
//[3] 0 Number
//[4] 0 Number
//[5] 1.5 Number
//[6] 0 Number
//[7] 0 Number
//[8] 0 Number
//[9] 0 Number
//[10] 2.5 Number
//[11] 0 Number
//[12] 0 Number
//[13] 0 Number
//[14] 0 Number
//[15] 1 Number
----------
* appendTranslation:追加平移数据
* 将当前的矩阵追加xyz三个方向平移数据
----------
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var offsetX:number = 0.5;
var offsetY:number = 1.5;
var offsetZ:number = 2.5;
//X Y Z 方向分别平移 0.5 1.5 2.5
matrix.appendTranslation(offsetX, offsetY, offsetZ);
//matrix
//[0] 1 Number
//[1] 0 Number
//[2] 0 Number
//[3] 0 Number
//[4] 0 Number
//[5] 1 Number
//[6] 0 Number
//[7] 0 Number
//[8] 0 Number
//[9] 0 Number
//[10] 1 Number
//[11] 0 Number
//[12] 0.5 Number
//[13] 1.5 Number
//[14] 2.5 Number
//[15] 1 Number
----------
* decompose:分解一个矩阵,获得缩放/平移/旋转数据
* 分解得出的结果为egret3D.Vector3D的数组中长度为3.其中第一个记录平移数据,第二个记录旋转数据,第三个记录缩放数据
* 需要指定旋转数据格式请参照egret3d.Orientation3D中枚举出的3个值
----------
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var offsetX:number = 0.2;
var offsetY:number = 0.4;
var offsetZ:number = 0.6;
//X Y Z 方向分别平移 0.2 0.4 0.6
matrix.appendTranslation(offsetX, offsetY, offsetZ);
var scaleX:number = 0.5;
var scaleY:number = 1.5;
var scaleZ:number = 2.5;
//X Y Z 方向分别缩放 0.5 1.5 2.5
matrix.appendScale(scaleX, scaleY, scaleZ);
var axis: egret3d.Vector3D = new egret3d.Vector3D(1, -1, 10, 1);
axis.normalize();
//围绕axis指定的方向旋转45度角
matrix.appendRotation(45, axis);
//拆分矩阵
var result:egret3d.Vector3D[] = matrix.decompose(egret3d.Orientation3D.QUATERNION);
var pos:egret3d.Vector3D = result[0];
var rot:egret3d.Vector3D = result[1];
var scale:egret3d.Vector3D = result[2];
//<-0.41275760531425476, 0.34762030839920044, 1.5260378122329712>
//<0.03789130620377082, -0.037891307211827124, 0.37891307413438385, 0.9238795211721623>
//<0.5000000018751693, 1.5000000284558414, 2.49999994435313>
----------
* deltaTransformVector:按照该矩阵所包含的旋转信息,变换另外一个向量
* 向量没有平移信息
----------
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var offsetX:number = 0.2;
var offsetY:number = 0.4;
var offsetZ:number = 0.6;
//X Y Z 方向分别平移 0.2 0.4 0.6
matrix.appendTranslation(offsetX, offsetY, offsetZ);
var scaleX:number = 0.5;
var scaleY:number = 1.5;
var scaleZ:number = 2.5;
//X Y Z 方向分别缩放 0.5 1.5 2.5
matrix.appendScale(scaleX, scaleY, scaleZ);
var axis: egret3d.Vector3D = new egret3d.Vector3D(1, -1, 10, 1);
axis.normalize();
//围绕axis指定的方向旋转45度角
matrix.appendRotation(45, axis);
//给定原向量
var direction:egret3d.Vector3D = new egret3d.Vector3D(10, 10, -5, 1);
direction.normalize();
matrix.deltaTransformVector(direction, direction);
//w 0 Number
//x -0.43193634599447245 Number
//y 1.024675299723943 Number
//z -0.75433882077535 Number
----------
* transformVector:使用当前矩阵变换另外一个位置点
* 初始位置被变换之后,得到的结果为按照当前矩阵所给定的数据获得的新位置
* 坐标数据不包含缩放/旋转信息
----------
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var offsetX:number = 0.2;
var offsetY:number = 0.4;
var offsetZ:number = 0.6;
//X Y Z 方向分别平移 0.2 0.4 0.6
matrix.appendTranslation(offsetX, offsetY, offsetZ);
var scaleX:number = 0.5;
var scaleY:number = 1.5;
var scaleZ:number = 2.5;
//X Y Z 方向分别缩放 0.5 1.5 2.5
matrix.appendScale(scaleX, scaleY, scaleZ);
var axis: egret3d.Vector3D = new egret3d.Vector3D(1, -1, 10, 1);
axis.normalize();
//围绕axis指定的方向旋转45度角
matrix.appendRotation(45, axis);
//给定原向量
var direction:egret3d.Vector3D = new egret3d.Vector3D(10, 10, -5, 1);
direction.normalize();
matrix.transformVector(direction, direction);
//w 1 Number
//x -0.8446939513087273 Number
//y 1.3722956081231434 Number
//z 0.7716989914576212 Number
----------
* invert:获取当前矩阵的逆矩阵
* 理想状态下,矩阵和逆矩阵的乘积为单位矩阵
* 不是所有的矩阵都有逆矩阵
----------
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var offsetX:number = 0.2;
var offsetY:number = 0.4;
var offsetZ:number = 0.6;
//X Y Z 方向分别平移 0.2 0.4 0.6
matrix.appendTranslation(offsetX, offsetY, offsetZ);
var scaleX:number = 0.5;
var scaleY:number = 1.5;
var scaleZ:number = 2.5;
//X Y Z 方向分别缩放 0.5 1.5 2.5
matrix.appendScale(scaleX, scaleY, scaleZ);
var axis: egret3d.Vector3D = new egret3d.Vector3D(1, -1, 10, 1);
axis.normalize();
//围绕axis指定的方向旋转45度角
matrix.appendRotation(45, axis);
//给定原向量
var direction:egret3d.Vector3D = new egret3d.Vector3D(10, 10, -5, 1);
direction.normalize();
var enable:boolean = matrix.invert();
//enable : true
//[0] 1.4199564456939697 Number
//[1] -0.46867436170578003 Number
//[2] -0.016519593074917793 Number
//[3] 0 Number
//[4] 1.394537091255188 Number
//[5] 0.47331884503364563 Number
//[6] -0.03949161246418953 Number
//[7] 0 Number
//[8] 0.19745805859565735 Number
//[9] 0.027532655745744705 Number
//[10] 0.39770281314849853 Number
//[11] 0 Number
//[12] -0.20000006258487701 Number
//[13] -0.4000000059604645 Number
//[14] -0.6000000238418579 Number
//[15] 1 Number
----------
* makeTransform:输入缩放/旋转/位移信息,生成一个矩阵
* 旋转数据为四元数格式
----------
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var pos:egret3d.Vector3D = new egret3d.Vector3D(0.2, 0.4, 0.6, 1);
var scale:egret3d.Vector3D = new egret3d.Vector3D(0.5, 1.5, 2.5, 1);
var rot:egret3d.Quaternion = new egret3d.Quaternion(-1, 2, 10, 1);
rot.normalize();
//组装
matrix.makeTransform(pos, scale, rot);
//[0] -0.4811320900917053 Number56939697 Number
//[1] 0.07547169923782348 Number6170578003 Number
//[2] -0.11320754885673523 Number93074917793 Number
//[3] 0 Number
//[4] -0.3396226465702057 Number1255188 Number
//[5] -1.3584905862808227 Number503364563 Number
//[6] 0.5377358198165893 Number1246418953 Number
//[7] 0 Number
//[8] -0.37735849618911743 Number859565735 Number
//[9] 0.9905660152435303 Number5745744705 Number
//[10] 2.264151096343994 Number314849853 Number
//[11] 0 Number
//[12] 0.20000000298023224 Number6258487701 Number
//[13] 0.4000000059604645 Number059604645 Number
//[14] 0.6000000238418579 Number238418579 Number
//[15] 1 Number
----------
* recompose:输入缩放/旋转/位移信息,重组矩阵
* 旋转数据为欧拉角格式
* 该函数先将欧拉角转化成四元数然后调用makeTransform方法实现
----------
var matrix: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var pos:egret3d.Vector3D = new egret3d.Vector3D(0.2, 0.4, 0.6, 1);
var scale:egret3d.Vector3D = new egret3d.Vector3D(0.5, 1.5, 2.5, 1);
var rot:egret3d.Vector3D = new egret3d.Vector3D(-1, 2, 10, 1);
rot.normalize();
//组装
matrix.recompose([pos, rot, scale]);
----------
* transpose:转置一个矩阵,使矩阵按照右上和左下角互换规则交换所有数据
----------
![](transpose.jpg)
----------
* lerp:矩阵插值操作
* 从矩阵A到矩阵B通过输入0-1之间的一个时间作为插值系数进行平滑插值
----------
var matrixA: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var matrixB: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var result: egret3d.Matrix4_4 = new egret3d.Matrix4_4();
var t:number = 0.2;
result.lerp(matrixA, matrixB, t);
----------