Dreidimensionale Spielewelten

Werbung
Dreidimensionale Spielewelten
- Die dritte Dimension Themen:
• Beschreibung der dreidimensionalen Spielewelt durch Vektoren
• Dreidimensionale Wetltransformationen durch Matritzen
• Schnelle Quadratwurzelberechnung
• Schnelle Berechnung von Rotationsmatritzen
Softwaretechnologie II - M. Thaller
Wintersemester 2005 / 2006
Referentin: Tanja Lange
1
Koordinatensysteme
2 Arten
der Erweiterung des zweidimensionalen Koordinatensystems in
die Dritte Dimension:
Für DirectX-Programmierer:
 Linkssystem = positive z-Achse zeigt in Monitor
Rechtssystem = z-Achse zeigt in entgegengesetzte Richtung
2
Grundbegriffe: Definition Vektor
ein Vektor ist eine Liste von Zahlen !
ein Vektor ist eine gerichtete, orientierte Strecke im Raum
Vektoren werden durch Pfeile repräsentiert.
Länge des Pfeils = Betrag des Vektors 
In der Geometrie ist ein Vektor eine Klasse von Pfeilen
gleicher Länge (Betrag), gleicher Richtung und gleicher
Orientierung.
Um beispielsweise das Dreieck ABC in
der Figur an die Position A'B'C' zu
verschieben, muss jeder Punkt um 7
Einheiten nach rechts und 3 nach oben
verschoben werden. Da diese Pfeile in
Länge, Richtung und Orientierung alle
übereinstimmen, fasst man sie zu einer
Klasse (Vektorklasse) zusammen. Man beschreibt die Klasse
durch die Verschiebung, die ihre Pfeile bewirken, im Beispiel:
im dreidimensionalen Raum entsprechend mit 3
Koordinaten.
3
Grundbegriffe:
Zeilenvektor: Bsp.: (3,-2,4)
3
Spaltenvektor: Bsp.: -2
4
ein Punkt P wird durch Komponenten (Ax, Ay, Az) beschrieben
Basisvektoren = senkrecht aufeinander stehende (orthogonale)
Vektoren  Hilfestellung: Dreifinger-Regel !
Basisvektoren eines dreidimensionalen,
rechtwinkligen Koordinatensystems:
Basisvektor, der die x-Achse repräsentiert: i = (1 0 0)
Basisvektor, der die y-Achse repräsentiert: j = (0 1 0)
Basisvektor, der die z-Achse repräsentiert: k = (0 0 1)
Ortsvektor = gebundener Vektor  hat Ursprung bzw.

Ausgangspunkt
Einheitsvektor = Vektor mit Betrag 1 = normiert
Bezeichnung: ex, ey, ez
4
Grundbegriffe:
Nullvektor = Vektor mit Betrag 0  Ursprung
Gegenvektor = gleicher Betrag, - Richtung, andere Orientierung
Translation = Verschiebung  Verschiebungsvektor
Verbindungsvektor = zw. 2 Punkten P (=Schaft) und Q (=Spitze)
Skalare = Beträge von Vektoren = gerichtete Größe
kollinear = Parallel, Schreibweise: a || b, Antiparallel =
entgegengesetzt
Linearkombination = Summe vom Vielfachen von Vektoren
Determinante = in der linearen Algebra eine spezielle Funktion,
die jeder quadratischen Matrix eine Zahl zuordnet.
Matrix = stellt Anordnung von Elementen in mehreren Richtungen
dar
In der Informatik entspricht eine Matrix einem n-dimensionalen Feld
In der linearen Algebra ist eine Matrix (Plural: Matrizen) eine Anordnung von
Zahlenwerten (oder Operatoren) in Tabellenform. Man spricht von den
Spalten und Zeilen der Matrix, und bezeichnet selbige auch als Vektoren
(d.h. Zeilenvektoren und Spaltenvektoren). Die Objekte, die in der Matrix
angeordnet sind, nennt man Komponenten oder Elemente der Matrix.
5
Vektorprodukt (Kreuzprodukt)
ein weiteres Produkt (Vektor c) zweier Vektoren a und b
steht senkrecht auf a und b  c = a • b  c = 0 für a || b
! Nicht verwechseln: !
Skalarprodukt (Punkt-):
a • b = |a| • |b| • cosα
 a • b = 0 für a ┴ b
 a • b = |a| • |b| für a || b
Betrag Vektor c = Flächeninhalt A  |c| = |a| • |b| • sinα
 |c| = |a| • |b| für a ┴ b, weiter gilt: c ┴ a, b
