在XNA、C#中使用矩阵时,对操作顺序感到困惑
本文关键字:操作 顺序 XNA | 更新日期: 2023-09-27 18:21:41
这里有两段不同的代码
这就是我从开始的
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;
如果顺序是从左到右,为什么这样做?
因为按照矩阵顺序,右边的东西首先生效在原始文件中,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;
其中,rotateSpin
和rotateOrbit
是分别定义旋转(绕对象原点的旋转)和轨道(平移后绕世界原点的转动)的旋转矩阵。请注意,操作影响服务顶点的顺序是从左到右。