SelfDXD von Martin Pyka
SelfDXD --- DirectX Graphics --- Theoretisches Vorwissen
Matrizen
Einleitung
Was ist eine Matrix?
Translation
Rotation
Skalieren
Multiplizieren von Matrizen

Einleitung

Dieses Kapitel bietet Ihnen eine kurze Einführung in das Thema Matrizen. Alle hier erklärten Dinge sind auf das Arbeiten mit Direct3D ausgerichtet. Die Theorie der Matrizenrechnung ist damit also noch lange nicht erschöpfend behandelt.


Was ist eine Matrix?

Eine Matrix ist, um es in Programmierersprache auszudrücken, ein zweidimensionales Array, das Zahlen speichert. In DirectX wird dabei eine ganz spezielle Matrix verwendet. Sie ist 4x4 Felder gross. In Delphi ist der Datentyp TD3DMatrix allerdings kein Array sondern ein Record:

TD3DMatrix = record
{ _11 _12 _13 _14 }
_21 _22 _23 _24
_31 _32 _33 _34
_41 _42 _43 _44
alle Elemente sind vom Typ Single

Die erste Zahl jeder Variable gibt die Zeile an, die zweite Zahl die Spalte.

Der Einsatz von Marizen hat folgenden Hintergrund: im Kapitel Elemente der 3D-Welt werden Sie lernen, dass 3D-Körper in erster Linie aus Vertices bestehen, die zum Beispiel die Ecken von Körpern kennzeichnen. Für das Verschieben, Rotieren und Skalieren (Vergrössern, Verkleinern) von 3D-Modellen sind bestimmte Berechnungen notwendig. Diese Berechnungen sind jedoch bei allen Punkten eines Modells gleich. Um zum Beispiel beim Verschieben nicht für jeden Vertex den gleichen Term eingeben zu müssen, kann man sich der Hilfe einer Matrix bedienen. Eine Matrix wird nämlich wie folgt auf einen Vertex angewendet:

x_neu = (x * _11) + (y * _21) + (z * _31) + _41
y_neu = (x * _12) + (y * _22) + (z * _32) + _42
z_neu = (x * _13) + (y * _23) + (z * _33) + _43

Leichter kann man es sich so erklären: Wenn man sich den Aufbau des Matrix-Record's anschaut, dann beziehen sich die ersten drei Spalten von links auf die Berechnung der x-, y- und z-Koordinaten der Vertices. Dabei werden die ersten drei Zeilen einer Spalte mit der x-, y- und z-Koordinate multipliziert und alle 3 Ergebnisse mit der vierten Zeile zusammen addiert. Die vierte Spalte wird bei der Berechnung von Vertices nicht benötigt. Sie hat eine andere Funktion, die in einem späteren Kapitel behandelt wird, für den Theorieteil aber erstmal nicht von Bedeutung ist.

Diese Form der Berechnung bietet Ihnen alle Möglichkeiten Ihr Objekt verschieben, skalieren oder rotieren zu können. Hier ein Beispiel:

Verschieben um 3 Pixel nach rechts die entsprechende Matrix
x_neu = (x * 1) + (y * 0) + (z * 0) + 3 { _11= 1 _12= 0 _13= 0 _14= 0 }
y_neu = (x * 0) + (y * 1) + (z * 0) + 0 _21= 0 _22= 1 _23= 0 _24= 0
z_neu = (x * 0) + (y * 0) + (z * 1) + 0 _31= 0 _32= 0 _33= 1 _34= 0
_41= 3 _42= 0 _43= 0 _44= 1

Wichtig ist dass die Faktoren _11, _22, _33 den Wert 1 haben, da sonst der vorherige x-Wert nicht übernommen wird. Die Variable _41 gibt schliesslich die Verschiebung auf der x-Achse an.

Eine Matrix die in der Hauptdiagonalen (von oben links nach unten rechts) nur den Wert 1 besitzt und ansonsten nur 0, nennt man Einheitsmatrix.

Einheitsmatrix
{ 1 0 0 0 }
0 1 0 0
0 0 1 0
0 0 0 1

Wendet man diese Matrix auf Vertices an, kommen die gleichen Koordinaten dabei heraus.


Translation

Translation meint, ein 3D-Objekt um eine bestimmte Anzahl an Koordinaten zu verschieben. Dabei bleibt die Grösse und die Ausrichtung des Objektes die gleiche.

Transformationsmatrix
{ 1 0 0 0 }
0 1 0 0
0 0 1 0
Tx Ty Tz 1

Zur Verschiebung eines 3D-Objektes, werden der Matrix einfach nur die Werte, um die das Objekt verschoben werden soll, in die Additionsfelder eingegeben.


Rotation

Ein Objekt können Sie sowohl auf der x-, y-Achse als auch auf der z-Achse rotieren lassen. Dazu müssen Sie mit den Winkeklfunktionen Sinus und Cosinus arbeiten. Grundlagen zur Rotation werden im Kapitel Berechnung von Rotationen behandelt.

Rotation um die x-Achse
{ 1 0 0 0 }
0 cos(a) sin(a) 0
0 -sin(a) cos(a) 0
0 0 0 1

Rotation um die y-Achse
{ cos(a) 0 -sin(a) 0 }
0 1 0 0
sin(a) 0 cos(a) 0
0 0 0 1

Rotation um die z-Achse
{ cos(a) sin(a) 0 0 }
-sin(a) cos(a) 0 0
0 0 1 0
0 0 0 1

Diese drei Tabellen zeigen, wie Matrizen aussehen, die zur Berechnung von Rotationen entlang der verschiedenen Achsen notwendig sind. a bezeichnet hierbei den Winkel im RAD-Format. Dabei sind 2*Pi=360°.


Skalieren

Eine Matrix können Sie auch dazu verwenden, 3D-Objekte in Ihrer Grösse zu verändern. Im Prinzip werden dabei alle Punkte des Objektes um einen bestimmten Faktor von ihrem Ursprung verschoben.

Skalieren
{ Sx 0 0 0 }
0 Sy 0 0
0 0 Sz 0
0 0 0 1

Sx, Sy und Sz sind dabei die Faktoren, um die das Objekt bzw. Ihre einzelnen Punkte skaliert werden.


Multiplizieren von Matrizen

Durch das Multiplizieren von Matrizen können Sie mehrere Veränderungen eines Objektes in einer Matrix zusammenfassen. Wenn Sie zum Beispiel ein Objekt der x-Achse entlang rotieren möchten, um es anschliessend nach oben zu verschieben und grösser zu skalieren, dann können Sie alle drei Matrizen durch das Multiplizieren zusammenfassen und müssen somit nur eine Matrix an Ihrem Objekt anwenden.

Das Multiplizieren selbst ist bei Matrizen ein wenig komplizierter. Allerdings bietet DirectX Ihnen eine Funktion, die Ihnen die Multiplikation zweier Matrizen abnimmt, so dass wir uns selbst darum nicht kümmern brauchen. Daher verzichte ich hier auf eine genaue Erklärung. Im Internet werden Sie hierzu jedoch erschöpfendes Material finden. Für uns reicht es jedoch zu wissen, dass eine Multiplikation zweier Matrizen immer bewirkt, dass die Bewegungen, die in den beiden Matrizen verankert sind, zusammengefasst werden.