Fläche A ist vorzeichenbehaftet: Winkel > 180°  negatives
Vorzeichen, c entgegengesetzte Richtung
Beim arbeiten mit negativem Winkel wird Reihenfolge der
Multiplikation der Vektoren a und b festgelegt
Da Vektoren c1 und
c2 antiparallel sind 
6
Berechnung des Vektorprodukts
mit Hilfe von Determinanten, Bsp.: eine 3x3 Determinante:
Zur Berechnung wird Determinante mit Hilfe von Laplaceschen
Entwicklungssatz zerlegt:
1. Zeile: Basisvektoren
2. Zeile: Komponenten des Vektors a
3. Zeile: Komponenten des Vektors b
In Spaltenform:
 DirectX-Funktion: D3DXVector3* D3DXVec3Cross( )
Hilfsmethode zur Berechnung der Komponenten:
d.h.:
1 4 2 1 4 2
-1 5 6 -1 5 6 = (1 · 5 · 3) + (4 · 6 · 2) + (2 · (-1) · (-8)) – (1 · 6 · (-8)) – (4 · (-1) · 3) – (2 · 5 · 2) = 119
2 -8 3 2 -8 3
7
Polarkoordinaten (Kugelkoordinaten)
für Konstruktion von 3D-Szenarien einer Weltraumsimulation
Bsp.: 30° nach rechts drehen; 40° nach oben drehen; 0,5 aU geradeaus fliegen
 leichter zu interpretieren als kartesische Koordinaten (x-, y-, z-)
Für eine dreidimensionale Polarkoordinatendarstellung benötigt
man zwei Winkel sowie die Länge des Ortsvektors
x = Entfernung * cos(Vertikalwinkel) * sin(Horizontalwinkel)
y = Entfernung * sin(Vertikalwinkel)
z = Entfernung * cos(Vertikalwinkel) * cos(Horizontalwinkel)
Horizontalwinkel = Drehung nach rechts (positiver Wert) oder
links (negativer Wert)
Vertikalwinkel =
Drehung nach oben (positiver Wert) oder
unten (negativer Wert)
8
Quadratwurzelberechnung
häufige Rechenoperation in einem Spiel im Zusammenhang mit
der Normierung und Längenberechnung von Vektoren
Entwicklung eigener, schneller Quadratwurzel-Routinen 
Prozessorleistung
Näherungsverfahren durch
unsigned long *ptr = NULL;
Iterationsverfahren nach dem
float Value;
alten Heron:
inline float FastWurzelExact(float r)
{
if(r==0.0f)
return 0.0f;
if(r<0.0f)
r = -r;
Value = r;
halfValue = 0.5f*r;
ptr = (unsigned long*)&r;
*ptr = (0xbe6f0000-*ptr)>>1;
temp1Wurzel = r;
 Da Zeiger ptr vom Typ unsigned long*, werden
Bits als die einer Ganzzahl interpretiert
 Prüfen, ob Wurzel von Null berechnet werden soll
(da bei Division durch Null evtl. Programmabsturz)
 Prüfen, ob Zahl zur QWB positiv ist
 Divisionen durch Multiplikation ersetzen !
temp1Wurzel *= 1.5f-temp1Wurzel*temp1Wurzel*halfValue;
temp1Wurzel *= 1.5f-temp1Wurzel*temp1Wurzel*halfValue;
return Value*temp1Wurzel;
}
9
Längenberechnung & Normierung
von Vektoren
Funktion für die Berechnung des Vektorbetrags
(unter Verwendung der FastWurzelExact( ) – Funktion):
inline float Calculate3DVectorLength(D3DXVec3* pVectorIn)
{
if(*pVectorIn == NullVector)
{
return 0.0f;
}
tempNorm = D3DXVec3LengthSq(pVectorIn);
tempNorm = FastWurzelExact(tempNorm);
return tempNorm;
}
// Quadratische Länge des Vektors mittels
// DirectX-Funktion D3DXVec3LengthSq( )
// berechnet
Normierung eines Vektors:
inline float NormalizeVector( )
{
If (tempNorm != 1.0f)
// prüfen, ob Vektor überhaupt normiert werden muß
{
tempNorm = FastWurzel(tempNorm); // es ist nicht immer erforderlich
}
// Vektor exakt zu normieren
}
10
Manipulation der 3D-Welt
Transformation von Vektoren mit Hilfe von Matrizen
 DirectX-Funktion: D3DXVector3* D3DXVec3TransformCoord( )
Durch DirectX keine einzelnen Transformationen mehr
notwendig
Nur Adresse der Transformationsmatrix an DirectX-Funktion
SetTransform( ) mit Hinweis auf Weltkoordinatensystem
(Welttransformation) übergeben
 die grafische Darstellung (Renderprozess) des Objekts
