2012-01-29 9 views
5

Oto dwa różne kawałki koduzna kolejność operacji przy użyciu matrycy w XNA, C#

To, co zaczęło się

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

I to jest to, co mi powiedziano jest uproszczona wersja

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

Co ja nie rozumiem, dlaczego nie jest to pierwsza linia w wersji simpilifed

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

Ponieważ w celu matrycy rzeczą na prawo to wchodzi w życie pierwszego i w oryginale mamy mat1 są mnożone w pierwszej

EDIT: Poniższy rysunek przedstawia kolejność operacji pożądane

http://www.riemers.net/images/Tutorials/XNA/Csharp/Series2D/mat1.png

Samouczek mówi, że do stworzenia tej transformacji używasz;

Matrix carriageMat = Matrix.CreateTranslation(0, -carriage.Height, 0) * Matrix.CreateScale(playerScaling) 
* Matrix.CreateTranslation(xPos, yPos, 0) * Matrix.Identity; 

Dlaczego to działa, jeśli zamówienie jest od lewej?

+0

Myślę, że jest to http://gamedev.stackexchange.com/ pytanie. Otrzymasz tam więcej opinii. – rcdmk

+0

Dzięki temu spróbuję. Czy powinienem to wtedy zamknąć? – Alxander

+0

Jeśli chcesz. Prawdopodobnie pojawią się niektórzy moderatorzy. – rcdmk

Odpowiedz

3

Ponieważ w celu matrycy rzeczą po prawej zajmie pierwsze i w oryginale mamy mat1 efekt jest zwielokrotniony w pierwszej

Faktycznie, „rzecz na lewo” wchodzi w życie pierwszy. Matryce są stosowane do wierzchołka w takiej samej kolejności, w jakiej je czytasz (zakładając, że jesteś przyzwyczajony do języka łacińskiego).

W XNA zazwyczaj wykonuje się transformacje w kolejności SRT (skalowanie, obracanie, tłumaczenie). W ten sposób obiekt zostanie przeskalowany i obrócony wokół własnego źródła (obracając się na własnej osi), zanim zostanie przeniesiony do przestrzeni świata.

Na przykład: jeśli chce obrócić obiekt Pi/2, przenieść go 100 jednostek wzdłuż osi X, można używać:

var rotate = Matrix.CreateRotationY(MathHelper.PiOver2); 
var translate = Matrix.CreateTranslation(new Vector3(100,0,0)); 

var worldMatrix = rotate * translate; 

Jeżeli zamiast tego chce przenieść obiekt 100 jednostek w prawo, następnie obrócić go o pochodzeniu świata (0,0,0), aby uzyskać coś w rodzaju efektu orbicie (zamiast przędzenia podobnie jak w pierwszym przykładzie), użyję

var worldMatrix = translate * rotate; 

Można również obrócić obiekt na jego osi, przesuń go o 100 jednostek wzdłuż światowej osi X, orbitując wokół świata o:

var worldMatrix = rotateSpin * translate * rotateOrbit; 

gdzie rotateSpin i rotateOrbit są macierzami rotacji definiowania korkociąg (obrót o pochodzeniu obiektu) oraz orbity (obrót o pochodzeniu świata poniższym tłumaczeniem), odpowiednio. Zwróć uwagę, że kolejność, w której operacje wpływają na wierzchołki usługi, jest od lewej do prawej.

Powiązane problemy