Запутался в порядке работы при использовании матрицы в XNA, C#


Вот два разных фрагмента кода

Вот с чего я начал

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);

Чего я не понимаю, так это почему не первая строка в simpilifed версии

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 5

1 ответ:

Так как в матричном порядке вещь справа вступит в силу первой. и в оригинале мы имеем mat1, умноженное на first

На самом деле," вещь слева от " вступает в силу первой. Матрицы применяются к вершине в том же порядке, в котором вы их читаете (если вы привыкли к латинскому языку).

В XNA обычно выполняются преобразования в порядке SRT (масштабирование, поворот, перевод). Таким образом, объект будет масштабироваться и поворачиваться о своем собственном происхождении (вращаясь вокруг собственной оси) перед перемещением в мировое пространство.

Например: если бы я хотел повернуть объект на Pi / 2, переместить его на 100 единиц вдоль оси X, я мог бы использовать:

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;

Вы также можете вращать объект вокруг своей оси, перемещать это 100 единиц вдоль оси X мира, орбита его о происхождении мира по:

var worldMatrix = rotateSpin * translate * rotateOrbit;

Где rotateSpin и rotateOrbit - матрицы вращения, определяющие ваш спин (вращение вокруг начала координат объекта) и орбиту (вращение вокруг начала координат мира после перевода) соответственно. Обратите внимание, что порядок, в котором операции влияют на вершины сервиса, находится слева направо.