erfolgt dann in korrekter Größe (Skalierung), Ausrichtung und
Verschiebung !
11
Manipulation der 3D-Welt
Translationsmatrix für die Bewegung im Raum
Erweiterung der Translationsmatrix T
für die Bewegung im Raum:
 DirectX-Funktion: D3DXMatrix* D3DXMatrixTranslation( )
Skalierungsmatrix
Skalierungsmatrix S lässt sich ohne
Probleme um eine Dimension erweitern:
 DirectX-Funktion: D3DXMatrix* D3DXMatrixScaling( )
Einheitsmatrix
Alle Transformationsmatritzen werden
stets als Einheitsmatrix initialisiert:
 DirectX-Funktion: D3DXMatrix* D3DXMatrixIdentity( )
12
Rotationsmatrizen für Drehung
Im dreidimensionalen Raum kann sich ein Objekt um eine
beliebig orientierte Achse drehen
Rotation eines Vektors um x-Achse lässt sich durch drei
Gleichungen beschreiben: xneu = x
yneu = ycosα - zsinα
zneu = ysinα + zcosα
Zugehörige Matrix Rx hat folgenden Aufbau:
-y
 Bsp. anhand dreier Winkel (0°, 90°, 180°)
α2
α
1-z
Gleichung 1: Rotation um x-Achse beeinflußt x-Komponenten des Vektors nicht
Gleichung 2: Drehung um 0° überführt alte y-Komponente in neue yKomponente, Drehung um 90° überführt negative z-Komponente in neue yKomponente, Drehung um 180° überführt y-Komponente in negative yKomponente
Gleichung 3: Drehung um 0° überführt alte z-Komponente in neue zKomponente, Drehung um 90° überführt y-Komponente in neue z-Komponente,
13
Drehung um 180° überführt z-Komponente in negative z-Komponente
Rotationsmatrizen für Drehung
Rotation eines Vektors um y-Achse:
Zugehörige Matrix Ry:
Rotation eines Vektors um z-Achse:
Zugehörige Matrix Rz:
xneu = xcosα + zsinα
yneu = y
zneu = -xsinα + zcosα
xneu = xcosα - ysinα
yneu = xsinα + ycosα
zneu = z
 DirectX-Funktion: D3DXMatrix* D3DXMatrixRotationX( )/…Y( )/…Z( )
14
Rotationsmatrizen für Drehung
Rotation um beliebige Achse:
Trick zur Aufstellung der Matrixgleichung:
Rotationsachse auf eine bekannte Achse (z.B. z-Achse)
transformieren (Drehung wird so zur Drehung um z-Achse mit
gleichem Winkel), Rücktransformation in die ursprüngliche
Rotationsachse mit inverser x- und y-Achsen-Rotationsmatritzen
(= rückgängig machen der Transformation einer Matrix, d.h.
Rotationsmatrix Drehung von 10° um x-Achse  inverse
Rotationsmatrix Drehung von -10° um x-Achse)
 DirectX-Funktion: D3DXMatrix* D3DXMatrixInverse( )
Rotationsmatrix für eine Drehung um beliebige Achse:
x, y, z = Komponenten der
normierten Rotationsachse
 DirectX-Funktion: D3DXMatrix* D3DXMatrixRotationAxis( )
15
Frame-Rotationsmatrizen &
Gesamtrotationsmatrizen
Zwei Typen von Rotationsmatrizen:
Gesamtrotationsmatrix: verantwortlich für endgültige Ausrichtung
eines Objekts aus dessen Anfangsorientierung
Frame-Rotationsmatrix: beschreibt nur Drehung während des
aktuellen Frames
 neue Gesamtrotationsmatrix nach Framedrehung durch Multiplikation FrameRotationsmatrix mit Gesamtrotationsmatrix des vorangegangenen Frames
(Multiplikationsreihenfolge abhängig von gegebenem Problem!)
 Für Rotation von Planeten, Wolken und Asteroiden folgende
Multiplikation:
R(neue Rotationsmatrix) = R(alte Rotationsmatrix) * R(für Drehung pro Frame)
Gesamtrotationsmatrix R muß zu Beginn des Spiels als
Einheitsmatrix initialisiert werden D3DXMatrixIdentity( )
 Zur Kurvenbewegung eines Raumschiffs wird
