Mathematische Grundlagen
Für 3D Programmierung sind díe Vektorrechnung und die Differentialrechnung so ziemlich das einzige,was
man wissen muss. Man hat es mit den Objekten Punkt, Gerade, Ebene und Matrix zu
tun. Das einzige Schwierigkeit sind Matrizen. Auf sie
werden wir im Kapitel Transformationen zu sprechen kommen.
Daneben gibt es noch die Operationen Vektoraddition, Vektorsubtraktion, Skalarprodukt, Vektorprodukt und Skalare
Multiplikation. Wer sich da nicht sicher ist , hat das schnell "herausgegoogelt".
Geometrische
Objekte und ihre Implementation
Objekte
Ein Überblick:
Geometrisches Objekt | Drawing3d Klasse | Erzeugung | Beschreibung |
Vektor bzw. Punkt | xyz | P = new xyz(1,2,3) | P.x = 1,P.y = 2, P.z = 3 |
Gerade | LineType | P=new xyz(2,1,3);
Dir= new xyz(0,0,1);
L = new LineType(P , Dir); | Eine Gerade durch den Punkt P mit der Richtung Dir |
Ebene | Plane | P=new xyz(2,1,3);
N= new xyz(0,0,1);
e = new Plane(P,N); | e ist Ebene durch den Punkt P
mit Normalenvektor N |
Matrix | Matrix | P ein Punkt,
T = Matrix.Translation(P);
g eine Gerade
Alfa ein double.
R = Matrix.Rotation(R,Alfa);
Plane eine Ebene
M = Matrix.Mirror(Plane); | T ist eine Translationsmatrix
R ist eine Rotationsmatrix
M ist eine Spiegelungsmatrix |
Die entsprechenden 2d-Objekte haben den Typ xy bzw. LineType2D.
Operationen
Ein Überblick: P und Q seien vom Typ xyz, Lamda vom Typ double, A und B seien Matrizen.
Operation | Implementation |
Vektoraddition | P+Q |
Vektorsubtraktion | P-Q |
Skalarprodukt | P*Q |
Vektorprodukt | P&Q |
Skalare Multiplikation | P*Lamda |
Multiplikation zweier Matrizen | A*B |
Multikaltion Matrix mit Punkt | A*P |
Beispiel1: Berechnung des Volumens eines Tetraeders mit den Punkten A,B,C,D.
xyz A = new xyz(4,1,1);
xyz B = new xyz(2,5,4);
xyz C = new xyz(1,-3,-6);
xyz D = new xyz(9,0,7);
double Volumen = ((B-A)&(C-A))*(D-A)*0.5;// Halbe Determinante
Volumen = System.Math.Abs(Volumen); // der Absolutwert
Beispiel 2: Berechnung des Abstandes eines Punktes P von einer Ebene
gegeben durch A und dem Normalvektor auf die Ebene.
xyz A = new xyz(4,-2,1);
xyz Normal = new xyz(5,1,3);
Normal = Normal.normalized(); // eine Methode von xyz
double Abstand = (P-A)*Normal;
Beispiel 3: Drehung eines Punktes P(3,1,2) um 46° um die Gerade g, die durch die Punkte A(4,1,2) und B(-3,-2,5)
gegeben ist.
xyz P = new xyz(3,1,2);
xyz A = new xyz(4,1,2);
xyz B = new xyz(-3.-2,5);
LineType g = new LineType(A, B-A);
Matrix Rotation = Matrix.Rotation(g,46/180*System.Math.PI); // im Bogenmaß
xyz DestinationP = Rotation*P;
Methoden
In der Drawing 3D Mathematikbibliothek gibt es eine Unzahl von Methoden und
Funktionen, die sich mit diesen geometrischen Objekten beschäftigen,
z.B: Die Methode P.Cross(g,out double Lam,out xyz Crosspoint) liefert den
Schnittpunkt der Ebene P mit der Geraden g. P.Cross(Q) ergibt die Schnittgerade
der beiden Ebenen P und Q.
Funktionen
Definitionen
Eine Funktion oder Abbildun gordnet Elementen einer Menge A Elemente einer anderen Menge B zu.
Die Menge A bezeichnen wir mit Definitionsbereich, wenn für jedes Element die Zuordung einen "vernünftigen" Wert in B ergibt. B bezeichnen wir als Zielmenge.
Symbolisch schreibt man f : A --> B.
Die reellen Zahle bezeichnen wir mit R.
RXR oder R² sind Abkürzungen und beduten einfach die Menge
der reellen Zahlenpaare wie (1.4,2.5), (4,-3) usw.
Also kann man RXR auch verstehen als Menge von Punkten der Ebene.
In der Literatur wird RXR als kartesisches Produkt bezeichnent.
RXRXR oder R³ bezeichnen die Menge der reellen
Zahlentripel wie (1.4,2.5,4.2), (0.4,-3,7.2) usw.
Also kann man RXRXR auch verstehen als Menge von Punkten (oder Vektoren) im Raum.
Ein Intervall [0,1] bezeichnet alle reellen Zahlen zwischen 0 und 1, z.B.:
0.2345,0.456456,0.13216,0, 1,... usw
Kurven und Fächen
Eine Kurve in der Ebene wird dargestellt durch eine Funktion
f:[0,1] -->RXR.
z.B.:
Ein Kreis:
x = radius*Cos(t*2*PI));
y = radius*Sin(t*2*PI));
0<= t, und t <=1.
Hier wird jedem t ein Paar von Zahlen x,y zugordnet. Diese Paare als Punkte
der Ebene aufgefasst bilden einen Kreis.
Eine Kurve im Raum wird dargestellt durch eine Funktion
f:[0,1] -->RXRXR.
z.B.:
Eine Spirale:
x = radius*Cos(t*2*PI));
y = radius*Sin(t*2*PI));
z = 10*t;
0<= t, und t <=1.
Durchläuft t die Werte von 0 bis 1, so ergeben x und y einen Kreis. Überlagert wird er
von einer stetigen Erhöung des z-Wertes, der schließlich den Wert 10 erreicht.
Somit ergibt sich eine Spirale mit der Höhe 10 mit einer Windung.
Polygone
Die wichtigsten Objekte bei einer 3D Darstellung sind Polygone. Letzt endlich wird
alles zurückgeführt auf die Darstellung von Polygonen.
Drawing 3D implementiert zwei- und dreidimensionlae Polygone:
- xyzArray: Enhält einen Array von Punkten vom Typ xyz
- xyArray: Entält einen Array von Punkten vom Type xy
Zusäzlich werden Listen von xyzArrays und xyArrays definiert:
- Loxyz : Eine Liste von xyzArray
- Loxy: Eine Liste von xyArray
Diese Listen werden verwendet. wenn eine Fläche "Löcher" hat. In diesem Fall ist der erste Array von Loxyz die Kontur, alle anderen
Arrays sind "Löcher".
Definition eines xyzArray mit 4 Punkten:
...
xyzArray A = new xyzArray(4);
A[0] = new xyz(1,1,0);
A[1] = new xyz(1,11,0);
A[2] = new xyz(11,11,0);
A[3] = new xyz(11,1,0);
...
Die Klasse xyzArray enthält eine Menge von Methoden und Eigenschaften:
A sei vom Typ xyzArray
- Enthält A Count Punkte so ist A.Value eine Funktion, die das reelle Intervall
[0, Count] auf die Punkte Polygons abbildet.
Ist z.B.: Count = 8 , so ist A.Value(3.5) der Halbierungspunkt der Strecke
A[3]A[4].
- Mit A.Transformation(Matrix) kann ein Polygon transformiert werden.
- A.LengthToParam und A.ParamToLength können Parameter, wie sie von Value
verwendent werden in die tatsächliche Länge umgerechnet werden und umgekehrt.
- A.MaxBox() lieftert den kleinsten Quader, in dem A enthalten ist.
- u.v.a
Polygone kännen in 2 Modi ausgegeben werden.
- Im Linemodus: Device.PolygonMode = Polygonme.Line;
Dies entspricht der Graphicsmethode DrawPolygon
- Im Fillmode :Device.PolygonMode = Polygonme.Fill;
Dies entspricht Graphics.FillPolygon.
Wichtig
In Füllmodus muss der Uhrzeigersinn berücksichtigt werden. Ein 3D-Polygon
stellt eigentlich zwei Seiten dar. Eine die im Uhrzeigersinn und eine
("darunter"), die im Gegenuhrzeigersinn berandet ist.
Die Drawing 3D Device zeichnet nur jene Seite, die im Uhrzeigersinn ist. Die
andere Seite kann trotzdem angezeigt werden, wenn die Egenschafft Culling auf
false gesetzt wird.
Code Beispiel in c#.
Der Codeinhalt vom Form1
public partial class Form1 : Form
{
MyDevice Device = new MyDevice();
public Form1()
{
InitializeComponent();
Device.WinControl = this;
}
}
public class MyDevice:OpenGlDevice
{
xyzArray A = new xyzArray(5);
public override void OnPaint()
{
base.OnPaint();
drawPolyLine(A);
}
protected override void OnCreated()
{
base.OnCreated();
BackColor = Color.White;
A[0] = new xyz(-3, 0, 0);
A[1] = new xyz(0, 4, 0);
A[2] = new xyz(3, 0, 0);
A[3] = new xyz(0, -4, 0);
A[4] = new xyz(-3, 0, 0);
}
}
Und so siehts aus :
Links ist die Ausgabe im Füllmodus, rechts im Linemodus. Dabei ist lediglich in
der Paintmethode "Device.PolygonMode = PolygonMode.Fill;" zu setzen.
Die Drawing 3d Device besitzt die Eigenschaften PenWidth, PenColor und PenStyle. Probier diese mal aus.