![]() ![]() ![]() |
|
![]() |
|
![]() |
![]() ![]() ![]() ![]() ![]() ![]() |
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.
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 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.
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°.
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.
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.