Multiplikationsreihenfolge umgedreht:
R(neue Rotationsmatrix) = R(für Drehung pro Frame) * R(alte Rotationsmatrix)
16
Simulation von Bewegung
Bsp. für den Gebrauch (Simulation der Bewegung eines
Asteroiden durch den Weltraum):
Variablen zur Beschreibung der Bewegung:
D3DXVector3 Ortsvektor, Eigenverschiebung, Rotationsachse; float Rotationsgeschwindigkeit
Matrizen zur Transformation:
D3DXMatrix Transformationsmatrix, Scalematrix, Rotationsmatrix, FrameRotationsmatrix,
Translationsmatrix
als Einheitsmatrizen initialisieren: D3DXMatrixIdentity( )
Skalierungsmatrix erzeugen: Scalematrix._11 = scaleX, …
Rotationsachse und –geschwindigkeit festlegen
Rotationsmatrix für Rotation von Frame zu Frame: D3DXMatrixRotationAxis( )
aktueller Ortsvektor: Ortsvektor = Ortsvektor + Eigenverschiebung
aktuelle Translationsmatrix mit Hilfe von Ortsvektor erzeugen:
Translationsmatrix._41 = Ortsvektor.x, …
aktuelle Rotationsmatrix: Rotationsmatrix = Rotationsmatrix * FrameRotationsmatrix
Gesamttransformationsmatrix zur korrekten Darstellung im Raum:
Transformationsmatrix = Scalematrix * Rotationsmatrix * Translationsmatrix
17
Schnelle Berechnung von
Rotationsmatrizen
Mehrere Funktionen zur Erzeugung von Rotationsmatrizen
Problem: bei Berechnung der Sinus- und Kosinuswerte relativ langsame API-Funktion
Computer werden immer schneller, trotzdem keine unnötige Rechenzeit verschwenden !
Rotationsmatrizen mit Look-up-Tabellen erzeugen

Problem: Drehungen finden in zwei Richtungen statt
(Drehwinkel positiv oder negativ)
Speicherverschwendung (für Bereich -360° bis +360°)
negative in positive Winkel umwandeln!
Winkel -10° = 350° (360° + (-10°))

merke folgende Regel:



360° + neg. Winkel = pos. Winkel
Rotationsmatrizen mit gleichbleibendem Rotationswinkel

falls diese ständig benötigt werden  einmal erzeugen und
immer wieder verwenden (einfache Optimierungsmethode, die
oft vergessen wird)
18
Schnelle Berechnung von
Rotationsmatrizen
Rotationsmatrizen mit Hilfe von vorberechneten Sinus- und
Kosinuswerten erzeugen

statt Winkel vorberechnete Sinus- und Kosinuswerte an
entsprechende Funktion übergeben
(Richtung beachten! für z.B. -10° einfach neg. Wert übergeben)
inline void CreateRotMatrix( )
Rotationsmatrizen für kleine Winkel
Objekte drehen sich in einem Frame nur um kleine Winkel
 Frame-Rotationsmatrizen mit Sinus- und Kosinusnäherungen für
kleine Drehwinkel berechen
 Sinuswert für kleine Winkel (bis 10°) mittels Geradengleichung
sin (α) ~ α (Näherung (Approximation) ist Winkel im Bogenmaß!)

Kosinusfunktion für kleine Winkel mittels Parabelfunktion
cos (α) ~ 1 – 1.5·α² (Näherung ist Winkel im Bogenmaß!)
inline void CalcRotXMatrixS( )
inline void CalcRotAxisMatrixS( )
{ NormalizeVektor_If_Necessary( ) }
19
Schnelle Berechnung von
Rotationsmatrizen
Rotationsmatrizen für beliebige Winkel


Berechnung der Sinus- und Kosinuswerte muß um paar Glieder
erweitert werden
für Winkel im Bereich -180° bis +180°
positive Winkel > 180° müssen wegen
Rechengenauigkeit in negative
umgerechnet werden (Winkel – 360°),
negative < 180° umgekehrt (360° + Winkel)
Hinweis: bei der praktischen Anwendung Division durch
Multiplikation ersetzen !
inline void CalcRotXMatrix( )
inline void CalcRotAxisMatrix( )
{
NormalizeVektor_If_Necessary( )
}
20
Literatur
BÜCHER:
3D-Spiele mit C++ und DirectX in 21 Tagen, Alexander Rodolph,
Markt + Technik Verlag, München, 2003
INTERNET:
https://www.htw-saarland.de/fb-gis/labore/strahlenschutz/
folder.2005-06-14.6092569165/physkriptEtechnikteil1.pdf
iva.uni-ulm.de/physik/repetitorium/MATHEMATIK/10/10.html-4k
de.wikipedia.org/wiki/Vektor - 41k
21
Herunterladen