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

时间:2012-01-29 19:03:39

标签: c# vector matrix xna

以下是两段不同的代码

这是我开始的

Vector2 hold = Vector2.Transform(pos1, mat1);
Matrix inv = Matrix.Invert(mat2);
Vector2 pos2 = Vector2.Transform(hold, inv);

这就是我所说的简化版

Matrix matrix1to2 = mat1 * Matrix.Invert(mat2);
Vector2 pos2 = Vector2.Transform(pos1, matrix1to2);

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

Matrix matrix1to2 = Matrix.Invert(mat2)*mat1;

因为在矩阵顺序中,右边的东西会先生效,而在原始中我们将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;

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

1 个答案:

答案 0 :(得分: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;

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

var worldMatrix = translate * rotate;

你也可以在它的轴上旋转物体,沿世界X轴移动它100个单位,它绕世界原点轨道运行:

var worldMatrix = rotateSpin * translate * rotateOrbit;

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