Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在XNA,C中使用矩阵时对操作顺序感到困惑#_C#_Vector_Matrix_Xna - Fatal编程技术网

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

C# 在XNA,C中使用矩阵时对操作顺序感到困惑#,c#,vector,matrix,xna,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, matrix1

下面是两段不同的代码

这是我开始的

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;
我不明白的是,为什么第一行不是简单的版本

Matrix matrix1to2 = mat1 * Matrix.Invert(mat2);
Vector2 pos2 = Vector2.Transform(pos1, matrix1to2);
Matrix matrix1to2 = Matrix.Invert(mat2)*mat1;
因为在矩阵的顺序中,右边的东西会首先生效,而在原始的矩阵中,我们先乘以mat1

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

教程中说,要创建此转换,请使用

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)旋转它以获得某种轨道效果(而不是像第一个示例中那样旋转),我会使用

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

var worldMatrix = rotateSpin * translate * rotateOrbit;

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

我认为这是一个问题。你会有更多的反馈。谢谢。我会试试的。那么我应该关上这个吗?如果你想的话。大卫,我所看到的每一次关于矩阵顺序的讨论,都谈到了首先应用右边的运算。例如,“首先缩放对象,然后旋转它,然后平移它:L=T*R*S”。请解释什么是不同的,例如,您所说的是从左到右。例如,查看问题中引用的Riemer图,并将其与问题中显示的公式进行比较,讨论的第一个变换是图像(1)和(2)之间的变换;这是XY位置的变化。在公式中(忽略末尾对象的单位变换矩阵),这是最后一个矩阵
matrix.CreateTranslation(xPos,yPos,0)
。车厢高度变换(仅在y中)是最终更改,图像(3)变为(4),由第一个矩阵
矩阵完成。CreateTranslation(0,-carries.height,0)
。。。因此,IMHO,一个更好的解释是两种方法--(应用一个mult,然后应用第二个mult)与(将两个矩阵相乘,然后应用组合)“以相同的方式工作”:它们都可以被认为是“执行第二个操作,然后执行第一个操作”。因此,您可以按照希望它们生效的相反顺序应用它们。当“简化”一个有效的多步骤公式时,正如你正确地说的,你不会改变它们的顺序。但在考虑最终结果时,请从右到左考虑。@ToolmakerSteve这取决于代码和API中使用的约定。例如,GLSL中的矩阵的应用顺序与HLSL中的相反,因为矩阵是转置的(行主对列主)。在所有XNA文档中——这就是六年前的问题——矩阵都是按照我在答案中指定的顺序应用的。矩阵是结合的,但不是交换的。(我想——我已经有一段时间没上八年级几何课了。)