在XNA中使用Matrix时,对于操作顺序感到困惑,C#

Alx*_*der 5 c# xna vector matrix

这是两段不同的代码

这就是我的开始

Vector2 hold = Vector2.Transform(pos1, mat1);
Matrix inv = Matrix.Invert(mat2);
Vector2 pos2 = Vector2.Transform(hold, inv);
Run Code Online (Sandbox Code Playgroud)

这就是我所说的简化版

Matrix matrix1to2 = mat1 * Matrix.Invert(mat2);
Vector2 pos2 = Vector2.Transform(pos1, matrix1to2);
Run Code Online (Sandbox Code Playgroud)

我不明白的是,为什么不是简化版的第一行

Matrix matrix1to2 = Matrix.Invert(mat2)*mat1;
Run Code Online (Sandbox Code Playgroud)

因为在矩阵顺序中,右边的东西将首先生效,而在原始中我们首先将mat1相乘

编辑: 下图显示了所需的操作顺序

http://www.riemers.net/images/Tutorials/XNA/Csharp/Series2D/mat1.png

教程说你要创建这个转换;

Matrix carriageMat = Matrix.CreateTranslation(0, -carriage.Height, 0) * Matrix.CreateScale(playerScaling) 
* Matrix.CreateTranslation(xPos, yPos, 0) * Matrix.Identity;
Run Code Online (Sandbox Code Playgroud)

如果订单是从左到右,为什么这会起作用?

3Da*_*ave 3

因为按照矩阵顺序,右边的东西会先生效,而在原始版本中,我们首先将 mat1 相乘

实际上,“左边的东西”先起作用。矩阵按照您阅读它们的顺序应用于顶点(假设您习惯拉丁语言)。

在 XNA 中,您通常按 SRT(缩放、旋转、平移)顺序执行转换。这样,对象在移动到世界空间之前将围绕其自身原点进行缩放和旋转(在自己的轴上旋转)。

例如:如果我想将一个对象旋转 Pi / 2,将其沿 X 轴移动 100 个单位,我可能会使用:

var rotate = Matrix.CreateRotationY(MathHelper.PiOver2);
var translate = Matrix.CreateTranslation(new Vector3(100,0,0));

var worldMatrix = rotate * translate;
Run Code Online (Sandbox Code Playgroud)

相反,如果我想将对象向右移动 100 个单位,然后围绕世界原点 (0,0,0) 旋转它以获得某种轨道效果(而不是像第一个示例中那样旋转),我会用

var worldMatrix = translate * rotate;
Run Code Online (Sandbox Code Playgroud)

您还可以在其轴上旋转对象,沿世界 X 轴移动 100 个单位,并通过以下方式绕世界原点运行:

var worldMatrix = rotateSpin * translate * rotateOrbit;
Run Code Online (Sandbox Code Playgroud)

其中rotateSpinrotateOrbit是分别定义自旋(绕物体原点旋转)和轨道(平移后绕世界原点旋转)的旋转矩阵。请注意,操作影响服务顶点的顺序是从左到右。