以下是两段不同的代码
这是我开始的
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;
如果订单是从左到右,为什么会这样?
答案 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;
其中rotateSpin
和rotateOrbit
分别是定义旋转(围绕对象原点的旋转)和轨道(围绕平移的世界原点的旋转)的旋转矩阵。请注意,操作影响服务顶点的顺序是从左到右。