visualisierung von scheibenaufbauten in...

96
Visualisierung von Scheibenaufbauten in Verglasungseinheiten mit Hilfe der neuen Microsoft .net-Framework 3.0 Technologie Diplomarbeit zur Erlangung des akademischen Grades Diplom – Mathematiker (FH) vorgelegt von Mathias Schubert Friedberg 2007 Eingereicht am: 30.05.2007 Betreuer: Prof. Dr. Ulrich Abel (FH Gießen – Friedberg) Prof. Dr. Michael Guckert (FH Gießen – Friedberg)

Upload: lamdung

Post on 17-Sep-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

Visualisierung von Scheibenaufbauten in

Verglasungseinheiten mit Hilfe der

neuen Microsoft .net-Framework 3.0

Technologie

Diplomarbeit

zur Erlangung des akademischen Grades

Diplom – Mathematiker (FH)

vorgelegt von

Mathias Schubert

Friedberg 2007

Eingereicht am: 30.05.2007

Betreuer: Prof. Dr. Ulrich Abel (FH Gießen – Friedberg)

Prof. Dr. Michael Guckert (FH Gießen – Friedberg)

I Inhaltsverzeichnis I

I Inhaltsverzeichnis

I Inhaltsverzeichnis I

II Bildverzeichnis V

1.0 Vorwort 1

1.1 Erklärung 1

1.2 Danksagung 2

2.0 Einleitung 3

2.1 Ziel der Arbeit 3

2.2 Problemstellung 3

2.3 Umsetzung der Arbeit 3

2.4 Verzeichnis der Kurzzeichen und Symbole 4

2.5 Begriffserklärung 5

3.0 Delaunay-Triangulation 8

3.1 Einführung 8

3.1.2 Klassische Problemstellungen 8

3.1.3 Gründe für die Verwendung der Delaunay-Triangulation 9

3.1.4 Verwendung der Delaunay-Triangulierung 12

3.1.5 Bedingungen für eine Delaunay-Triangulation 12

3.2 Der inkrementelle Algorithmus 12

3.2.1 Voraussetzungen 12

3.2.1.1 Kriterien beim Triangulieren 12

3.2.1.2 Fälle bei der Triangulierung von 4 Punkten 16

3.2.1.2.1 Erster Fall 16

3.2.1.2.2 Zweiter Fall 17

3.2.1.2.3 Dritter Fall 17

3.2.1.3 Das Umkreiskriterium 18

3.2.1.4 Optimale Triangulierung 19

I Inhaltsverzeichnis II

3.2.2 Der inkrementelle Algorithmus 21

3.2.2.1 Ergebnis des Algorithmus 25

3.3 Mathematische Grundlagen 26

3.3.1 Konvexe und nichtkonvexe Hüllen 26

3.3.1.1 Definition 26

3.3.2 Flächeninhalt von Dreiecken 27

3.3.2.1 Berechnung 27

3.3.3 Kreis mit 3 Punkten erzeugen 29

3.3.3.1 Berechnung 29

3.3.3.2 Punkt im Kreis 31

3.3.4 Berechnung eines Kreisbogens 31

3.3.4.1 Analytische Lösung 31

3.4 Sonderfälle 32

3.4.1 Nichtkonvexe Hülle 32

3.4.1.1 Einleitung und Idee 32

3.4.2 Darstellung von Löchern 34

3.4.2.1 Einleitung und Idee 34

4.0 Exkurs Voronoi-Diagramm 36

4.1 Das Postamtproblem 36

4.2 Begriffe 37

4.3 Fälle bei der Voronoi-Konstruktion 39

4.3.1 Punkt im Umkreis 39

4.3.2 Weiterer Punkt im Dreieck selbst 40

5.0 Fenster- und Glaseigenschaften 41

5.1 Fensteraufbau 41

5.2 Eigenschaften von Glas 41

5.2.1 Materialarten des WPF 42

5.2.1.1 Lambert Material 42

5.2.1.2 Emissives Material 43

5.2.1.3 Specular Material 44

5.2.2 Verwendung der Materialien 45

6.0 Verwendete Programmiersprachen und Ressourcen 46

I Inhaltsverzeichnis III

6.1 C# (CSharp) 46

6.1.1 Unterschiede C++ und C# 46

6.1.1.1 Laufzeitumgebung 46

6.1.1.2 C#-Objekte 47

6.1.1.3 C#-Anweisungen 48

6.1.2 Funktionen, die in C# nicht zu Verfügung stehen 49

6.2 .net 3.0 49

6.2.1 Einführung in das .net 3.0 49

6.2.1.2 Einige wichtige Objekte und Methoden 50

6.2.1.2.1 Collection 50

6.2.1.3 WPF 51

6.2.1.3.1 Voraussetzung damit WPF einen 3-D Körper darstellt 52

6.2.1.3.2 Normalen 53

6.2.1.3.3 Texture mapping 54

6.2.1.4 x-Datei 56

6.3 XML 57

6.3.1 Einleitung 57

6.3.2 Aufbau einer XML Datei 58

6.3.3 Verschachtelung 58

6.3.4 Attribute 58

6.3.5 Elemente ohne echtes End-Tag 59

6.3.6 Nur ein Wurzel/Stamm Element ist erlaubt 60

6.3.7 XML Deklaration 60

6.3.8 Das Auslesen einer XML Datei 62

6.3.9 CamXML 62

7.0 Umsetzung in eine DLL 63

7.1 Dynamic-Link Library (DLL) 63

7.1.1 Die Schnittstelle (Interface) der DLL 63

7.1.2 Erstellen einer DLL mit MS Visual Studio 2005 64

7.2 Auslesen der Punkte mit der Funktion SortPoints 64

7.2.1 Voraussetzungen 64

7.3 Randgeometrien 65

7.3.1 Die verschiedenen Ausschnitte 65

7.3.1.1 Böhrlöcher 65

I Inhaltsverzeichnis IV

7.3.1.2 Senkbohrlöcher 66

7.3.1.3 Innenausschnitte 66

7.4 SpacerTriangulation 67

7.5 SideTriangulation 69

7.6 InCircle 71

7.7 TestToNotConvex 71

7.8 CreateRectangleMesh 72

7.8.1 Voraussetzungen 72

7.8.2 Der Algorithmus 73

7.8.3 Finde nichtkonvexe Seitenteile 74

7.8.4 Bohrlöcher und Senkbohrlöcher 75

7.8.5 Innenausschnitte 75

7.8.6 Schluss 76

7.9 CreateGlassMesh 77

7.10 Wireframe 78

7.11 Strukturglas 80

8.0 Fazit 82

8.1 Komplexität des Algorithmus 82

8.2 Probleme während der Umsetzung 82

8.3 Abschließende Betrachtungen 83

9.0 Anhang 84

9.1 Literaturverzeichnis 84

9.2 Bilder 86

II Bildverzeichnis V

II Bildverzeichnis

Bild 1: Höhenprofil eines Bergkamms, der trianguliert wurde.

Bild 2: Modell der Triangulierung des Bergkamms von oben.

Bild 3: Oben Kriterium der kürzeren Diagonalen, in der Mitte Max-Min-

Winkelkriterium und unten Max-Min-Radiuskriterium [6].

Bild 4: Triangulation nach Min-Max-Kriterium. Lokal optimal, da a(T2) <

a(T1). Jedoch ist es nicht global optimal. Deshalb ist eine bessere

Triangulation möglich [8].

Bild 5: Allgemeiner Fall der Triangulierung von vier Punkten. Alle vier

Punkte bilden die konvexe Hülle.

Bild 6: Ein Punkt liegt nicht auf dem Rand.

Bild 7: Drei Punkte liegen auf einer Linie.

Bild 8: Umkreiskriterium. Links im Bild wird das Umkreiskriterium verletzt.

Durch Diagonalentausch (edge flip) wird rechts eine gültige Triangulierung

erreicht. Es genügt eines der beiden Dreiecke zu überprüfen. Das

Umkreiskriterium verhält sich in beiden Fällen äquivalent.

Bild 9: Zwei lokal optimale Triangulierungen. Beide sind bzgl. Min-Max-

Winkelkriterium optimal.

Bild 10: Startdreieck

Bild 11: Ein Punkt wird in die Triangulation eingefügt [5].

Bild 12: Die Umkreise werden bestimmt [5].

Bild 13: Neue Dreiecke entstehen [5].

Bild 14: Links ist eine konvexe Hülle und rechts eine nichtkonvexe Hülle

Bild 15: Konvexe Hülle

Bild 16: Dreieck

Bild 17: Kreis mit drei Punkten aufziehen, die auf dem Kreis liegen.

http://local.wasp.uwa.edu.au/~pbourke/geometry/circlefrom3

Bild 18: Links nichtkonvexe und rechts konvexe Stellen

Bild 19: Nichtkonvexe Hülle. Schwarz ist der eigentliche Rand und grün

die Dreiecke, die entfernt werden müssen.

Bild 20: Viereck mit Löchern

Bild 21: Gebietsaufteilung

Bild 22: Begriffe des Voronoi-Diagramm

Bild 23: Voronoi-Knoten und -Kanten

Bild 24: Veranschaulichung der Dualität

II Bildverzeichnis VI

Bild 25: Punkt im Kreis

Bild 26: Punkt im Dreieck

Bild 27: Lambert Material von der Website

http://www.cosc.brocku.ca/Offerings/3P98/2000/firstdate/boat.gif

Bild 28: Emissives Material von der Website

http://www.swirlx3d.com/tutorials/t010/matemis.png

Bild 29: Specular Material von der Website

http://www.evl.uic.edu/aej/488/diagrams/spherespec.gif

Bild 30: Links: Oberfläche mit normierter Normalen; Rechts: Oberfläche

mit Normalen und Winkel alpha

Bild 31: Verhältnisse von alpha und der Helligkeit

Bild 32: Texturen

Bild 33: Eine x-Datei

Bild 34: XML-Datei

Bild 35: Gummirand einer Vorderseite bei einem Viereck (Die Zahlen

stellen die Indexnummern der Punkte dar)

Bild 36: Seitenteil des Gummirandes (Die Zahlen stellen die

Indexnummern der Punkte dar)

Bild 37: Ausschnitt nichtkonvexe Ecke

Bild 38: Wireframe

Bild 39: Strukturglas

Bild 40: Strukturglas mit Loch

Bild 41: Bohrloch

Bild 42: Senkbohrloch

Bild 43: Fenster mit Kreisbögen

Bild 44: Bogen

Bild 45: Nichtkonvexe Ecken (ein Testbild; keine Fensterform)

Bild 46: Testbild

1.0 Vorwort Seite 1

1.0 Erklärung

Ich erkläre hiermit, dass ich die vorliegende Arbeit selbständig und ohne Benutzung anderer als der angegebenen Hilfsmittel angefertigt habe. Die aus fremden Werken wörtlich oder sinngemäß übernommenen Gedanken sind unter Angabe der Quellen gekennzeichnet.

Ich versichere, dass ich bisher keine Prüfungsarbeit mit gleichem oder ähnlichem Thema bei einer Prüfungsbehörde oder anderen Hochschule vorgelegt habe.

………………………………… ………………………………………

Ort, Datum Unterschrift

1.0 Vorwort Seite 2

1.1 Danksagung

Herrn Jürgen Makowka danke ich für das Hilfe und die Möglichkeit zu die-ser Arbeit. Herrn Michael Hartmann danke ich für die Teilnahme an dem Projekt.

Mein besonderer Dank gilt Herrn Prof. Dr. Ulrich Abel, der mir als Betreuer immer mit Rat und Tat zur Seite stand, und auch Herrn Prof. Dr. Michael Guckert, der mich als Zweitprüfer unterstützt hat.

Zuletzt möchte ich noch meiner Familie für ihre Unterstützung danken.

2.0 Einleitung Seite 3

2.0 Einleitung

2.1 Ziel der Arbeit

Im Unternehmen Albat und Wirsam (A+W) werden Fenster(-scheiben) im 2-Dimensionalen dargestellt. Da die Komplexität dieser Fensterscheiben immer mehr zu nimmt, wird eine 3-dimensionale (3D) Visualisierung be-nötigt. Zum Beispiel können einzelne Scheiben, aus denen ein Vielschei-benglas (VSG) besteht, unterschiedlich groß (z. B. durch eine Stufe) sein. Um zu wissen, an welcher Stelle diese einzelnen Scheiben sind, ist eine 3-dimensionale Ansicht hilfreich. Mit dieser Arbeit wird ein Teil dazu beige-tragen, dass dies realisiert werden kann.

2.2 Problemstellung

Gesucht wurde ein Algorithmus, der Oberflächen von Körpern in Dreiecke zerlegt. Diese Körper sind in unserem Fall Fensterscheiben, der Abstand-halter (das Metallstück zwischen zwei Fensterscheiben) des Fensters und der schwarze Gummi, der zwischen Glasrand und Abstandhalter liegt (Bild siehe Kapitel 9.2). Der Algorithmus sollte zudem erweitert werden, damit ein vorgegebener Glasrand und Löcher in der Scheibe möglich sind. Auch wichtig ist, dass wir uns in der Ebene befinden, also im R².

Durch eine sorgfältige Internet- und Bücherrecherche wurde in kurzer Zeit der Begriff Delaunay-Triangulation gefunden, der die obigen Vorgaben er-füllte und eine Umsetzung ermöglichte.

2.3 Umsetzung der Arbeit

Zur Umsetzung der Arbeit gehörten die Programmierung eines Delaunay-Algorithmus für das Projekt AWVision und das Nutzen von Ressourcen, die andere Programme des Unternehmens A+W bieten. Zur Umsetzung der Arbeit siehe Kapitel 5 bis 9. In Kapitel 3 werden die mathematischen Vor-aussetzungen für die nachfolgenden Kapitel geschaffen. Das vierte Kapitel beschäftigt sich mit einem Exkurs über Voronoi-Diagramme.

2.0 Einleitung Seite 4

2.4 Verzeichnis der Kurzzeichen und Symbole

K Kriterium Bezeichnung für Winkelkriterium

P Punktmenge

T Triangulation

a x b Vektorprodukt

a(T) sei ein Winkelmaß für ein Dreiecks aus T (z.B. kleins-ter/größter Innenwinkel).

p Punkt aus einer Punktmenge

2.0 Einleitung Seite 5

2.5 Begriffserklärung

- Konvexe Menge

Eine allgem. Teilmenge von M aus R² wird konvex genannt, wenn mit je zwei ihrer (beliebig gewählten) Punkte auch deren Verbindungsstrecke in der Menge liegt, d.h. wenn für alle gilt, dass

ist. Eine Menge, die nicht konvex ist, wird nichtkonvexe Menge genannt. Oft wird dafür auch die Bezeichnung konkave Menge verwendet. Dies ist je-doch irreführend, weil konkav nicht die Negation von konvex ist. - Konvexe Hülle

Der Durchschnitt (Schnittmenge) beliebig vieler konvexer Mengen ist kon-vex. Die konvexe Hülle einer Menge ist die kleinste konvexe Obermenge. Sie ist der Durchschnitt aller konvexen Mengen, in denen sie enthalten ist.

- Nichtkonvexe Menge

Diese Menge ist nichtkonvex. Polygone, die nichtkonvex sind, haben ein-springende Ecken bspw. ein T (Gemeint ist die Form, nicht der Buchstabe) oder ein Loch (bspw. ein Torus).

Warum nennt man diese Menge nicht konkav?

Mit konkav und konvex bezeichnet man zwei zueinander gegensätzliche

Eigenschaften (betreffend die Krümmung von Flächen und Kurven), wobei

konkav aber nicht das Gegenteil von konvex bedeutet.

Eine Fläche (oder Kurve) ist lokal (d.h. in der Nähe eines Punktes)

• konvex gekrümmt, wenn sie nach "außen" gewölbt ist,

und sie ist

• konkav gekrümmt, wenn sie nach "innen" gewölbt ist.

Ein Körper (oder eine Figur) wird immer von außen betrachtet. Er wird

konvex genannt,

2.0 Einleitung Seite 6

• wenn seine Oberfläche (der Rand) überall konvex gekrümmt ist.

In analoger Weise würde man einen Körper konkav nennen,

• wenn seine Oberfläche (der Rand) überall konkav gekrümmt ist.

Einen solchen Körper gibt es jedoch nicht.

Natürlich kann man definieren, dass eine Menge konkav ist genau dann,

wenn sie nicht konvex ist. Eine solche Definition wäre jedoch nicht tref-

fend, sondern irreführend und würde auch der Bedeutung (nach innen

gewölbt) nicht entsprechen. Eine Funktion, die nicht konvex ist, ist des-

halb noch nicht konkav (Beispiel eine Linie parallel zu x-Achse y = c).

- Triangulation für R²

Die Punkte der Dreiecke werden als Indexe angegeben, d. h. der erste

Punkt aus der Punktmenge P erhält den Indices eins usw.

Eine Menge aus Tripeln T:= {(ai, bi, ci) | ai, bi, ci ε {1, ..., M}, 1 ≤ i ≥ P} heißt Triangulation von P, wenn folgendes gilt: - Für jedes i ε {1, ..., M} Dreieck bilden die Punkte Pai, Pbi, Pci die Eck-punkte eines Dreiecks. - Jedes Dreieck aus T enthält keine weiteren Punkte aus P außer genau den drei Eckpunkten. - Die Menge der inneren Punkte eines Dreiecks ist disjunkt zu der Menge der inneren Punkte jedes anderen Dreiecks. - Die Vereinigung aller Dreiecke aus T ist gleich der konvexen Hülle [P] von P.

- Bei der Triangulation entstehen keine entarteten Dreiecke, d. h. die Drei-

ecke besitzen keine Punkte, die auf einer Linie liegen.

- Ein Ziel sind wohlgeformte Dreiecke, d. h. die Dreiecke besitzen keine spitzen Winkel. Sei T eine Triangulation von P und sei D ein Dreieck aus T mit Eckpunkten Pai, Pbi, Pci, dann heißen die Verbindungen PaiPbi, PbiPci, PbiPci Kanten (Dabei gilt: PaiPbi = PbiPai). Eine innere Kante ist die gemeinsame Kante zweier

2.0 Einleitung Seite 7

benachbarter Dreiecke aus T. Eine Kante, die nur zu einem Dreieck ge-hört, heißt eine Randkante.

- Dreiecksnetz

Das Resultat der Triangulation ist ein Netz aus Dreiecken. Es wird Drei-

ecksnetz genannt.

- Planarer Graph

Ein planarer Graph (auch plättbarer Graph) ist in der Graphentheorie ein

Graph, der auf einer Ebene mit Punkten für die Knoten und Linien für die

Kanten dargestellt werden kann, so dass sich die Kanten nicht schneiden.

- Kollinear

Punkte liegen auf einer Linie.

- Startdreieck

Ein Dreieck, welches zur Initialisierung der Triangulation dient. Dieses

Dreieck schließt in seiner Fläche alle Punkte ein, die trianguliert werden

sollen. Es wird auch als Initialisierungsdreieck oder Superdreieck bezeich-

net.

- WPF (Windows Presentation Foundation)

WPF, enthalten im .net 3.0 (enthält Klassen), dient zur Ausgabe von 2-D-

/3-D-Grafiken, Video, Audio und Bildern. Es setzt, im Gegensatz zu seinen

Vorgängern GDI und GDI+, auf Directx auf und bietet dadurch volle Hard-

warebeschleunigung.

3.0 Delaunay-Triangulation Seite 8

3.1 Einführung

3.1.1 Boris Nikolaevich Delone

Die Delaunay-Triangulation erhielt ihren Namen von dem russischen Ma-thematiker Boris Nikolaevich Delone [1]. Boris Delone wurde 1890 in St. Petersburg geboren und verstarb 1980. Er absolvierte sein Studium im Jahr 1913, in dem er unter anderem Algebra und Zahlentheorie studierte, an der Universität von Kiew. Seine Arbeiten führten ihn in seine Geburts-stadt St. Petersburg zurück. Dort arbeitete er in verschiedenen mathema-tischen Instituten und machte sich dadurch einen Namen als Mathemati-ker. Von 1935 bis 1942 war er Professor an der Universität Moskau. Der Namen Delaunay entstand durch die Übersetzung seiner Werke in die französische Sprache. Das Wort Triangulation definiert der Duden folgen-dermaßen: „Die Triangulation ist das Festsetzen eines Netzes von Drei-ecken zur Landvermessung (Geodäsie).“. Damit ist die Aufteilung einer bestimmten Fläche in einzelne Dreiecke gemeint, die die gegebene Fläche komplett abdecken.

3.1.2 Klassische Problemstellungen

Ein klassisches Problem der algorithmischen Geometrie ist die Ermittlung der konvexen Hülle. Es handelt sich dabei um folgendes Problem: Gege-ben seien n Nägel in einem Holzbrett, und um diese wird ein Gummiband gespannt. Die Lage des Gummibandes, nachdem es losgelassen wurde, soll bestimmt werden. Auch in höheren Dimensionen ist die konvexe Hülle für Punktmengen interessant. Im 3–dimensionalen Raum etwa können wir uns vorstellen, dass um die Punkte eine elastische Gummihaut gelegt wird. Das Problem wurde ausgiebig behandelt. Gründe dafür sind, dass es ein einfaches, sehr natürliches Problem ist. Viele andere Probleme sind darauf zurückzuführen. Natürlich gibt es aber auch Anwendungen, die aus anderen Teilbereichen kommen:

3.0 Delaunay-Triangulation Seite 9

• Beispielsweise sind verschiedene Mixturen gegeben, die zwei Substanzen in verschiedenen Konzentrationen enthalten. Kann ein vorgegebenes Mi-schungsverhältnis durch Mischung dieser Mixturen erreicht werden?

• Das automatische Erkennen von verschiedenen Holzsorten. Dazu misst man für ausreichend viele Bretter einer Holzsorte (z. B. Buche) zwei Pa-rameter z. B. Maserung und Helligkeit. Im Anschluss trägt man diese Punkte in eine Ebene ein und zeichnet die konvexe Hülle. Sollten nun Messwerte für eine unbekannte Holzsorte in der konvexen Hülle liegen, so kann man davon ausgehen, dass es sich um ein Buchenbrett handelt.

• Man ordne z. B. vier Tennisbälle so an, dass man möglichst wenig Verpa-ckungsmaterial benötigt. Das ist eine Minimierung der Oberfläche der kon-vexen Hülle.

3.1.3 Gründe für die Verwendung der Delaunay-Triangulation

Landschaftsoberflächen sind ebenfalls eine Einsatzmöglichkeit für die De-launay-Triangulation. Wenn die Koordinaten in eine Ebene transformiert werden, kann eine Delaunay-Triangulation durchgeführt werden. Deswe-gen erhält man eine Fläche, die in einzelne Dreiecke vollständig aufgeteilt ist. Wird diese Fläche im 3-dimensionalen Raum unter Beibehaltung der Einteilung in Dreiecke auf ihre gegebene Höhe „gezogen“, wird man einen Körper (in diesem Beispiel eine Landschaftsfläche) erhalten, der aus ein-zelnen Dreiecksflächen gebildet wurde und eine Nährung der Höhe an ei-nem beliebigen Punkt erlaubt. Das Bild 1 auf der nächsten Seite stellt eine solche Höheninterpolation dar. Es ist das Ergebnis der Delaunay-Triangulation in der Ebene zu erkennen. Die fett markierten Punkte in der Ebene stellen die gegebenen Punkte der Landschaftsoberfläche dar.

3.0 Delaunay-Triangulation Seite 10

Bild 1: Höhenprofil eines Bergkamms, der trianguliert wurde [2].

Sicherlich stellt sich jetzt die Frage, warum bei so einem Problem die De-launay-Triangulation verwenden werden sollte und nicht irgendeine ande-re. Das nächste Bild veranschaulicht, welche möglichen Fehler auftreten, wenn nicht die Delaunay-Triangulation verwendet wird.

Bild 2: Modell der Triangulation des Bergkamms von oben [2].

Die Abbildung zeigt den Verlauf eines Bergkamms. Dabei muss man sich

vorstellen, dass man von oben auf den Bergrücken schaut. Der Bergkamm

wird durch die senkrechte Line, die von oben nach unten verläuft,

3.0 Delaunay-Triangulation Seite 11

dargestellt. Wenn die Höhe des Punkte q gefragt ist, müssen nun die Hö-hen interpoliert werden. Der linke Teil in Bild 2 gibt eine realistische Aus-kunft von genau 985 Meter. Blickt man nun den rechten Teil der Abbildung an, erhält man den Wert 23 Meter, der eindeutig zu niedrig ist. Der Grund für dieses Ergebnis ist das Kriterium (siehe Kapitel 3.2.1.1), unter dem die Triangulation durchgeführt wurde. Die Triangulation im linken Teil wurde auf möglichst maximale Winkel (Max-Min-Winkelkriterium, siehe 3.2.1.1) durchgeführt. Der Fehler im rechten Teil entsteht durch Zulassen von sehr kleinen, spitzen Winkel. Eine wichtige Eigenschaft der Delaunay-Triangulation ist, dass sie den minimalen Winkel in einem Dreieck opti-miert. Damit wird der minimale Winkel möglichst groß und somit werden spitze Dreiecke vermieden. Bei der Delaunay-Triangulation wird das soge-nannte Max-Min-Winkelkriterium benutzt.

Die Delaunay-Triangulation ist dafür bekannt wohlgeformte Dreiecke (es werden spitzwinklige Dreiecke vermieden) zu erzeugen, d. h. es wird an-gestrebt die Bildung von langen, dünnen Dreiecken zu vermeiden. Die re-sultierenden Dreiecke überlappen sich nicht und vermaschen eine beliebig große Punktmenge flächendeckend und eindeutig. Die Delaunay-Triangulation ist die zum Voronoi-Diagramm, auch als Dirichlet-Tesselation (Parkettierung) bezeichnete, duale1 Struktur (Der Exkurs Voronoi-Diagramme ist in Kapitel 4 zu finden).

1 Dual: Zu einen zusammenhängenden, ebenen Graphen ist der duale Graph G* derjeni-

ge Graph, dessen Ecken in den Flächen von G liegen und dessen Kanten wie folgt be-

stimmt sind: Ist e eine Kante von G mit Fläche X auf der einen und Fläche Y auf der an-

deren Seite, so sind die Ecken X*, Y* (X* liegt in der Fläche X und Y* liegt in der Fläche

Y) von G* durch eine Kante e* verbunden. (Siehe Bild 38 und Kapitel 4).

3.0 Delaunay-Triangulation Seite 12

3.1.4 Verwendung der Delaunay-Triangulation

Sie wird verwendet zur Darstellung von Landschaftsbilder, Spielen, Anima-tionen (Filme), menschlichen Körperansichten und bei CAD-Programmen und Lasertechnik, usw.

3.1.5 Bedingungen für eine Delaunay-Triangulation

Siehe 2.5.

3.2 Der inkrementelle Algorithmus

3.2.1 Voraussetzungen

Die Nachbarschaft einer Kante wird von maximal zwei Dreiecken gebildet. Randkanten haben nur ein Nachbardreieck (Das Dreieck, welches die Kan-te besitzt).

Definition: Wenn ein Dreieck die Kante eines anderen Dreiecks besitzt, bezeichnet man das als eine Nachbarschaft. Demnach besitzt ein Dreieck maximal drei Nachbardreiecke.

3.2.1.1 Kriterien beim Triangulieren

Bei einer Triangulation von vier Punkten gibt es bereits mehr als ein Drei-eck und die Triangulation ist nicht eindeutig. Dabei ist bereits für diesen einfachen Fall eine Technik zur Auswahl der geeigneten Triangulation not-wendig. (Notation a() bezeichnet ein Winkelmaß. Siehe 2.4). In diesem Abschnitt wird immer von vier Punkten ausgegangen, die trianguliert wer-den sollen.

● Kriterium der kürzeren Diagonalen

3.0 Delaunay-Triangulation Seite 13

Eine Triangulation T von vier Punkten heißt bessere Triangulation als T' genau dann, wenn gilt d < d', wobei d die Länge der Diagonalen DT der Triangulation T und d' die Länge der Diagonalen DT’ der Trian-gulierung T' bezeichnet.

Dieses Kriterium ist nicht in der Lage die Erzeugung langer, dünner, also spitzer, Dreiecke zu vermeiden. In der Charakteranimation wie auch in der FEM (Finite-Element-Methode) ist man bestrebt, kleine Winkel zu vermeiden, um „wohlgeformte" Dreiecke (s. Kap. 2.5) zu erhalten.

● Max-Min-Winkelkriterium: der kleinste vorkommende Dreieckswinkel wird maximiert

Eine Triangulation T von vier Punkten heißt bessere Triangulation als T' genau dann, wenn gilt a(T) > a(T') mit a(T) = min{a(Tj) | Tj ∈ T}, wobei a(Tj) den kleinsten Winkel im Dreieck Tj bezeichnet.

Es ist das Kriterium des größten, kleinsten Winkels und vermeidet lange, spitze Dreiecke. Es liefert stets für vier Punkte eine eindeutige Entscheidung. Es gilt als nicht allgemein, wenn von vier Punkten drei Punkte kollinear sind. Es existiert dann in diesem Fall ohnehin nur eine gültige Triangulierung (siehe folgenden Abschnitt).

● Min-Max-Winkelkriterium: der größte vorkommende Dreieckswinkel wird minimiert

Eine Triangulation T von vier Punkten heißt bessere Triangulation als T' genau dann, wenn gilt a(T) < a(T') mit a(T) = min{a(Tj) | Tj ∈T}, wobei a(Tj) den größten Winkel im Dreieck Tj bezeichnet.

Finite-Element-Methoden approximieren, basierend auf einer endli-

chen Zahl von Dreiecksflächensegmenten, eine Funktion und erlau-

ben das dynamische Verhalten von Objekten zu simulieren. Es wer-

den beispielsweise das Verformungsverhalten von Automobilkarosse-

rien oder thermodynamische Vorgänge in Turbinen und Verbren-

nungsmotoren simuliert. Die Konvergenz dieser Verfahren und damit

die Fehlerabschätzung hängen nicht allein von der Größe des kleins-

ten Winkels ab. Zu große Winkel sind ebenfalls ungünstig.

3.0 Delaunay-Triangulation Seite 14

BERN und EPPSTEIN (vgl. [3] und [4]) weisen auf Arbeiten hin, in denen theoretisch dargelegt wird, wie sich die Konvergenz der FEM bei Auftreten großer Dreieckswinkel verschlechtert. Statt den kleins-ten Winkel zu maximieren, minimiert das Min-Max-Winkelkriterium daher den größten Winkel (Häufig führen das Max-Min- und das Min-Max-Winkelkriterium zur gleichen Triangulierung. Vergleichende Tests mit Zufalls-Punktmengen zeigten Abweichungen in nur ca. 10 % der Fälle. Durch diese Methode wird eine lokale Optimalität er-reicht, die die globale Optimalität nicht mit einbezieht. Siehe Kapitel 3.2.1.4).

Weitere Kriterien, die kurz vorgestellt werden:

● Max-Min-Radiuskriterium

Maximiere für die Triangulation von vier Punkten den kleinsten Radi-us, der Kreise, die in die beiden angrenzenden Dreiecke einbeschrie-benen sind.

● Min-Max-Radiuskriterium

Minimiere für die Triangulation von vier Punkten den größten Radius, der Kreise, die in die beiden angrenzenden Dreiecke einbeschriebe-nen sind.

● Max-Min-Flächenkriterium

Maximiere bei der Triangulation von vier Punkten den kleinsten Flä-cheninhalt der beiden Dreiecke.

● Max-Min-Höhenkriterium

Maximiere für die Triangulation von vier Punkten die kleinste Höhe in beiden Dreiecken.

3.0 Delaunay-Triangulation Seite 15

● Minimale Summe der Kantenlängen

Minimiere die Summe der Längen der fünf Kanten der vier Punkte (minimum weight triangulation oder minimum length triangulation). Dies ist ein einfaches Maß für die Größe der Dreiecke.

Beispiele:

Bild 3: Oben Kriterium der kürzeren Diagonalen, in der Mitte Max-Min-Winkelkriterium

und unten Max-Min-Radiuskriterium [6]

3.0 Delaunay-Triangulation Seite 16

Bild 4: Triangulation nach Min-Max-Kriterium. Lokal optimal, da a(T2) < a(T1). Jedoch ist

es nicht global optimal. Deshalb ist eine bessere Triangulation möglich [8].

Das Max-Min-Winkelkriterium ist das einzige bekannte Kriterium, für das alle lokalen Optima stets auch globale Optima sind, da der Algorithmus stets das lokale Optimum (Siehe 3.2.1.4) durch das Umkreiskriterium (Siehe 3.2.1.3) einhält.

3.2.1.2 Fälle bei der Triangulierung von vier Punkten

Definition (Lokal optimale Triangulierung): Eine Triangulierung T heißt lokal optimal bzgl. eines Kriteriums K genau dann, wenn jedes Viereck in T, das von zwei Dreiecken gebildet wird, die sich eine Kante teilen, optimal trianguliert ist bzgl. K.

3.2.1.2.1 Erster Fall

Man betrachte nun - als lokalen Fall - die Triangulation einer Menge von vier Punkten, die ein konvexes Viereck bilden. Das heißt, dass Viereck ist identisch mit der konvexen Hülle seiner vier Eckpunkte. Außerdem sind die Punkte nicht kollinear. Dann ist die Triangulierung nicht eindeutig. Es gibt zwei Möglichkeiten (siehe Bild 5).

3.0 Delaunay-Triangulation Seite 17

Bild 5: Allgemeiner Fall der Triangulierung von vier Punkten. Alle vier Punkte bilden die

konvexe Hülle.

3.2.1.2.2 Zweiter Fall

Die Bedingung des konvexen Vierecks bedeutet (Erster Fall), dass sich alle Punkte ausschließlich auf dem Rand der konvexen Hülle befinden. Befindet sich einer der Punkte innerhalb der konvexen Hülle, dann gibt es nur eine mögliche Triangulierung bei der drei Dreiecke entstehen (siehe Bild 6).

Bild 6: Ein Punkt liegt nicht auf dem Rand.

3.2.1.2.3 Dritter Fall

Sind drei Punkte kollinear, dann ist ebenfalls nur eine Triangulierung mög-lich und es entstehen zwei Dreiecke (Bild 7).

3.0 Delaunay Triangulation Seite 18

Bild 7: Drei Punkte liegen auf einer Linie.

3.2.1.3 Das Umkreiskriterium

Hierbei wird zu einem Dreieck ein weiterer Punkt hinzugefügt. Durch das bekannte Dreieck kann der Umkreis des Dreiecks errechnet werden. Nun muss ermittelt werden, ob der neue Punkt innerhalb oder außerhalb des Umkreises liegt. Sobald er außerhalb liegt, wird der Punkt mit den nächs-ten zwei Eckpunkten des Dreiecks durch Kanten verbunden. Wenn er in-nerhalb liegt, wird er auch mit den nächsten zwei Eckpunkten verbunden. Jedoch wird zusätzlich die Diagonale des entstanden Vierecks vertauscht (siehe Bild 8), damit der eingefügte Punkte nicht im Umkreis liegt.

Die lokale Eigenschaft „das Innere eines Umkreises jedes Dreiecks enthält

keine weiteren Punkte“ (Siehe Abb. unten) ist äquivalent zum Max-Min-

Winkelkriterium und ein Verstoß dagegen lässt sich durch Diagonalen-

tausch (Edge flip) aufheben. Das lokale Umkreiskriterium zur Triangulie-

rung von jeweils vier Punkten impliziert das globale Umkreiskriterium für

große Punktmengen. Bei dem für sämtliche Dreiecke der Triangulierung

gelten muss, dass ihr jeweiliger Umkreis keine weiteren Punkte aus der

Punktmenge P beinhalten darf.

3.0 Delaunay-Triangulation Seite 19

Bild 8: Umkreiskriterium. Links im Bild wird das Umkreiskriterium verletzt. Durch Diago-

nalentausch (edge flip) wird rechts eine gültige Triangulierung erreicht. Es genügt eines

der beiden Dreiecke zu überprüfen. Das Umkreiskriterium verhält sich in beiden Fällen

äquivalent.

Dieses einfache Kriterium ersetzt somit das Max-Min-Winkelkriterium ab Kapitel 3.2.1.5. Im nächsten Kapitel wird das Max-Min-Winkelkriterium allerdings noch benötigt.

3.2.1.4 Optimale Triangulation

Mit Hilfe der für Vierecke eingeführten Entscheidungskriterien aus 3.2.1.2 können auch größere Punktmengen trianguliert werden. Man beginnt bei einer Triangulation mit einem Dreieck und nimmt jeweils einen Punkt hin-zu. Damit kann eine optimale Triangulierung erzeugt werden. Dabei stellt sich die Frage, welches Kriterium aus einem lokalen Optimum ein globales Optimum erzeugt?

Definition: Eine Triangulation heißt global optimal bzgl. eines Kriteriums K genau dann, wenn jedes Viereck, definiert - durch je zwei entlang ihrer Kanten aneinander anschließenden Dreiecke von T - optimal trianguliert ist bzgl. K.

Problem: Es können dabei verschiedene lokal optimale Triangulierungen entstehen (siehe Bild 9). Das ganze ist abhängig von der Reihenfolge.

3.0 Delaunay-Triangulation Seite 20

Bild 9: Zwei lokal optimale Triangulierungen. Beide sind bzgl. Min-Max-Winkelkriterium

optimal.

Hierzu werden die lokalen Maße des betrachteten Kriteriums für alle Drei-ecke der Triangulation T in einem lexikographisch sortierten Vektor zu-sammengefasst und die Vektoren lexikographisch verglichen. Für jede Tri-angulierung T der Punktmenge P mit m Dreiecken wird ein Vektor a(T) = (a1,…, am) durch das lokale Entscheidungskriterium aufgestellt, bei dem die Komponenten ai = ai (Tj) der Größe nach sortiert werden. Wenn z. B. beim Min-Max-Winkelkriterium nun M Dreiecke entstehen, sind 3*m Win-kel vorhanden, die sortiert werden müssen. Nun wird jede Triangulation, die durch das Min-Max-Winkelkriterium erzeugt wurde, miteinander vergli-chen. Dadurch wird die beste Triangulation ermittelt. Denn eine Triangula-tion T gilt als global optimal, falls keine von T verschiedene Triangulation T' existiert, deren Vektor kleiner (minimierendes Kriterium) oder größer (maximierendes Kriterium) ist.

Definition: Eine Triangulierung T einer Punktmenge P heißt global optimal bzgl. eines Kriteriums K genau dann, wenn mit dem obigen Vektormaß a(T) gilt: a(T) >= a(T') (bzw. <=) für jede Triangulierung T' von P gilt.

Anmerkung: Die global optimale Triangulation ist, bis auf Änderungen, die das Optimalitätsmaß a(T) konstant halten (neutrale Fälle), eindeutig. Ist eine Triangulation global optimal, so ist sie auch lokal optimal. Umge-kehrt ergibt nur das Max-Min-Winkelkriterium aus einer lokal optimalen Triangulation zwingend eine global optimale Triangulation und somit wird das lexikographische Vergleichen der verschiedenen Triangulationen ande-rer Kriterien hinfällig, da es beim Max-Min-Winkelkriterium nur eine Trian-gulation gibt. Lokal optimale Triangulation bezüglich anderer lokaler Ent-scheidungskriterien (Min-Max-Winkelkriterium oder minimales Verhältnis von Umkreis- und Dreiecksflächen) sind oft weit entfernt vom globalen Optimum. Hoschek (vgl. [8], S. 324) zeigt, dass das Max-Min-Winkelkriterium das einzige bekannte Kriterium ist, bei welchem stets lo-kale Optima auch globale Optima sind. Die mit dem Max-Min-Winkelkriterium erzeugte Triangulierung ist äquivalent zur Delaunay-Triangulierung und somit genau die richtige.

3.0 Delaunay-Triangulation Seite 21

3.2.2 Der inkrementelle Algorithmus

1. Als erstes werden drei neue Punkte eingefügt mit denen ein Startdrei-eck aufgebaut wird. Das Startdreieck soll alle Punkte in seiner Fläche beinhalten, die trianguliert werden sollen. Das Startdreieck initialisiert die Triangulation. Es ist sozusagen die Startinitialisierung.

2. Ein Punkt wird zu der bestehenden Triangulation eingefügt.

3. Feststellen der Dreiecke aus der bereits bestehenden

4. Entfernen dieser Dreiecke aus der bestehenden Triangulation,

5. Verbinden der Randpunkte der Umgebung (Fläche), in der der neue Punkt liegt. So entstehen die neuen Kanten und somit auch Dreiecke.

Zuerst muss das Startdreieck erzeugt werden. Die vier letzten obigen Punkte werden dann immer wieder abgearbeitet für alle Punkte, die trian-guliert werden sollen.

Nun die ersten fünf Punkte nochmals erläutert mit jeweils einem Bild.

Zu 1:

3.0 Delaunay-Triangulation Seite 22

Bild 10: Startdreieck

Es wird ein Startdreieck gebaut, das alle Punkte, die trianguliert werden sollen, in seiner Fläche enthält.

Zu 2:

Bild 11: Ein Punkt wird in die Triangulation eingefügt [5]

3.0 Delaunay-Triangulation Seite 23

Ein Punkt wird zu der bestehenden Triangulation eingefügt.

Zu 3 und 4:

Bild 12: Die Umkreise werden bestimmt [5]

Die Dreiecke, deren Umkreis den Punkt (der in die Triangulation aufge-nommen werden soll) enthalten, werden gelöscht.

Zu 5:

Bild 13: Neue Dreiecke entstehen [5]

3.0 Delaunay-Triangulation Seite 24

Es entstehen neue Dreiecke zwischen dem hinzugefügtem Punkt und den Ecken der Umgebung (Fläche), in der der Punkt liegt. Am Ende der Trian-gulation werden alle Dreiecke, die einen Punkt des Startdreiecks haben, gelöscht.

Pseudo-Code

for each sample point in the vertex list initialize the edge buffer

for each triangle currently in the triangle list

calculate the triangle circumcircle center and radius

if the point lies in the triangle circumcircle then

add the three triangle edges to the edge buffer

remove the triangle from the triangle list

endif

endfor

delete all doubly specified edges from the edge buffer

this leaves the edges of the enclosing polygon only

add to the triangle list all triangles formed between the point

and the edges of the enclosing polygon

endfor

remove any triangles from the triangle list that use the supertriangle ver-tices

remove the supertriangle vertices from the vertex list

end

Wie zu sehen ist, ist dies nur der Algorithmus für eine Triangulation ohne das Herausnehmen der Löcher oder das Einhalten des Randes. Das wird noch ergänzt (siehe Kapitel 7 und 3.4).

3.0 Delaunay-Triangulation Seite 25

3.2.2.1 Ergebnisse des Algorithmus

Graphentheoretisch stellt die Triangulation einen planaren (Def. siehe 2.5), zusammenhängenden Graph dar, der die konvexe Hülle der Punktmenge vollständig umschließt.

Wenn jeder Punkt in die Triangulation aufgenommen wurde, gibt es einen Zusammenhang. Die Anzahl der Dreiecke ist etwa gleich groß wie die An-zahl der Außenkanten, da die Delaunay-Triangulation ein planarer Graph ist. Nun der Beweis:

Voraussetzungen

P habe n Außenkanten

t entspricht der gesuchten Zahl der Dreiecke

Beweis

Lemma Eulersche Polyederformel

Der Satz besagt: Seien e die Anzahl der Ecken, f die Anzahl der Flächen und k die Anzahl der Kanten eines konvexen Polyeders. Dann gilt:

e + f − k = 2

In Worten bedeutet, dass: Anzahl der Ecken plus Anzahl der Flächen mi-

nus Anzahl der Kanten gleich zwei.

Bei der Triangulation gehört jede Innenkante zu genau 2 Dreiecken und jede der n Außenkanten zu einem Dreieck ⇒ Gesamt-Kantenzahl k = (3t + n)/2 (Jedes Dreieck besitzt drei Kanten. Addiert mit den Außenkanten und dividiert durch 2, da alle Kanten doppelt gezählt wurden). Die Euler-sche Polyederformel beschreibt eine Eigenschaft von konvexen Polyedern, die auch bei planaren Graphen gilt. Für k setzt man (3t + n)/2 ein. Für e wird die Zahl der Außenkanten n eingesetzt und f wird durch t + 1 (Anzahl der Dreiecke und ein Außengebiet) ersetzt:

e – k + f = 2 ⇒ n – (3t+n)/2 + t + 1 = 2 ⇒ t = n – 2 ⇒ die Zahl der Dreiecke liegt fest.

Die Formel gilt nur, wenn P keine Löcher hat und der Rand konvex ist. Wenn es Punkte gibt, die kollinear auf dem Rand liegen, müssen diese kol-

3.0 Delaunay-Triangulation Seite 26

linearen Punkte abzogen werden. Also würde das Ergebnis n – 2 – (Anzahl der kollinearen Punkte) lauten.

3.3 Mathematische Grundlagen

3.3.1 Konvexe und nichtkonvexe Hüllen

3.3.1.1 Definition

Als konvex (lat.: convexus gewölbt, gerundet) bezeichnet man Formen (Flächenteile, Linien), die nach außen gewölbt sind.

Definition siehe 2.5.

Bild 14: Links ist eine konvexe Hülle und rechts eine nichtkonvexe Hülle

3.0 Delaunay-Triangulation Seite 27

Konvexe Hülle

Definition siehe 2.5

Bild 15: Konvexe Hülle

Als nichtkonvex bezeichnet man Formen, die nach innen gewölbt sind.

Definition siehe 2.5

3.3.2 Flächeninhalt von Dreiecken

Wenn man eine Dreiecksfläche berechnen möchte und man gegen den Uhrzeigersinn das Dreieck durchläuft, kann man die Punkte markieren mit z. B. (siehe Bild 16) P0, P1 und P2 und bekommt die Koordinaten x0 und y0 für P0, x1 und y1 für P1, x2 und y2 für P2.

3.3.2.1 Berechnung

Durch die Hälfte der Determinante von

3.0 Delaunay-Triangulation Seite 28

22

11

0 0

y x 1

y x 1

y x 1

kann der Flächeninhalt der drei Punkte bestimmt werden. Als Lösung, wenn die Determinante ausgerechnet wird, erhält man (x1 * y2 + x2 * y0 + x0 * y1 - x2 * y1 - x0 * y2 - x1 * y0)*0.5. Die Ergebnisse können negativ und positiv sein. Wenn die Durchlaufrichtung im Uhrzeigersinn ist, sind die Ergebnisse negativ und mit (-1) zu multiplizieren. Die Ergebnisse bei die-ser Berechnung gegen den Uhrzeigersinn sind positiv. Das Ergebnis hängt also von der Orientierung der Punkte ab.

Ein anderer Rechenweg wäre über das Kreuzprodukt (auch: Vektorprodukt genannt). Die Rechnung lautet dort: 0.5 * |a x b|

Bild 16: Dreieck

3.0 Delaunay-Triangulation Seite 29

3.3.3 Kreis mit 3 Punkten erzeugen

Für das Umkreiskriterium wird diese Rechung benötigt, da immer wieder ausgerechnet werden muss, ob der Punkt, welcher zu der Triangulation hinzugefügt werden soll, im Umkreis der Dreiecke ist, die bereits durch die Triangulation entstanden sind.

3.3.3.1 Berechnung

Bild 17: Kreis mit drei Punkten aufziehen, die auf dem Kreis liegen.

Wie auf dem Bild oben zu sehen, ist der Kreismittelpunkt relativ einfach zu berechnen. Als erstes muss die Steigung ma der Geraden a zwischen den Punkten P1, P2 und die Steigung mb der Geraden b zwischen den Punkten P2, P3 ermittelt werden. Die Punkte haben die Koordinaten x1 und y1 für P1, x2 und y2 für P2 und x3 und y3 für P3.

ma = (y2 – y1) / (x2 - x1)

mb = (y3 - y2) / (x3 – x2)

Diese beiden Steigungen (ma und mb) müssen negiert und davon der Kehr-wert genommen werden, da die Steigung der Geraden ya und yb. (im Bild 17 sind die Indices groß geschrieben) lotrecht/senkrecht sind zu den Stei-gungen ma und mb.

-1/ma = -(x2 - x1) / (y2 – y1) (Steigung der Geraden a im Bild 17)

3.0 Delaunay-Triangulation Seite 30

-1/mb = -(x3 – x2) / (y3 - y2) (Steigung der Geraden b im Bild 17)

Nun wird der Kreismittelpunkt berechnet. Dazu wurden die beiden Glei-chungen ya und yb der Geraden aufgestellt. Diese erhält man, da die Ge-raden, die Steigungen von oben besitzen und die neuen Geraden ya und yb durch die Mittelpunkte der Geraden zwischen den Punkten P1 und P2 bzw. P2 und P3 gehen. So das x verschoben ist, um den Mittelpunkt der Gera-den zwischen den Punkten P1 und P2 bzw. P2 und P3. Der y-Achsenabschnitt ist der Mittelpunkt der Geraden zwischen den Punkten P1 und P2 bzw. P2 und P3.

ya = -1/ma (x – (x1 + x2)/2) + (y1 + y2)/2

yb = -1/mb (x – (x2 + x3)/2) + (y2 + y3)/2

Die beiden Gleichungen ya und yb werden für y (ya = yb) gleichgesetzt und nach x aufgelöst. xc (der x-Wert des Kreismittelpunktes) wird somit er-rechnet. Heraus kommt, nach einigem Umformen, die Gleichung:

Dann wird die Lösung xc für x entweder in die Gleichung ya oder yb einge-setzt, um yc (der y-Wert des Kreismittelpunktes) zu berechnen.

Der Radius wird in folgender Weise berechnet.

dx = x2 – xc

dy = y2 - yc

rsqr = √(dx * dx + dy * dy)

3.0 Delaunay-Triangulation Seite 31

3.3.3.2 Punkt im Kreis

Da man den Kreisradius kennt durch die Berechung in 3.3.3.1, kann ein Punkt P darin unterschieden werden, ob dieser im Kreis ist oder nicht. Dazu muss nur verglichen werden, wie groß der Abstand zwischen P (Mit den Punkten (Px/Py)) und Kreismittelpunkt Mk (Mit den Punkten (Mkx/Mky)) ist.

dx = Px – Mkx

dy = Py – Mky

drsqr = √(dx * dx + dy * dy)

Ist der Abstand drsqr kleiner wie der Radius rsqr (aus dem Abschnitt vorher) liegt der Punkt im Kreis. Bei gleichen Werten liegt er auf dem Kreisrand, und ist der Abstand größer liegt der Punkt außerhalb des Kreises.

3.3.4 Berechnung eines Kreisbogens

3.3.4.1 Analytische Lösung

Auf diese Berechnung wird im gesamten Algorithmus immer wieder zu-rückgegriffen, wenn z. B. Kreisbögen oder Bohrlöcher ins Spiel kommen. Deshalb wird kurz vorgestellt wie man Kreisbögen berechnet. Dazu benö-tigt man nur den Startwinkel des Kreisbogen im Bogenmaß (bei welchem Bogenmaß der Kreisbogen beginnt. 0 für 0°, PI/2 für 90°, PI für 180° usw.), Endwinkel des Kreisbogen im Bogenmaß (bei welchem Bogenmaß der Kreisbogen endet), Radius des Kreisbogen, Kreismittelpunkt des Kreisbogen und die Auflösung, das heißt mit wie vielen Punkten der Kreis aufgespannt werden soll. Der Gesamtwinkel ist nichts weiter als Endwinkel minus Startwinkel. Dieser wird einfach durch die Anzahl der Punkte, die den Kreis aufziehen sollen, dividiert und man erhält den Wert, der in die Variable „resolution“ geschrieben wird. In einer For-Schleife, welche von Start- zum Endwinkel läuft und immer um den Wert resolution erhöht wird, werden die Kreisbogenpunkte durch die zwei Formeln auf der nächs-ten Seite berechnet:

3.0 Delaunay-Triangulation Seite 32

arcs.Centre.x + radius * Math.Cos(alpha) die den x-Wert und

arcs.Centre.x + radius * Math.Sin(alpha) die den y-Wert berechnet.

Alpha hat herbei denselben Wert wie der Gesamtwinkel.

3.4 Sonderfälle

Sonderfälle sind Probleme, die nicht durch die Delaunay-Triangulation ge-löst werden, jedoch so wichtig sind, dass sie analysiert und gelöst werden müssen.

3.4.1 Nichtkonvexe Hülle

3.4.1.1 Einleitung und Idee

Die Definition konvexer und auch nichtkonvexer Hüllen kann man in 2.5 und 3.3.1.1 nachlesen. Ein Objekt, welches trianguliert werden soll, kann auch eine nichtkonvexe Hülle besitzen. Es muss ein Weg gefunden wer-den, der diese nichtkonvexen Stellen finden kann, da das Ergebnis der Tri-angulation eine konvexe Hülle ist. Dazu sollte erst mal erklärt werden, woran sich konvexe und nichtkonvexe Stellen unterscheiden. Wie in der Definition beschrieben, sind konvexe Stellen nach außen gewölbt. Wäh-rend nichtkonvexe nach innen gewölbte Stellen sind. Alle Stellen bestehen aus Dreiecken und deshalb kann man 3.3.2 benutzen. Denn konvexe Hül-len haben ein positives Ergebnis beim Berechnen des Flächeninhalt der einzelnen Dreiecke und nichtkonvexe ein negatives, da bei einer konvexen Stelle die Durchlaufrichtung gegen und bei einer nichtkonvexen Stelle die Durchlaufrichtung mit dem Uhrzeigersinn (siehe Bild 18) ist.

Der nächste Punkt ist immer der Nachbar und damit kann dies genutzt werden. Das ist so, weil die Punkte, die man bekommt, gegen den Uhrzei-gersinn sortiert sind.

3.0 Delaunay-Triangulation Seite 33

Bild 18: Links nichtkonvexe und rechts konvexe Stellen

Es gibt ganze Seitenteile, die nichtkonvexe seien können (Siehe Bild 19).

Bild 19: Nichtkonvexe Hülle. Schwarz der eigentliche Rand und grün die Dreiecke, die

entfernt werden müssen.

3.0 Delaunay-Triangulation Seite 34

Wie auf Bild 19 zu sehen, sind die nichtkonvexen Stellen einfach nach in-nen gewölbte Dreiecke. Die durch 3.3.2 unterscheidbar von nach außen gewölbten Dreiecken, also konvexen, sind. In 3.3.2 wird der Flächeninhalt von Dreiecken durch das halbe Vektorprodukt berechnet und das Ergebnis ist positiv, wenn die Durchlaufrichtung gegen den Uhrzeigersinn und das Dreieck konvex ist. Bei einem nichtkonvexen Dreieck, ist das Ergebnis ne-gativ. Wichtig ist auch, dass die Punkte gegen den Uhrzeigersinn gespei-chert sind.

Man muss also nur den Rand durchgehen und sich alle Dreiecke merken, welche einen Flächeninhalt kleiner Null besitzen und diese dann löschen.

3.4.2 Darstellung von Löchern

3.4.2.1 Einleitung und Idee

In diesem Abschnitt wird der Sachverhalt ausgenutzt, dass mehrere lokale Triangulationen eine globale ergeben. In der XML-Datei sind diese Punkte gesondert als Innenkonturen (inner contours) gespeichert. Die Punkte der Bohrlöcher werden ans Ende zu den anderen Punkte (Randpunkte der Scheibe), die trianguliert werden müssen, angehängt. Dann werden alle Punkte trianguliert und das Ergebnis sieht folgendermaßen aus:

3.0 Delaunay-Triangulation Seite 35

Bild 20: Viereck mit Löchern

Wie man sieht, sind die Löcher durch Dreiecke aufgezogen, welche nicht nach außen ragen. Also muss man nun einfach alle Dreiecke löschen, de-ren Punkte einen höheren Indexwert haben als die Randpunkte (Indexwert siehe 2.5). Dabei dürfen aber die Dreiecke zwischen den Bohrlöchern nicht gelöscht werden.

Im Kapitel 7 wird das Thema ausführlicher behandelt.

4.0 Exkurs Voronoi-Diagramm Seite 36

4.0 Exkurs Voronoi-Diagramm

Wenn von der Delaunay-Triangulation gesprochen wird, fällt immer wieder ein Name, der hier kurz erläutert werden soll, da es durch aus interessant ist, was sich dahinter verbirgt.

4.1 Das Postamtproblem

Das Voronoi-Diagramm2 befasst sich unter anderem mit dem Problem, welchen Einzugsbereich Postämter haben. Wenn sich z. B. ein Kunde fragt, welches Postamt für ihn liegt am nächsten? Es sind also Entfernungs- und Aufteilungssprobleme, die damit bearbeitet werden können. Ein Voronoi-Diagramm unterteilt eine Ebene mit Punkten in Regionen auf. Das Voro-noi-Diagramm ist auch eine Struktur zur Speicherung von Mengen von Punkten, die sich auf Nachbarschaftsanfragen stützen.

2 Die Voronoi-Diagramme erhielten ihren Namen von dem Mathematiker M. G. Voronoi,

der diese geometrische Konstruktion 1908 entdeckte. G. L. Dirichlet kannte dieses Prob-

lem bereits 1850, weshalb das Voronoi-Diagramm manchmal auch Dirichlet Tesselation

genannt wird. Voronoi-Diagramme sind wichtige Konstruktionen, die durch Gitter definiert

werden. Sie sind weit verbreitet in der Wissenschaft und werden auf den unterschied-

lichsten Gebieten eingesetzt. Oft wurden sie nach der Person benannt, die sie als erstes

in einem spezifischen Fachgebiet einsetzten. In der Meteorologie sind sie als Thiessen

Polygone bekannt, um Polygone zu definieren, in deren Mitte sich eine Wetterstation be-

findet. Die Voronoi-Diagramme sind zudem bekannt als Wigner-Seitz cells in der Metal-

lurgie oder als Blum's transform in der Biologie.

4.0 Exkurs Voronoi-Diagramm Seite 37

Bild 21: Gebietsaufteilung [6]

Bild 22: Begriffe des Voronoi-Diagramm [6]

In Bild 22 sind die Sprachkonventionen bei Voronoi-Diagrammen zu er-kennen.

4.2 Begriffe

Die wichtigsten Begriffe der Voronoi-Diagramme werden hier kurz erläu-tert.

4.0 Exkurs Voronoi-Diagramm Seite 38

Bild 23: Voronoi Knoten und Kanten [6]

1) Ein Voronoi-Knoten, der Mittelpunkt eines Kreises, (mittlerer blauer Punkt in Bild 15) definiert sich dadurch, dass der Umkreis des Kno-tens mindestens drei Punkte enthält, die die Postämter aus dem Bei-spiel (schwarze Punkte in Bild 15) darstellen sollen.

2) Am oberen blauen Punkt erkennt man eine Voronoi-Kante, die sich durch die Mittelsenkrechten der beiden Postämter (schwarzen Punk-te in Bild 15) ergibt.

3) Voronoi-Zellen besitzen die Eigenschaft, dass sie konvexe Polygone (die weiße Fläche zwischen den Kanten in Bild 15) sind.

4.0 Exkurs Voronoi-Diagramm Seite 39

Bild 24: Veranschaulichung der Dualität

Das Voronoi-Diagramm teilt eine Menge von Punkten (in der Ebene) in Gebiete ein. Dies wird erreicht durch Zeichnen der Mittelsenkrechten, die jede Seite des Dreiecks in der Mitte schneiden (siehe Bild 24). Diese Mit-telsenkrechten treffen sich im Mittelpunkt des Umkreises bzw. im Voronoi-Knoten. Die Delaunay-Triangulation der Punktmenge P ergibt sich dann als duale Struktur (siehe Fußnote Seite 10) des Voronoi-Diagramms und er-zeugt ein globales Optimum. Als nächstes einige Fälle, die beim Voronoi-Diagramm beachtet werden müssen.

4.3 Fälle bei der Voronoi-Konstruktion

4.3.1 Punkt im Umkreis

4.0 Exkurs Voronoi-Diagramm Seite 40

Bild 25: Punkt im Kreis

Die Dreiecke müssen nochmals berechnet werden. Die Umkreise der Drei-ecke dürfen mehr als drei Voronoi-Punkte enthalten, wobei der Voronoi-Knoten der Mittelpunkt des Umkreises ist (siehe Abschnitt vorher).

4.3.2 Weiterer Punkt im Dreieck selbst

Bild 26: Punkt im Dreieck

Bei einem weiteren Punkt im Dreieck entstehen drei neue Dreiecke. Also müssen diesmal neue Dreiecke im alten erzeugt werden. Das alte Dreieck fällt zudem weg, da es nun die drei neuen beinhaltet.

5.0 Fenster- und Glaseigenschaften Seite 41

5.0 Fenster- und Glaseigenschaften

Dieser Abschnitt ist wichtig für den Aufbau der Fensterscheibe und die Verwendung von Materialien, die in .net (Engl.: ausgesprochen dot net) 3.0 (Siehe Kapitel 6.2) zu Verfügung gestellt werden.

5.1 Fensteraufbau

Das Fenster besteht natürlich aus Fensterscheiben, einem Abstandhalter zwischen den Glasscheiben, der meist eine silbrig, glänzende Oberfläche besitzt. Ein schwarzer, matter Gummi liegt zwischen Scheibenrand und Abstandhalter. Bis jetzt werden 2-fach-ISO-Fenster animiert, d. h. der Auf-bau besitzt folgende Struktur:

Scheibe, Abstandhalter, Scheibe

Mehrfachisoliertes Glas (3-fach-ISO usw.) hat pro Scheibe, die es mehr enthält, noch einen Abstandhalter zwischen der neuen Scheibe und der, wo der Abstandhalter sonst noch aufliegt.

Bei Glas im Innenausbau und den ISO-Fenstern müssen Dinge wie Innen-ausschnitte und Bohrlöcher berücksichtigt werden. Türen oder Dekorati-onsglas sind auch mehr als dekoratives Element bedacht und bestehen aus einer oder mehreren Scheiben ohne Abstandhalter.

Außerdem kann Strukturglas vorkommen, d. h. die Vorder- und Rückseite der Glasscheibe ist z. B. aufgeraut.

5.0 Fenster- und Glaseigenschaften Seite 42

5.2 Eigenschaften von Glas

In diesem Abschnitt interessiert uns, welche Reflektions- und Refraktions-

eigenschaften Glas besitzt. Glas bricht einen Teil der Lichtstrahlen und re-

flektiert den anderen Teil. Wenn man durch Glas schaut, ist die andere

Seite um wenige Millimeter versetzt. Also wird das Licht gebrochen. Wird

jedoch auf Glasflächen geschaut, die viel Sonnenlicht reflektieren, sieht

man ein weiß-gelbes Glanzlicht. Das sind die reflektierten Sonnenstrahlen.

Am Übergang von Licht zwischen Luft und Glas kommt es abhängig vom

Einfallswinkel und der Glassorte zu einer Reflektion von ca. 4-9% des ein-

fallenden Lichts. Somit wird das restliche Sonnenlicht gebrochen. Diese

Eigenschaften sollten nachgebildet werden mit Hilfe des .net 3.0 und des-

sen WPF (Windows Presentation Foundation beschrieben in Kapitel

6.2.1.3). Durch das WPF kann man auf einige Materialarten zugreifen und

diese bei Verlangen unterschiedlich stark transparent erscheinen lassen.

5.2.1 Materialarten des WPF

Das WPF stellt einige Materialen zu Verfügung. Diese werden hier vorge-stellt.

5.2.1.1 Lambert Material

Das Lambert Material (auch diffuses Material genannt) eignet sich gut für matte Oberflächen. Es simuliert eine Art raue Oberfläche, welche die meis-ten Lichtstrahlen absorbiert und somit auch keine Glanzlichter (Specular Highlights) hat. Die Flächen erscheinen aus allen Richtungen betrachtet gleich hell, da sie das Licht mit gleicher Intensität in alle Richtungen gleichförmig reflektieren. Die Helligkeit eines Punktes hängt nur vom Win-kel zwischen der Richtung zur Lichtquelle und der Flächennormalen ab. Im WPF kann zudem noch die Transparenz (Opacity) eingestellt werden. Viele Materialen unserer Alltagswelt können gut mit diesem Material nachgebil-det werden, z. B. Papier, Holz usw.

5.0 Fenster- und Glaseigenschaften Seite 43

Bild 27: Lambert Material

5.2.1.2 Emissives Material

Die Eigenschaft "Emissive" gibt die Farbe an, die ein Objekt von Natur aus emittiert, unabhängig von dem Licht, welches auf das Objekt fällt. Diese Eigenschaft ist auch dann wichtig, wenn es kein Licht gibt. Sie lässt ein Objekt glühend erscheinen. Ein Objekt strahlt durch diese Eigenschaft je-doch selbst kein Licht aus. Benachbarte Objekte werden dadurch nicht heller dargestellt. Hier kann ebenfalls die Transparenz eingestellt werden. Lampen wären zum Beispiel mit einem solchen Material auszustatten.

Bild 28: Emissives Material

5.0 Fenster- und Glaseigenschaften Seite 44

5.2.1.3 Specular Material

Mit der Eigenschaft Specular (Glanzpunkte) kann ein Effekt berücksichtigt

werden, der in der Realität so oft vorkommt, dass er kaum noch wahrge-

nommen wird. Dieser Effekt entsteht durch Unregelmäßigkeiten in der O-

berflächenstruktur eines Materials und ist als heller Fleck auf der Oberflä-

che eines Objektes sichtbar. Denken wir an ein Bild mit einem Apfel. Der

Apfel selbst ist grün. Aber an der Stelle, an der besonders viel Licht auf

den Apfel fällt, erscheint ein heller Fleck. Wenn stattdessen eine Farbe

verwendet wird, die näher an der Farbe des dargestellten Objektes liegt,

erscheint der Fleck weniger hell. Solche Farbwerte werden häufiger zur

Darstellung von metallischen Gegenständen verwendet. Ansonsten werden

glänzende Materialien - wie zum Beispiel Kunststoffe - auf diese Weise gut

dargestellt. Auch hier kann optional eine Transparenz und dazu noch der

Wert SpecularPower, der angibt wie stark die Reflektion sein soll, einge-

stellt werden.

Bild 29: Specular Material

5.0 Fenster- und Glaseigenschaften Seite 45

5.2.2 Verwendung der Materialen

Im Fensteraufbau im Abschnitt 5.1 wurden die einzelnen Fensterteile be-schrieben, die animiert werden sollen. Das Lambert Material wird für die matten Oberflächen des Gummis benutzt. Das Glas erhält ein Emissives und ein Specular Material. Der Abstandhalter bekommt ein Specular Mate-rial.

6.0 Verwendete Programmiersprachen und Ressourcen Seite 46

6.0 Verwendete Programmiersprachen und Ressourcen

Dieser Abschnitt wird klären, was ein XML ist, was .net 3.0 und speziell WPF alles bieten und welche Programmiersprache benutzt wurde.

6.1 C# (CSharp)

C# ist eine rein, objektorientierte Programmiersprache, die der Software-hersteller Microsoft (MS) im Rahmen seiner .net-Strategie entwickelt hat und später als ein Standard von ECMA (European Computer Manufacturers

Association) und ISO akzeptiert wurde. Die Sprache zeigt deutliche paral-lelen zu Java und C++. Viele Konzepte der beiden Sprachen finden sich in C# wieder.

6.1.1 Unterschiede C++ und C#

6.1.1.1 Laufzeitumgebung

1) Sobald ein Objekt nicht länger benötigt wird, erfolgt das Löschen des Objektes über die Speicherbereinigung. Destruktoren (= Finali-sierungsroutinen) können nicht mehr im gleichen Umfang wie in C++ zur Durchführung von Bereinigungsaufgaben eingesetzt wer-den.

2) Es gibt nur noch Zeiger im unsafe-Modus. Diese werden jedoch sel-ten eingesetzt. Also existieren keine generellen Zeiger mehr. C# verwendet deshalb Verweise, die denen von C++ ähneln.

Der kompilierte Code (Ausgedrückt in der .net-Zwischensprache IL) und auch die Metadaten, die Beschreibungen des kompilierten Codes enthalten, werden in Assembler kompiliert. Die include-Dateien (.h Header Dateien) fallen weg, da alle .net-Sprachen über die Metada-ten die gleichen Informationen abfragen, wie sie die C++ .h-Dateien enthalten.

6.0 Verwendete Programmiersprachen und Ressourcen Seite 47

3) Das Aufrufen von systemeigenem Code ist etwas zeitaufwendiger.

4) Eine Ausnahmebehandlung (Exception) wird anstatt einer Fehler-rückgabe verwendet.

6.1.1.2 C#-Objekte

1) Nur eine Einfachvererbung von Klassen ist möglich, obwohl das Imp-lementieren von mehreren Schnittstellen zulässig ist, da C#-Objekte allesamt auf die Basisklasse Object zurückgehen.

2) In einer Struktur können sich kleine, schlanke Objekte befinden, die nicht dem Heap (wie Objekte), sondern einem Stack zugeordnet werden.

3) Objektboxing: Falls erforderlich ist dies bei C#-Strukturen und an-dere Wertetypen möglich (Einschließlich der integrierten Datenty-pen). Die Werte werden dann in einen Wrapper (Das Wrap ist die Hülle oder auch als Hüllenklasse bezeichnet) gepackt und in den Heap gelegt, um mit einem Objekt aus dem Heap kompatibel zu sein. Das vereinheitlicht das Typensystem und ermöglicht die Ver-wendung von Variablen als Objekte und zudem entsteht kein O-verhead, wenn eine Vereinheitlichung nicht erforderlich ist.

6.0 Verwendete Programmiersprachen und Ressourcen Seite 48

6.1.1.3 C#-Anweisungen

1) Das new-Schlüsselwort ist gleichzusetzen mit „Abrufen einer neuen Kopie von“ einem Objekt. Das Objekt wird dem Heap zugeordnet, wenn es sich um einen Verweistyp handelt. Es wird dem Stack oder intern zugeordnet, wenn es sich um einen Wertetyp oder eine Struk-tur handelt.

2) Keine automatische Konvertierung von int in bool, d. h. boolsche Bedingungen müssen auch boolsche Variablen sein.

3) Switch-Anweisungen reduzieren die Fehlerzahl, da Fehlschläge ver-hindert werden. Switch kann nun auch für Zeichenfolgen (String o-der Char) verwendet werden.

4) Zum Iterieren über die Elemente von Arrays, Zeichenfolgen oder anderen Collections bietet C# die von Visual Basic übernommene foreach-Schleife.

5) Über checked und unchecked werden arithmetische Operationen

und Konvertierungen auf einen Überlauf geprüft.

Beispiel (int besitzt Wertebereich von -2147483648 bis +2147483647):

int i = 2147483647, j = 5, k; k = checked(i + j); Es wird beim Überlauf nicht mit Zufallszahlen weitergerechnet, son-dern es wird ein Ausnahmefehler ausgelöst. Somit wird die Berech-nung nicht weiter fortgeführt.

6.0 Verwendete Programmiersprachen und Ressourcen Seite 49

6.1.2 Funktionen, die in C# nicht zu Verfügung, stehen

1) Mehrfachvererbung

2) Const-Mitgliedsfunktionen oder –Parameter. Const-Felder werden unterstützt.

3) Globale Variablen

4) Typedef. Es können nicht mehr Synonyme (oder andere Namen) für bestehende Datentypen gebildet werden.

6.2 .net 3.0

In diesem Abschnitt wird kurz das .net 3.0 erläutert und einige Objekte aus .net 3.0, die in der Software benutzt wurden. Das .net-Framework (Framework heißt nichts anderes als Ansammlung von Klassen) 3.0 bün-delt die Windows Presentation Foundation (WPF), Windows Communicati-on Foundation (WCF), Windows Workflow Foundation (WFF) und Windows CardSpace (WCS) alias InfoCard. Zusätzlich sind alle Komponenten aus .net 2.0 (einschließlich ASP.Net, WinForms und ADO.Net) enthalten.

6.2.1 Einführung in das .net 3.0

.net ist ein SDK (Software development kit) oder anders eine Plattform für aktuelle Programme, die für Programmiersprachen entwickelt wurden, die .net unterstützen (C# oder Visual Basic .net). Es ist eine Technologie, die verschiedene Betriebssystem-Funktionen zusammenfasst und an einem zentralen Punkt anbietet. Damit sollen veraltete Technologien und Vorge-hensweisen der Programmierer wie z.B. COM3 oder API4-Aufrufe im Pro-grammcode ersetzt

3 COM (Component Object Model) ist von Microsoft um Windows Klassen aus DLLs zu im-

portieren, damit Code wieder verwendet wird.

6.0 Verwendete Programmiersprachen und Ressourcen Seite 50

werden. Microsoft stellt diese Plattform als Umsetzung des Common-Language-Infrastructure-Standards5 (CLI) für Windows zu Verfügung.

6.2.1.2 Einige wichtige Objekte und Methoden

Einige Objekte wie die Materialtypen aus Kapitel 5.2.1 wurden bereits vor-gestellt. Das .net stellt jedoch bedeutend mehr zu Verfügung. In diesem Abschnitt werden einige Objekte und einige derer Funktionen beschrieben, die für die Umsetzung relevant waren.

6.2.1.2.1 Collection

In .net gibt es eine Vielzahl von Collection (ein Array für Objekte) für ver-schiedene Typen. Eine Point3DCollection sammelt Punkte (einzelne Punkte mit drei Koordinaten im .net sind vom Typ Point3D), die aus drei Koordina-ten bestehen. Für integer- und double-Werte stellt .nett eine int32Collection bzw. doubleCollection zu Verfügung. Eine PointCollection sammelt Objekte z. B. Punkte, die aus zwei Koordinaten bestehen.

Einige Methoden und Eigenschaften, die Collections immer besitzen:

- Add(Point3D) fügt der Collection einen Punkt am Ende der Collection hinzu.

- Insert(int, Point3D) fügt der Collection an einer bestimmten Stelle, die in dem int-Wert steht, einen Punkt hinzu.

- Remove(Point3D) löscht den Punkt aus einer Collection.

4 API (Application Programming Interface) ist eine Schnittstelle einer Software zu einer

anderen, um die eine an die andere anzubinden.

5 Die CLI ist ein ISO/IEC/ECMA Standard, der Systeme spezifiziert und somit die sprach-

und plattformneutrale Anwendungsentwicklung und -ausführung ermöglicht.

6.0 Verwendete Programmiersprachen und Ressourcen Seite 51

- RemoveAt(int) löscht den Punkt an der Stelle des integer-Wertes.

- Clone(): Die Werte einer Collection werden einer anderen übertragen.

Dabei sind beide Collection unterschiedliche Objekte im Heap, die nicht

manipulieren werden können. Mit Collection A = Collection B kann man

durch Collection B Collection A manipulieren. Wenn man Werte löscht oder

hinzufügt in Collection B, wird das bei Collection A ebenfalls getan und

umgekehrt. Es sind also die gleichen Objekte im Heap.

- Count() gibt an wie viele Objekte eine Collection besitzt.

Bei der Vector3DCollection, die Vektoren mit drei Koordinaten sammelt, kommen einige interessante mathematische Funktionen hinzu. Diese Col-lection vereinfacht die Normalenberechnung, falls man diese berechnen muss.

Methoden:

- AngleBetween(Vector3D, Vector3D): Winkel wird zwischen den beiden übergebenen Vektoren berechnet.

- CrossProduct(Vector3D, Vector3D): Kreuzprodukt wird zwischen den bei-den übergebenen Vektoren berechnet.

- Divide(Vector3D, double): Jede Vektorkomponente wird durch den doub-le Wert dividiert.

- UnaryNegation(Vector3D) negiert jede Vektorkomponente.

6.2.1.3 WPF

WPF dient zur Ausgabe von 2-D-/3-D-Grafiken, Video, Audio und Bildern.

Es setzt, im Gegensatz zu seinen Vorgängern GDI und GDI+, auf Directx

auf und bietet dadurch volle Hardwarebeschleunigung. WPF ist für die .net

Sprachen C# und Visual Basic (VB) verfügbar. Es wird mit der Markup-

Sprache XAML ausgeliefert. Die für das Entwerfen von Benutzeroberflä-

chen (Graphic User Interface (GUI)) eingeführt wurde. XAML basiert auf

6.0 Verwendete Programmiersprachen und Ressourcen Seite 52

XUL (User Interface Language), das zu erst für das Mozilla Projekt entwi-

ckelt wurde, jedoch nun auch von anderer Software genutzt wird. Zudem

entspricht XAML dem XML-Standard (Siehe 6.3) und ermöglicht es O-

berflä-chenelemente hierarchisch anzuordnen. Dadurch wird eine strikte

Trennung von Anwendungslogik und Oberflächendarstellung erreicht.

XAML ist aber nicht weiter wichtig für die Umsetzung.

6.2.1.3.1 Voraussetzung damit WPF einen 3-D Körper darstellt

Das Objekt MeshGeometry3D ist hierfür wichtig. Dieses Objekt besitzt fol-gende Werte, die wichtig waren:

1) Positions: eine Point3DCollection (sammelt Punkte mit drei Koordi-naten Werten)

2) TriangleIndices: eine int32Collection (sammelt Dreiecksindexe als int-Werte)

3) Normals: eine Vector3DCollection (sammelt Vektoren mit drei Ele-menten)

4) Textures: eine PointCollection (sammelt Punkte mit zwei Koordina-tenwerten)

Die letzten beiden Collections sind optional und die ersten beiden verbind-lich anzugeben. Der ersten Collection werden die Punkte mit den x, y, z Koordinaten übergeben, die z. B. das darzustellende Fenster besitzt.

Die zweite bekommt die Dreiecksindices, die dadurch resultieren wie der Delaunay-Alogrithmus das Dreiecksnetz erzeugt. Die Dreiecke müssen ge-gen den Uhrzeigersinn beschrieben werden, wenn die Vorderseite sichtbar sein soll. Sind die Indexe im Uhrzeigersinn, sieht man die Scheibe erst, wenn man von der Rückseite auf das Fenster schaut.

Die Indexe der Dreieckspunkte ergeben sich so:

Der erste Punkt, der in der Point3DCollection Position ist, hat den Index-wert 0, der zweite den Wert 1 usw. Die Normalen werden in der dritten

6.0 Verwendete Programmiersprachen und Ressourcen Seite 53

Collection aufbewahrt. Wenn die Normalen nicht berechnet werden, macht dies das WPF selbständig. Die Werte dienen der Beleuchtung (näheres da-zu im folgenden Abschnitt). Die Texturkoordinaten, die der letzte Collecti-on übergeben werden, werden im übernächsten Kapitel behandelt.

6.2.1.3.2 Normalen

Normalen sind Vektoren, die orthogonal von der Oberfläche stehen. Mit dem Kreuzprodukt von zwei Vektoren wird eine Normale berechnet. Dann sollte die Normale normiert werden, d. h. die Länge der Normale soll gleich eins sein. Das gelingt durch das ermitteln der Länge des Vektors, der durch das Vektorprodukt entstanden ist. Dann sollte man jede Vektor-komponente durch die ermittelte Länge dividieren.

Jedem Punkt (Vertex normal) kann beim WPF eine Normale übergeben werden. WPF rechnet intern mit den Normalen weiter. Die Normale gibt an, in welchem Winkel (hier: alpha) die Normale und der Lichtstrahl ste-hen (siehe Bild 30). Aus dem Skalarprodukt der normierten Normale (Face normal) multipliziert mit dem normierten Lichtvektor wird alpha berech-net, dessen Kosinus die Helligkeit bestimmt. Die 3-D-Oberfläche ist am hellsten, wenn das Licht koaxial (parallel) zur Normalen auftrifft.

Zeigt also die Normale in Richtung der Lichtquelle, soll die Farbe der Ober-fläche hell sein. Zeigt dieser weg, wird sie umso dunkler. Sind Normale und Lichtstrahl parallel und haben die gleiche Richtung, ergibt das Punkt-produkt 1 und somit volle Helligkeit. Stehen sie rechtwinkelig aufeinander, ist das Ergebnis 0 und zeigen sie entgegengesetzt ist es -1 (Siehe Bild 31).

Bild 30: Links: Oberfläche mit normierter Normalen; Rechts: Oberfläche mit Normalen

und Winkel alpha von [10]

6.0 Verwendete Programmiersprachen und Ressourcen Seite 54

Bild 31: Verhältnisse von alpha und der Helligkeit von [10]

Wie oben beschrieben besitzt ein Dreieck, da jeder Punkt eine Normale besitzt, drei Normalen. Wenn zwei oder mehr Dreiecke (wie z.B. an einer Pyramidenspitze) zusammenstoßen, kann man die am Punkt versammel-ten Normalen zu einer Durchschnittsnormalen mitteln, die die Helligkeit der Ecke recht gut wiedergibt.

6.2.1.3.3 Texture mapping

Um Oberflächen dreidimensionaler Modelle mit zweidimensionalen Bildern (Texturen) auszustatten (statt mit Material), gibt es das Verfahren der Musterabbildung (Texture mapping). Computergenerierte Bilder erschei-nen durch Texturen detailreicher und realistischer. Das zugrundeliegende Modell muss nicht verändert oder verfeinert werden. Bei Strukturglas wird auf die triangulierte Scheibe einfach ein Bild auf die Vorder- und Rückseite gelegt. Deshalb wird Texture mapping benötigt.

Für das Bestimmen eines Punktes in der Textur hat sich ein Koordinaten-system eingebürgert, in dem (0/0) die linke untere Ecke und (1/1) die rechte obere Ecke der Textur/des Bildes bezeichnet. Die beiden anderen Ecken sind dann folgerichtig (1/0) und (0/1). Die Koordinaten werden meist u und v genannt und sind Fließkommazahlen (double-Werte). Wenn der Zahlenwert einer Texturkoordinate unter 0 oder über 1 ist und sich somit unter bzw. über dem Rand der Textur befindet, wird die Textur wie-derholt.

6.0 Verwendete Programmiersprachen und Ressourcen Seite 55

Bild 32: Texturen

Wie auf dem Bild 32 zu erkennen, werden die relativen Texturkoordinaten einfach auf die Oberflächenpunkte der Modelle gelegt. So muss man bei der Berechnung die Oberflächenpunkte in x- und y-Richtung in Relation zu der Gesamtgröße des Modells in x- und y-Richtung angeben (Siehe hierzu 7.11). Aus den Oberflächenpunkten kann man somit die Texturkoordinaten berechnen.

Anmerkung: Bei WPF ist oben links (0/0) und unten rechts (1/1).

6.0 Verwendete Programmiersprachen und Ressourcen Seite 56

6.2.1.4 x-Datei

Bild 33: Eine x-Datei von [11]

Die Übergabeparameter des WPF gleichen denen aus Directx, wo es auch möglich ist 3-D-Objekte zu erstellen, in dem - relativ einfach - in einer x-Datei (Siehe Bild 33) Werte eingetragen werden. Directx setzt das ganze dann visuell in einen Fenster um. Es gibt Punkte (VertexBuffer im Bild ge-nannt) und Dreiecksindexe (IndexBuffer im Bild genannt). Texturkoordina-ten und Normalen können auch in die x-Datei geschrieben werden.

6.0 Verwendete Programmiersprachen und Ressourcen Seite 57

6.3 XML

In einem solchen Dateityp werden die Segmenttypen des Fensters, das zu triangulieren ist, gesichert. Wie Daten aus einer XML ausgelesen werden, wird in diesem Abschnitt besprochen.

6.3.1 Einleitung

XML (Extensible Markup Language) modelliert Daten in Form einer Baum-struktur, die vom World Wide Web Consortium (W3C) definiert wurde. Da-durch definiert XML Regeln für den Aufbau von Dokumenten, die Daten enthalten und die einer fest vorgegebenen Struktur entsprechen. Für je-den Fall bei dem XML angewendet wird ("XML-Anwendung"), müssen die Details der jeweiligen Dokumente spezifiziert werden. Dies trifft insbeson-dere die Festlegung der Elemente und ihre Anordnung innerhalb des Do-kumentenbaums zu. Eine Sprache wie XML zur Definition anderer Spra-chen nennt man Metasprache.

Das bedeutet, dass XML-Dateien sehr gut strukturierte Dateien sind. Sie können leicht von Programmen eingelesen werden. XML ist sehr weit ver-breitet. XHTML, RSS und das Dateiformat des neuen Microsoft Office 2007 sind nur einige populäre und auf XML basierende Dateiformate. Ein weite-rer Vorteil von XML ist seine Plattformunabhängigkeit. XML kann von Pro-grammen jedes Betriebssystems eingelesen werden.

6.3.2 Aufbau einer XML Datei

Wie bereits erwähnt, sind XML Dateien sehr gut strukturiert. XML Dateien bestehen aus einzelnen Elementen. Diese Elemente bestehen wiederum jeweils aus dem Start-Tag, dem Inhalt und dem End-Tag.

Beispiel:

<Benutzername>Robert</Benutzername>

Der rote Text ist das Start-Tag. Der Text zwischen spitzen Klammern ist der Name des Tags. Der grüne Text ist das End-Tag. Es ist gleich aufge-

6.0 Verwendete Programmiersprachen und Ressourcen Seite 58

baut wie das Start-Tag. Der einzige Unterschied ist das „/“-Zeichen nach der spitzen Klammer. Wichtig ist, dass der Text zwischen den Spitzen Klammern identisch zu dem Text des Start-Tags ist. Zwischen diesen bei-den Teilen ist der Name des Elements. In diesem Fall heißt es „Robert“.

Beispiel für ein falsches Element: <Benutzer>Simon</Benutzerrrrr>

Das ist falsch, da im End-Tag der Text (grün markiert) nicht dem Text des Start-Tags (rot markiert) entspricht.

Richtig wäre zum Beispiel dieses Element, da der Text im Start- und End-Tag gleich ist:

<Benutzer>Simon</Benutzer>

Oder auch dieses:

<Obst>Apfel</Obst>

6.3.3 Verschachtelung

XML-Elemente können ineinander verschachtelt werden. Zum Beispiel kann eine Liste mit Benutzernamen so aussehen:

<Benutzerliste>

<Benutzer>Robert</Benutzer>

<Benutzer>Simon</Benutzer>

</Benutzerliste>

Wichtig ist, dass jedes Element einen Anfang und ein Ende hat. Zur besse-ren übersicht sind immer noch die Start-Tags rot und die End-Tags grün eingefärbt.

6.3.4 Attribute

Attribute gehören ebenfalls noch zum Aufbau eines Elements, genauer ge-sagt gehören Sie zum Start-Tag. Mit Attributen können Sie zusätzliche In-

6.0 Verwendete Programmiersprachen und Ressourcen Seite 59

formationen (Variablen) in einem Element unterbringen. So könnte es in dem Beispiel der Benutzerliste unterschiedliche Benutzer geben:

Standard-Benutzer und Premium-Benutzer

Diese Information wird in einem Attribut mit dem Namen „typ“ unterge-bracht. Attribute werden nach dem Namen des Start-Tags gesetzt.

Beispiel:

<Benutzer typ=“standard“>Robert</Benutzer>

Beispiel für einen Premium-Benutzer:

<Benutzer typ=“premium“>Simon</Benutzer>

Der in den Beispielen rot gefärbte Text ist der Name des Attributs. Der blau gefärbte Text ist der Inhalt des Attributs. In der Benutzerliste schreibt man entweder „premium“ oder „standard“. Das Element mit dem Namen Robert hat den Typ "standard". Man kann nun mit einer IF-Bedingung das Element Robert von Simon unterscheiden (IF(Element.Equals("Robert"))). Wenn man das Element Robert hat, in einer Variablen die von Typ Benut-zer ist, kann man auf den „typ“ zugreifen und ihn abfragen oder einer Va-riablen geben.

6.3.5 Elemente ohne echtes End-Tag

Im Zusammenhang mit Attributen gibt es noch eine Besonderheit am Auf-bau von Elementen. In dem vorherigen Beispiel wurde der Benutzernamen in den Inhalt des Tags geschrieben und der Typ des Benutzers in ein ent-sprechendes Attribut. Man könnte auch für beide Informationen Attribute verwenden. Dies würde dann so ausschauen:

<Benutzername=“Robert“ typ=“standard“></Benutzer>

Da in diesem Fall der Inhalt des Tags leer ist, könnte man das End-Tag weglassen. Es muss aber vor der schließenden, spitzen Klammer des Start-Tags ein „/“-Zeichen setzen.

6.0 Verwendete Programmiersprachen und Ressourcen Seite 60

Beispiel:

<Benutzername=“Robert“ typ=“standard“/>

Das Start-Tag wird in diesem Fall „Empty-Element-Tag“ genannt. In den folgenden Erklärungsbeispielen wird aber, wie vorher, der Benutzernamen in den Inhalt des Tags geschrieben.

6.3.6 Nur ein Wurzel-/Stammelement ist erlaubt

XML-Dokumente brauchen immer genau ein Wurzel-/Stammelement. Das heißt, dass alle anderen Elemente in diesem Element verschachtelt sein müssen. Um das anschaulich zu machen, sieht man nun zwei Beispiele für XML-Dateien. Das erste Beispiel ist falsch, da es mehrere Wurzelelemente gibt. Im zweiten Beispiel sind alle anderen Elemente in dem Element „Be-nutzerliste“ verschachtelt, welches das einzige Wurzelelement ist.

FALSCH: (Kompletter Dateiinhalt)

<Benutzer>Simon</Benutzer>

<Benutzer>Thomas</Benutzer>

RICHTIG: (Kompletter Dateiinhalt)

<Programmbenutzer>

<Benutzer>Simon</Benutzer>

<Benutzer>Thomas</Benutzer>

</Programmbenutzer>

6.3.7 XML-Deklaration

Am Anfang einer jeden XML-Datei sollte man eine XML-Deklaration setzen. Diese enthält Informationen zur XML-Version (wobei momentan die

6.0 Verwendete Programmiersprachen und Ressourcen Seite 61

Version 1.0 aktuell ist) und zum Zeichensatz der Datei. Diese XML-Deklaration sieht z.B. so aus:

<?xml version="1.0" encoding="utf-8" ?>

Wie zu erkennen ist, hat dies vom Aufbau her eine große Ähnlichkeit zu XML-Elementen. So erkennt man die Attribute „version“ und „encoding“. Mithilfe des Attributs „version“ gibt man die XML-Version und im Attribut encoding den Zeichensatz ab. Wenn Sie XML-Dateien mithilfe des .net-Frameworks erzeugen, wird diese XML Deklaration automatisch erzeugt.

Bild 34: XML Datei

6.0 Verwendete Programmiersprachen und Ressourcen Seite 62

6.3.8 Das Auslesen einer XML Datei

Zum Auslesen der XML wird eine .DLL (Direct Link Library, siehe Kapitel 7.1) ins Projekt referenziert. Dann wird der namespace6 ins Projekt einge-fügt, damit man nicht immer auf die .DLL verweisen muss. Durch diese .DLL kann man auf die einzelnen Objekte der XML zugreifen. In der XML selber, wenn man sich zum Beispiel an der Wurzel (Stamm) befindet, kann man sich nun zu jedem Knoten bewegen, der direkt mit der Wurzel ver-bunden ist. Tiefere Knoten erreicht man durch weiteres Gehen. Jeder Kno-ten kann Inhalt enthalten, den man, wenn man den Knoten erreicht hat, auslesen kann.

6.3.9 CamXML

Dies ist der Dateityp, der zum auslesen von Punkten, Innenkonturen und

Rahmen benutzt wird. Die CamXML enthält die Randgeometrien sowie die

Bohrlöcher. Die Geometrien sind in Segmente aufgeteilt. Davon gibt es das

Linien- und das Kreisbogensegment. Ein Liniensegment wird durch An-

fangs- und Endpunkt und ein Kreisbogen durch Radius, Start- und End-

winkel im Bogenmaß und Kreismittelpunkt bestimmt.

6Zwar sind Objekte durch ihren Namen identifiziert, jedoch muss man den namespace für

eine eindeutige Zuordnung angeben. Da man nicht immer diesen namesspace bei jedem

Objekt neu angeben will, kann man ihn in einen namespace bereits vorher in das Pro-

gramm einfügen mit import "namespace";. So wird zu jedem Objekt der namespace beim

kompilieren angehängt ohne dass dies der Benutzer machen muss.

7.0 Umsetzung in eine DLL Seite 63

7.0 Umsetzung in eine DLL

In diesem Kapitel wird die Umsetzung des Triangulierunsalgorithmuses beschrieben. Es sollte nur eine DLL geschrieben werden, die die Fenster-scheiben, welche der DLL übergeben werden, trianguliert und eventuell noch Abstandhalter und Gummi erzeugt (Siehe Bilder in Kapitel 9.2).

7.1 Dynamic-Link Library (DLL)

Eine DLL ist eine Programmbibliothek, die unter MS Windows Verwendung findet. Solche Bibliotheken enden bei Ihrem Dateinamen normalerweise mit DLL, OCX (Für Bibliotheken die ActiveX Steuerelemente enthalten) o-der ICL (Für Bibliotheken die nur Gerätebilder, sogenannte Icons, und kei-nen Programmcode enthalten). Sowohl EXEs als auch DLLs besitzen Pro-grammcode (Maschinencode), Daten und Ressourcen, die sie in irgendei-ner Kombination enthalten können. DLLs wurden von MS zur Speicherre-duzierung auf Festplatte und Hauptspeicher eingeführt. Denn jeder Pro-grammcode, der von mehreren Anwendungen benutzt wird, steht in nur einer DLL auf der Festplatte und wird nur einmal in den Hauptspeicher ge-laden. Ein weiterer Vorteil fasst sich unter dem Stichwort Modularität zu-sammen. Wenn ein Stück des Programmcodes ausgetauscht werden muss, muss nicht das ganze Programm ausgetauscht werden, sondern nur die DLL, in sich der dieser Programmcode findet. Das Ganze könnte man als dynamisches Einbinden bezeichnen, da dies im Falle von Treiber zum Teil ohne Neustart des Systems funktioniert. DLLs haben jedoch auch eine Schwäche, DLL Hell genannt. Denn es gibt Anwendungen, die die gleichen DLLs benötigen, aber unterschiedliche Versionen davon. Eine Problembe-hebung wäre die DLL mit der richtigen Version ins Programmverzeichnis zu kopieren. MS .Net umgeht das Ganze, indem es einfach DDLs mit ver-schiedenen Versionen akzeptiert.

7.1.1 Die Schnittstelle (Interface) der DLL

Da man einen Teil der CamXML bekommt, der trianguliert werden soll, muss man mindestens eine Mesh-Geometrie als Return-Wert übergeben. Man erhält also zu Beginn den Teil der CamXML, wo

7.0 Umsetzung in eine DLL Seite 64

die Geometrie der Scheibe steht. Zurückgegeben werden zwei Objekte:

1) Eine triangulierte Scheibe (eventuell auch Abstandhalter und Gum-mi) wird zurückgegeben. D. h. die Punkte, Dreiecksindexe und evtl. Normalen und evtl. Texturkoordinaten werden einem MeshGeo-metry3D Objekt übergeben. Ein Mesh3DGeometry Objekt besteht aus den Punkten, den Dreiecksindexen, den Normalen (optional) und den Texturkoordinaten (optional). In diesem Kapitel ist dieses Objekt gemeint, wenn von Mesh geschrieben wird.

2) Das Oberflächen Material, das die verschiedenen Fensterteile erhal-ten sollen. Es ist ein MeshType Array. MeshType ist ein enum mit den verschiedenen Bezeichnungen der Fensterteile, damit das Mate-rial zugeordnet werden kann.

7.1.2 Erstellen einer DLL mit MS Visual Studio 2005

In MS Visual Studio 2005 kann man im Menü festlegen, wenn man ein Projekt beginnt, ob aus dem Projekt, eine Konsolenanwendung („Console Application“), Windows Application oder eine Class Library werden soll. Bei einer DLL muss der Typ eine Class Library sein, damit nach dem Kompilie-ren eine DLL erzeugt wird. Zudem ist es noch möglich den Projekttyp im Projektmanager zu ändern.

7.2 Auslesen der Punkte mit der Funktion SortPoints

Diese Funktion liest die Punkte der Glasscheiben. Dadurch müssen auch bereits Vorkehrungen erfasst werden, damit die Seitenteile und der Ab-standhalter erzeugt werden können.

7.2.1 Voraussetzungen

Die Segmenttypen werden immer von unten links, nach unten rechts, ü-ber oben rechts, nach oben links - also gegen den Uhrzeigersinn - durch-gegangen in der CamXML. Dadurch kennt man immer die Nachbarpunkte des Glasrandes.

7.0 Umsetzung in eine DLL Seite 65

Der Funktionskopf sieht folgendermaßen aus:

private MeshGeometry3D[] SortPoints(Point3DCollection points, double thick, double zExtend, int layer)

Erläuterung der Varibalen, die übergeben werden:

1) points bekommt im Laufe der Funktion die Punkte des Glasrandes übergeben.

2) thick ist der Wert der z-Koordinate oben auf der Glasvorderseite.

3) zExtend ist der Wert der z-Koordinate auf der Glasrückseite.

4) layer ist ein Wert der angibt, ob ein Abstandhalter nötig ist. Der Abstandhalter wird momentan immer eingefügt, wenn der layer 1 ist.

7.3 Randgeometrien

Zuerst werden die Randpunkte der Glasscheiben in der Collections points gesichert. Es wird durch eine If-Bedingung geprüft, welcher Segmenttyp vorliegt (Abstrakt: If(arc) oder if(line)). Entweder liegt eine Linie (hier lie-gen Start- und Endpunkt vor) oder ein Kreisbogen (hier liegen Radius, Start- und Endwinkel im Bogenmaß und Kreisbogenmittelpunkt vor) vor. Bei einer Linie werden einfach die Endpunkte der Linie als Randpunkt ge-nommen. Der Randpunkt bekommt die x- und y-Koordinate der Linie als x- bzw. y-Wert und der z-Wert wird mit der Variablen thick gefüllt. Der Kreisbogen berechnet sich wie in Kapitel 3.3.4 beschreiben (Die z-Koordinate wird auch mit dem Wert thick gefüllt).

Dann werden die Punkte des Abstandhalters aufgenommen (warum wird später erläutert). Es ist im Prinzip dasselbe wie für die Randpunkte der Glasscheibe. Jedoch müssen nicht die Kreispunkte berechnet werden. Es werden nur der Endpunkt und der Radius des Kreisbogens gesichert. Dazu werden noch die Start- und Endwinkel im Bogenmaß in einer anderen PointCollection gesichert. Auch der Kreismittelpunkt und die Anzahl der Punkte des Kreises werden in einer separaten Point3DCollection gesichert, damit nachher die Punkte des Kreisbogens noch erzeugt werden können.

Als nächstes werden Innenkonturen ausgelesen.

Anm.: Die Senkbohrlöcher und Bohrlöcher haben alle 40 Punkte, da diese nur zwei bis drei cm Durchmesser besitzen.

7.0 Umsetzung in eine DLL Seite 66

7.3.1 Die verschiedenen Ausschnitte

7.3.1.1 Bohrlöcher

Zuerst werden die normalen Bohrlöcher (Bild 40) behandelt, die durch die Bedingung if (stp.typeString.CompareTo("Drillhole") == 0) ermittelt wer-den. Die Punkte für die Löcher werden durch die Methode von oben (Kap. 3.3.4) erzeugt. Das ist auch bereits alles. Die Punkte werden in einer ge-sonderten Point3Dcollection (hier: insideNormalHoles) gesichert.

7.3.1.2 Senkbohrlöcher

Senkbohrlöcher (Bild 41) können auch visualisiert werden. Das funktio-niert ähnlich wie bei den normalen Löchern. Bei den Senklöchern ist die obere und untere Öffnung auf der Vorder- bzw. Rückseite der Glasscheibe verschieden breit. Das Bohrloch sieht wie ein Trichter aus. Mit der Bedin-gung if (stp.typeString.CompareTo("Sinkhole") == 0) werden Senkbohrlö-cher ermittelt.

Zuerst einmal wird die Unterscheidung von oben und unten benötigt bzw. ob man sich auf der Vorder- oder Rückseite des Fensters befindet. Dann benötigt man die verschieden Radien des Senkbohrloches. Es müssen nun zwei Point3DCollections mit Punkten befüllt werden. Eine, die die Punkte des Bohrloches der Vorderseite (Hier: insideContourSinkHolePoints) sam-melt und eine, die die Punkte des Bohrloches von der Rückseite (Hier: insideContourSinkHolePointsBehind) speichert. Ansonsten ist die Berech-nung exakt dieselbe wie bei den normalen Löchern.

7.3.1.3 Innenausschnitte

Diese werden wie die Randpunkte ausgelesen (Bild 36). Mit der Bedingung if (stp.typeString.CompareTo("InnerContour") == 0) werden Innenaus-schnitte ermittelt und in der Point3DCollection InnerCutOuts gesichert.

Das Material für die Seitenteile bei Ausschnitten und Bohrlöchern ist ein Specular Material.

Das sind alle Geometrien, die zusätzlich zum Rand ausgewertet werden.

7.0 Umsetzung in eine DLL Seite 67

In der Funktion SortPoints werden die Funktionen SpacerTriangulation und Shrink aufgerufen. Die erste Funktion trianguliert die Randteile des Glases und die zweite Funktion schrumpft den Abstandhalter. Daher müssen die Kreisbögen auch so angeben werden, damit die Funktion Shrink durch ei-ne API auf eine Funktion des Programms Shaping & Nesting (SN) zugrei-fen kann und die Scheibe geschrumpft wird (die Funktion kann auch die Scheibe vergrößern).

7.4 SpacerTriangulation

Der Funktionskopf:

private MeshGeometry3D[] SpacerTriangulation(Point3DCollection points, Point3DCollection spacer, PointCollection angle, DoubleCollection point-sOfCircle)

Diese Funktion erzeugt einige Meshes und gibt diese als Array zurück. Die Variablen des Funktionskopfes sind folgende:

1) points enthält die Randpunkte der Scheibe.

2) spacer enthält die Abstandhalter Punkte (Der eingeschrumpfte Glas-rand, der vorher durch die SN-API berechtet wurde.).

3) angle enthält die Winkel für die Start- und Endwinkel der Abstand-halterkreisbögen im Bogenmaß.

4) pointsOfCircle enthält die Anzahl der Punkte der Kreisbögen.

In der Funktion SpacerTriangulation werden zu Beginn die Kreisbögen des Abstandhalters berechnet. Die Punkte des Abstandhalters werden erzeugt, d. h. die Kreisbögen müssen berechnet werden. Diese sind nur mit ihrem Endpunkt und Radius angegeben sind. Weil aber die Start-, Endwinkel, des Kreismittelpunkt und die Anzahl der Punkte der Kreisbögen in ver-schiedenen Collections sind, kann man die Kreisbögen berechnen und an den Stellen einfügen, an denen vorher nur die Endpunkte und die Radien der Kreisbögen standen. Dann werden der Abstandhalter und der schwar-ze Gummi erzeugt. Die Seitenteile, gleichwohl ob Abstandhalter oder der schwarze Gummi, werden durch die Funktion SideTriangulation (nächstes Kapitel) errechnet, die das fertige Mesh, das sie erzeugt, übergibt.

7.0 Umsetzung in eine DLL Seite 68

Vorher müssen aus den Point3DCollection spacer und points zwei neue Point3DCollections erzeugt werden, die beide gleich zu den Collection spacer und points sind. Nur der z-Wert ist bei jedem Punkt anders. Er ist die Dicke der ersten Glasscheibe. Jeweils mit der Dicke des Abstandhalters werden die neuen Point3DCollection der Funktion SideTriangulation ein-zeln übergeben. Damit werden die beiden Seitenteile erzeugt. Dabei ist zu bemerken, dass das Material des Gummis Lambert und das Material des Abstandhalter Specular ist. Die z-Koordinate des Abstandhalters und die Dicke der ersten Scheibe werden aus der CamXML ausgelesen.

Wenn das Mesh für den Abstandhalter und den Gummi bestimmt ist, wird die schwarze Gummioberfläche für die Vorderseite und dann für die Rück-seite bestimmt. Dazu sollten die Punkte des Glasrandes und des Abstand-halters abwechselnd in eine neue Point3DCollction übergeben werden. Damit entsteht die Vorderseite (Siehe Bild 35).

Bild 35: Gummirand der Vorderseite bei einem Viereck (Die Zahlen stellen die Index-

nummern der Punkte dar)

Bild 36: Seitenteil des Gummirandes (Die Zahlen stellen die Indexnummern der Punkte

dar)

7.0 Umsetzung in eine DLL Seite 69

Bei der Triangulation der Gummioberfläche bilden der Index 0, dann der Index 2 und der Index 3 das erste Dreieck und Index 4, Index 1 und In-dex 0 bilden das zweite Dreieck (Bild 35). Dann folgt das nächste Viereck. Es wird nun mit den letzten beiden Indices (hier 2 und 3) und den nächs-ten beiden (4 und 5) neue Dreiecke erzeugt. In Bild 35 sähe das so aus: Die Indexe 0, 2, 3 und 3, 1, 0 bilden die Dreiecke eins und zwei, dann folgt das dritte 2, 4, 5 und vierte Dreieck 5, 3, 2 usw. Die Diagonale ver-läuft also immer zwischen dem ersten und letzten Punkt des Vierecks. Zum Schluss müssen die letzten beiden Punkte mit den ersten beiden tri-anguliert werden. Die Normalen bekommen alle den Vektor (1, 0, 0). Der Rückgabewert bekommt die Punkte, Normalen und Dreiecksindexe über-geben.

Es sind Trapeze die trianguliert werden. Nun müsste der Delaunay-Algorithmus angewendet werden, aber dazu wurde sich nicht entschieden, da die obige Berechnung schneller ist und der Abstandhalter nicht zu se-hen ist, wenn der Fensterrahmen in naher Zukunft visualisiert wird. Somit ist die Wahl der Diagonalen unerheblich.

Für die Rückseite wird ein Trick angewendet. Da man die Rückseite sieht, wenn die Dreiecksindexe im Uhrzeigersinn sind, werden die ersten beiden Dreiecksindexe jedes Dreiecks der Vorderseite (Da diese gegen den Uhr-zeigersinn sind) einfach vertauscht. Die Normalen der Punkte müssen nur noch den Vektor (-1, 0, 0) bekommen. Die Punkte der Rückseite ergeben sich aus den Punkten der Vorderseite mit einem andern z-Koordinatenwert, da die Rückseite tiefer liegt. Dieser wird aus der CamXML ausgelesen.

7.5 SideTriangulation

Diese Funktion trianguliert Seitenteile, ohne den Delaunay-Algorithmus zu benötigen. Der Funktionskopf sieht folgendermaßen aus:

public MeshGeometry3D SideTriangulation(Point3DCollection points, double thick)

Der Rückgabewert, wie bereits im Abschnitt vorher bemerkt, ist eine Mesh-Geometrie. Die Variablen:

1) points enthält die oberen Punkte.

2) thick ist die Dicke des Seitenteils.

7.0 Umsetzung in eine DLL Seite 70

Erst mal sind die übergebenen Punkte auf einer Ebene (also ist der z-Wert immer gleich) und in der Point3DCollection points gespeichert. Da die Di-cke übergeben wird, werden die neuen Punkte aus den alten erzeugt. Es ändert sich nur die z-Koordinate. Die Punkte werden in eine neue Collecti-on geschrieben und zwar wird jeder Punkt nacheinander zweimal einfügt. Einmal wie er in der Variablen points steht und einmal genauso nur mit dem Wert thick als neue z-Koordinate. Es wird nur die z-Koordinate ver-ändert (Siehe Bild 36).

Ob das Seitenteil links, rechts, oben oder unten befindet, ist egal, da man sich das ganze wie ein Rechteck vorstellen muss. Darum besitzen alle vier Winkel die Gradzahl 90 und es ist egal, welche Dreiecke für die Triangula-tion genommen wird.

Der allgemeine Fall (indices ist eine int32Colletion und i ist der Index-wert):

indices.Add(i + 1);

indices.Add(i + 3);

indices.Add(i + 2);

indices.Add(i + 2);

indices.Add(i);

indices.Add(i + 1);

Zum Schluss muss noch der letzte Fall analysiert werden, nämlich was passiert bei den letzten zwei Punkten und den ersten zwei Punkten. Denn diese müssen ebenfalls trianguliert werden, da sonst das letzte Seitenteil fehlen würde. Dies passiert wie oben. Nur die Indices der Dreiecke sind anders.

indices.Add(points.Count - 1);

indices.Add(1);

indices.Add(0);

indices.Add(points.Count - 2);

indices.Add(points.Count - 1);

indices.Add(0);

7.0 Umsetzung in eine DLL Seite 71

Die Normalen werden von dem WPF bestimmt, da dort die Ergebnisse besser sind. WPF bzw. Directx scheint zwischen den Punkten die Normalen zu interpolierten und somit wird der Übergang weicher.

Die beiden Funktionen SideTriangulationInnerContourHoles (Seitenteile für Bohrlöcher) und SideTriangulationInnerContourRectangles (Seitenteile für Innenausschnitte) besitzen fast den gleichen Algorithmus wie diese Funk-tion. Dort muss nur darauf geachtet werden, dass zwischen den einzelnen Löchern (egal, ob Innenausschnitt oder Bohrloch) keine Seitenteile sind. D. h., dass in der For-Schleife für die Erzeugung der Dreiecksindexe etwas geändert werden muss. Dort befinden sich jetzt zwei For-Schleifen. Die erste durchläuft von 0 bis zur Gesamtanzahl der Löcher/Innenausschnitte. Die zweite durchläuft vom ersten Punkt bis zum letzten Punkt des Lo-ches/Innenausschnittes und keinen Punkt mehr (ist auch nicht schwer, da alle Bohrlöcher 40 Punkte besitzen und man bei den Innenkonturen die Anzahl der Punkte jeder Kontur kennt). Ansonsten würde man ein Seiten-teil zwischen den Bohrlöchern/Innenausschnitte erzeugen. Der Funktion SideTriangulationInnerContourHoles übergibt man zudem noch einen Bool-Wert, der einfach angibt, ob es normale Bohrlöcher oder Senkbohrlö-cher sind. Denn die Senkbohrlöcher haben bereits alle Punkte (auch die in z-Richtung!). Diese benötigen keine weiteren Punkte mehr.

7.6 InCircle

Es werden vier Punkte übergeben (hier die einzelnen x- und y-Werte der Punkte). Der erste ist der Punkt, der in die Triangulation aufgenommen werden soll. Er soll darauf getestet werden, ob er im Umkreis liegt, den die anderen drei übergebenen Punkte aufziehen (die drei Punkte bestim-men ein Dreieck der Triangulation). Mit den drei Punkten wird also ein Kreis berechnet. Wenn der erste Punkt in oder auf dem Kreis liegt, ist der Rückgabewert true. Sonst ist der Wert false.

Als erstes wird getestet, ob die Punkte (mit denen der Umkreis erzeugt wird) auf einer gemeinsamen Line liegen. Denn dann kann kein Kreis be-rechnet werden und somit wäre der Rückgabewert false. Wenn die Punkte nicht auf einer Linie liegen, folgt die Berechnung, ob der Punkt im Umkreis der drei Punkte liegt. Die mathematische Berechung ist genau dieselbe wie in Kapitel 3.3.3.

7.7 TestToNotConvex

7.0 Umsetzung in eine DLL Seite 72

Die Berechnung ist im Kapitel 3.3.2 beschrieben.

Rückgabewerte:

1) Falls der Flächeninhalt größer Null ist, gibt er 1 zurück. Daraus folgt, es ist eine konvexe Ecke.

2) Falls der Flächeninhalt kleiner Null ist, gibt er -1 zurück. Daraus folgt, es ist eine nichtkonvexe Ecke.

3) Falls der Flächeninhalt Null ist, gibt er 1 zurück. Daraus folgt, dass die Punkte auf einer Linie liegen. Dieses Resultat bedeutet, es ist ei-ne konvexe Ecke.

7.8 CreateRectangleMesh

In dieser Funktion mit dem Rückgabewert MeshGeometry3D[] wird die Delaunay-Triangulation für die Glasscheiben durchgeführt. Der Funktions-kopf:

private MeshGeometry3D[] createRectangleMesh(Point3DCollection points, Vector3D normal)

Die Variablen des Funktionskopfes:

1) points enthält die Scheibenpunkte.

2) normal enthält die Normale. Die Vorderseite besitzt den Vektor (1, 0, 0).

Die Normalen erhalten diese Werte, da die Vorderseite der Scheibe eben ist und die Normalen senkrecht von der Glasscheibe abstehen. So kann die Berechnung gespart werden.

7.8.1 Voraussetzungen

Es werden in einer For-Schleife alle Punkte der Scheibe auf maximale und minimale x- und y-Werte getestet. Diese werden in den Variablen xmax bzw ymax und xmin bzw. ymin gespeichert. Dann wird der Abstand zwischen und maxmimalen und minimalen x- und y-Werten

7.0 Umsetzung in eine DLL Seite 73

berechnet und in die Variablen dx bzw. dy geschrieben. Der größte Wert von wird in der Varibale dmax zwischengespeichert. Dann werden die Varibalen ymid und xmid gefüllt mit der Mitte der Strecken zwischen xmax und xmin bzw. ymax und ymin. Diese Variablen werden für das Startdrei-eck benötigt. Dieses soll alle Punkte umschliessen. Im Anschluss daran bekommt nvertBoundary die Größe von points übergeben, da dort alle Randpunkte sind. Als nächstes werden am Ende von points die Punkte der Bohrlöcher hinzugefügt - falls es welche gibt - durch die Collections:

1) insideNormalHole enthält alle normalen Bohrlöcherpunkte und

2) insideContourSinkHolePoints enthält alle Senkbohrlöcherpunkte von der Vorderseite.

Die Innenausschnitte werden zu guter Letzt zu der Collection points hin-zugefügt. Zum Schluss wird nvert die Gesamtzahl der Punkte von der Col-lection points übergeben.

7.8.2 Der Algorithmus

Jetzt kommen wir zum Kernstück der Angelegenheit. Zuerst, wie angekündigt, wird das Startdreieck aufgezogen. Dafür werden die oben ermittelten Werte, die zuerst berechnet wurden, benutzt.

Punkt 1 hat den x-Wert xmid - 20 * dmax und den y-Wert ymid - dmax

Punkt 2 hat den x-Wert xmid und den y-Wert ymid + 20 *dmax

Punkt 3 hat den x-Wert xmid + 20 * dmax und den y-Wert ymid - dmax

Die z-Koordinate bekommt den z-Wert des ersten Punkts aus der Collection points.

Das Startdreieck wird markiert durch nvert, da es als Indexwert die Werte größer nvert bekommt. Damit sind die Dreiecke, die Punkte aus vom Startdreieck enthalten, leichter zu löschen. Es müssen nur die gelöscht werden, die einen oder mehrere Indices besitzen, die größer als nvert sind.

Eine For-Schleife über alle Punkte lässt die Triangulation beginnen. Mit je-dem Punkt, der eingefügt werden soll, wird die Collection edges neu initia-lisiert. Denn diese enthält die Start- und Endpunkte der Kanten (als In-dex), die eingefügt werden sollen. Als nächstes wird mit einer weiteren For-Schleife jedes Dreieck überprüft, ob der Umkreis des Dreiecks

7.0 Umsetzung in eine DLL Seite 74

den einzufügenden Punkt enthält. Dazu wird auf die oben beschriebene Funktion InCircle zurückgegriffen. Falls das der Fall ist, werden die Indexe der Dreiecksseiten (Kanten) in edges gesichert. Das Dreieck wird gelöscht und der Index der zweiten For-Schleife wird um eins reduziert. Wenn der einzufügende Punkt nicht im Umkreis liegt, wird das nächste Dreieck ge-testet. Nachdem alle Dreiecke getestet wurden, werden die Kanten kon-trolliert. In der nächsten geschachtelten For-Schleife werden einfach dop-pelte Kanten aus der Collection edges gelöscht. Dann werden aus den In-dexen der Kanten und dem Index des einzufügenden Punkt Dreiecke er-zeugt (da die Kante aus Start- und Endpunkt besteht und der Punkt, der in die Triangulation aufgenommen werden will, insgesamt drei Punkte sind, kann man ein Dreieck entstehen lassen.). Zu guter Letzt, nachdem alle Punkte trianguliert sind, werden alle Dreiecke mit Indexwerten größer nvert gelöscht (wie oben beschrieben). Die Indices der Dreiecke sind im Uhrzeigersinn. Jedoch benötigt WPF-Indices gegen den Uhrzeigersinn. Deshalb werden zum Schluss die ersten beiden Indices jedes Dreiecks ver-tauscht.

7.8.3 Finde nichtkonvexe Seitenteile

Im Prinzip werden mit der Funktion TestToNotConvex einfach Dreiecke getestet, ob diese nichtkonvex sind (wie bereits oben beschrieben). Es werden zwei For-Schleifen verschachtelt. Mit denen immer der aktuelle und der Nachbar des aktuellen (der Punkt, der in der Collection points den um eins erhöhten Indexwert besitzt) Punktes mit den nachfolgenden Punkten getestet werden. Wenn die drei getesteten Punkte nichtkonvex sind, werden der erste (der erste fixe Punkt) und der letzte Punkt (der Laufpunkt) in der PointCollection concav (hier werden dann nur die In-dexwerte gespeichert und zwar als Punkt. Das heißt als x (für den ersten Index) und y (für den zweiten Index) Wert) eingefügt.

Dann müssen die Dreiecke gelöscht werden, die zwei Indexe besitzen, die einem einzelnen Punkt in der PointCollection concav entsprechen. Dabei muss beachtet werden, dass die Indexwerte nicht größer sind als die An-zahl der Randpunkte. Sonst würden Innenkonturen betroffen sein. Diese haben aber nichts mit dem Rand zu tun.

7.0 Umsetzung in eine DLL Seite 75

7.8.4 Bohrlöcher und Senkbohrlöcher

Es wurden alle Punkte, die ein Bohrloch und Senkloch (Bild 40 und 41) darstellen, errechnet, wenn welche in der Glasscheibegeometrie vorhan-den sind. Dann wurden alle Punkte der Bohrlöcher zu den Randpunkten der Point3DCollection eingefügt. Die Punkte wurden trianguliert und letzt-lich werden die Dreiecke, die nicht benötigt werden, da diese in den Lö-chern sind, gelöscht. Das funktioniert recht simpel. Da alle Dreiecke ent-fernt werden, die nur aus Indexwerten bestehen, die größer sind wie die Anzahl der Randpunkte der Scheibe. Dabei muss jedes Bohrloch separat behandelt werden. D. h. es werden nur Dreiecke gelöscht, die in den ein-zelnen Bohrlöchern liegen (damit wird verhindert, dass Dreiecke gelöscht werden, die zwischen einzelnen Bohrlöchern liegen und ebenfalls nur aus Punkten der einzelnen Bohrlöcher bestehen.). Der Integer-Wert nvert-Boundary gibt die Anzahl der Randpunkte des Objektes an und man kennt die Anzahl der Bohrlöcher (da alle Löcher gleich viele Punkte haben und man die Gesamtpunktzahl und die Punkte der Innenausschnitte kennt.).

Bei den Senklöchern ist die obere und untere Öffnung auf der Vorder- und/oder Rückseite verschieden breit, so dass Bohrloch wie ein Trichter aussieht. Nun könnte man meinen, dass man beide Oberflächen triangu-lieren muss, da die Punkte verschiedene Koordinaten besitzen, wenn Vor-der- und Rückseite des Senkbohrlochs verschiedene Radien haben. Das muss jedoch nicht gemacht werden, weil man oben wie unten gleich viele Punkte hat und die Triangulation gleich wäre. Man übergibt dem WPF le-diglich andere Punktkoordinaten (der z-Wert muss geändert werden) und andere Dreiecksindexe (wie oben bereits angemerkt, müssen von jedem Dreieck der Vorderseite die ersten beiden Indices vertauscht werden.). Das ist ein ganz klarer Vorteil dieses Vorgehens, da die zusätzliche Trian-gulation ganz klar zeitaufwendiger wäre. Es wird also nur die Vorderseite trianguliert. Die Rückseite wird dann immer aus der Vorderseite gebaut.

7.8.5 Innenausschnitte

Die Erzeugung des Innenausschnittes funktioniert genauso wie im Ab-schnitt 7.8.4. Nur dass jeder Innenausschnitt eine unterschiedliche Anzahl von Punkten besitzt. Das macht aber nichts, da man die Anzahl der Punkte eines jeden Innenausschnittes kennt.

Die nichtkonvexen Stellen bei Innenkonturen dürfen nicht gelöscht wer-den. Darum führt man dasselbe durch wie beim Einhalten des Randes der

7.0 Umsetzung in eine DLL Seite 76

Glasscheibe durch. Nur dass hier mit den Punkten der Innenausschnitte gearbeitet wird. Die sind größer als nvertBoundary plus die Punkte der e-ventuell vorhandenen Bohrlöcher. Aber im Grunde ist es dieselbe Intenti-on, die dahinter steckt wie bei den nichtkonvexen Stellen der Randgeo-metrie. Die Punkte, die nicht gelöscht werden dürfen, werden in die Point-Collection innerContourNotConvexEdges eingefügt. Es ist auch recht ein-fach einzusehen, warum diese Ecken nicht gelöscht werden dürfen. Denn diese sind außerhalb des Loches (nichtkonvexe Stelle „<“ in Bild 37) und man würde somit ein Stück der Glasscheibe entfernen. Das passiert, da diese Stellen komplett aus Punkten von den Innenausschnitten bestehen können. Damit würden Dreiecke gelöscht werden, die zum Glas gehören.

Bild 37: Ausschnitt mit nichtkonvexer Stelle

In dem Algorithmus gibt es eine IF-Bedingung, die nur Dreiecke löscht, die nicht aus Indices bestehen, die in der Collection innerContourNotConvexEdges stehen.

7.8.6 Schluss

7.0 Umsetzung in eine DLL Seite 77

Hier werden für die Vorderseite einfach die Randpunkte und die geänder-ten Dreiecksindexen dem Rückgabewert des Objekts MeshGeometry3D[] (Es wird also ein Mesh übergeben) übergeben. Jedoch werden vorher die Normalen für jeden Punkt erzeugt. Bei einer Vorderseite ist der Vektor der Normalen (1, 0, 0) und bei einer Rückseite (-1, 0, 0). Für die Rückseite müssen die ersten Dreiecksindexe genommen werden (siehe oben) und die Punkte benötigen einen anderen z-Wert (die Gesamttiefe der Scheibe). Den kann man aus der CamXML auslesen.

7.9 CreateGlassMesh

Diese Funktion erzeugt die einzelnen Meshes und übergibt diese einem Mesh3DGeometry Array. Die einzelnen Funktionen zur Mesh-Erzeugung werden aufgerufen (z. B. createRectangleMesh für die Vorder- und Rück-seite). Die zurückgegebenen Meshes werden in dem MeshGeometry3D Ar-ray hinterlegt. Prinzipiell ist der Ablauf, dass zuerst das Mesh eines Teiles der Glasscheibe erzeugt wird. Dann wird dem MeshTypes Array der Typ (Welches Fensterteil es überhaupt ist, damit man später weiß, welches Material nötig ist) übergeben.

Funktionskopf:

private void createGlassMesh(Point3DCollection points, double thick, out MeshGeometry3D[] mesh, out MeshTypes[] types, int layer, MeshGeome-try3D[] meshSpacer)

Die Variablen des Kopfes:

1) points enthält die Glasscheibenpunkte.

2) thick enthält die Dicke.

3) mesh erwartet das komplette Mesh des Objektes.

4) layer Unterscheidung Vorder- oder Rückseite.

5) meshSpacer enthält das komplette Abstandhalter und Gummi Mesh.

Der Abstandhalter wurde nur aufgebaut, wenn der layer gleich eins ist. Die Innenkonturen werden ebenfalls nur berechnet, wenn diese in der Scheibengeometrie enthalten sind.

7.0 Umsetzung in eine DLL Seite 78

Für die ganzen Körper wie Glasscheibe, Innenkonturen – also Senk- und Bohrlöcher und auch Ausschnitte – müssen noch die Seitenteile mit den einzelnen SideTriangulation-Funktionen erzeugt werden. Aber nur, falls welche in der Geometrie sind. Die einzelnen Materialtypen müssen noch übergeben werden und das war es bereits. Da die Reihenfolge immer gleich ist und jedes einzelne Teil der gesamten Scheibe einzeln abgearbei-tet wird, ist dies relativ leicht.

Reihenfolge:

1) Vorderseite der Scheibe

2) Rückseite der Scheibe

3) Seitenteile der Scheibe

4) Vorderseite des Abstandhalters

5) Rückseite des Abstandhalters

6) Gelelement des Abstandhalters

7) Äußeres Seitenteil des Abstandhalters

8) Inneres Seitenteil des Abstandhalters

9) Äußeres Seitenteil von Bohrlöchern

10) Inneres Seitenteil von Bohrlöchern

11) Äußeres Seitenteil von Senkbohrlöchern

12) Inneres Seitenteil von Senkbohrlöchern

13) Äußeres Seitenteil von Ausschnitten

14) Inneres Seitenteil von Ausschnitten

Die Teile eins bis drei sind immer da. Vier bis acht nur, wenn die Vorder-seite erzeugt wird, der Layer also eins ist. Zehn bis vierzehn sind optional je nach Geometrie. Die vierzehn Objekte haben alle mindestens die ein-zelnen Punkte, Dreiecksindexe und einen eigenen Materialtyp.

7.10 Wireframe

Das Wireframe macht die Triangulation sichtbar. Es werden die Kanten der Dreiecke gezeichnet. Für das Wireframe werden die Start- und Endpunkte der Kanten von den Dreiecken benötigt. Dazu wurden einige Funktionen geschrieben, die nichts anderes machen wie zwischen diesen Punkten eine

7.0 Umsetzung in eine DLL Seite 79

Linie mit einer ausgewählten Dicke zu erzeugen. Zuerst werden alle Start- und Endpunkte der Linien durch die Funktion WireFrameHelper bestimmt. Das heißt, da ein Dreieck drei Seiten hat, werden jetzt sechs Punkte er-zeugt. Denn jede Seite hat einen Start- und Endpunkt. Wenn das beendet ist, wird die MeshGeometry bestimmt. Dazu wird die Methode RebuildGe-ometry aufgerufen, in der die Positionen der neuen Eckpunkte und Indexe bestimmt werden. Die neuen, verschobenen Punkte werden durch die Funktion AddSegement und Widen errechnet. Dazu muss man

1) den Richtungsvektor zwischen Start- und Endpunkt bestimmen,

2) z Null setzen (da man in einer Ebene ist, ist dieser bereits Null),

3) den Richtungsvektor normalisieren. Die Länge des Vektors eins werden lassen,

4) und dann die Normale bestimmen, in dem man den x- und y- Wert tauscht und der y Wert negiert wird.

Die Normale wird dann noch mit der gewünschten Dicke multipliziert. So-mit hat man bereits den Zahlenwert (hier Delta genant), der angibt, wie weit die neuen Linien zu der Kante parallel nach oben und unten verscho-ben sein sollen. Dann werden die neuen Punkte in der Funktion Widen be-rechnet. Dort werden die bisherigen Punkte einfach mit Delta addiert für die obere und subtrahiert für die untere Linie. Mit der Funktion AddTri-angle wird die Triangulation (das Dreiecksnetz) erzeugt.

Bild 38: Wireframe

7.0 Umsetzung in eine DLL Seite 80

7.11 Strukturglas

Wenn es verlangt wird, kann auf die Glasseiten ein Bild aufgeklebt wer-den, damit ein Strukturglas erzeugt werden kann. Dazu müssen nur ein Bild und die Texturkoordinaten (siehe Kapitel 6.2.1.3.3 Texture mapping) vorhanden sein. Das Bild ist entweder per Pfad in der CamXml angeben oder, wenn kein Bild angegeben ist, wird einfach ein Default Bild genom-men. Die Texturkoordinaten ermitteln sich über folgende Formeln:

1) für den x-Wert:

pointX = meshGeometry3D.Positions[i].X / boundingRectX * sumOfPic-turesX;

2) für den y-Wert:

pointX = meshGeometry3D.Positions[i].Y / boundingRectY * sumOfPic-turesY;

Die beiden Formeln unterscheiden sich einzig zwischen den x- und y-Werten. Da die Texturkoordinaten eines Bildes bei WPF oben links den Ur-sprung (Punkt 0/0) haben und unten rechts den Punkt (1/1) besitzen, können mehrere Bilder nebeneinander gelegt werden, damit die Textur nicht zu pixelig wird. Erreicht wird das, indem die Texturkoordinaten grö-ßer eins sind oder kleiner null. Dann weiß das WPF, das dass Bild einfach wiederholt wird. Ob mehrere Bilder nebeneinander sind, wird mit den Va-riablen sumOfPicturesX und sumOfPicturesY errechnet. Die Breite der Scheibe wird durch die Anzahl der Pixel in x-Richtung des Bildes dividiert. So wird der Wert sumOfPicturesX gefüllt; der Wert sumOfPicturesY macht dasselbe mit der Höhe (y-Richtung). Diese Werte geben an wie viele Bilder in x und y Richtung liegen sollen. Die Variablen boundingRectX und boun-dingRectY erhalten die maximalen x- bzw. y-Werte des umschließenden Rechtecks der Glasscheibe. Nun wird für jeden Punkt der Glasscheibe in der Variablen meshGeometry3D.Positions der relative Punkt zu den Tex-turkoordinaten ausgerecht mit den beiden obigen Formeln. Zuerst wird der x- oder y-Wert des Scheibenpunkts in Relation zu der Gesamtschei-bengröße in x- bzw. y-Richtung gesetzt und dann wird dieser Wert mit der Gesamtzahl der Bilder multipliziert.

7.0 Umsetzung in eine DLL Seite 81

Die Texturkoordinaten werden dann der Variable TextureCoordinate des Objekts meshGeometry3D übergeben. Damit das Bild tatsächlich auf die Oberfläche aufgeklebt wird, muss der MaterialTyp TextureMaterial sein.

Bild 39: Strukturglas

Bild 40: Strukturglas mit Loch

8.0 Fazit Seite 82

8.0 Fazit

8.1 Komplexität des Algorithmus

Der inkrementelle Algorithmus besitzt eine worst-case Laufzeit von maxi-mal O(n²). Dazu muss allerdings eine unrealistische Punkteverteilung vor-liegen. In praktischen Tests beobachtet Heller [7] eine Laufzeit von O(n log n) für den inkrementellen Algorithmus. Allerdings trifft das nur auf normale Triangulierung, d. h. der Rand ist konvex und es gibt keine Lö-cher, zu. Mit nichtkonvexen Seiten und Löchern kann die Komplexität im Allgemeinen nur höher sein. In der Literatur wurde mit anderen Algorith-men für Löcher und nichtkonvexe Seiten im worst-case maximal O(n³) [12] erreicht. Im Normalfall dürfte die Komplexität deutlich besser sein, aber natürlich ist sie auch größer als O(n log n). Man nimmt eine Komple-xität zwischen O(n log n) und O(n²) an.

8.2 Probleme während der Umsetzung

Eigentlich traten selten Probleme auf. Jedoch traten manchmal seltsame Effekte bei der Triangulation auf. Die sind wahrscheinlich auf die Trans-formierung der Koordinaten in Pixel zurückzuführen. Bei Punkten, die nahe beieinander lagen, kam es zu Problemen, dass die Punkte für das WPF scheinbar nicht mehr voneinander zu unterscheiden waren. Das konnte aber, indem die Punkte auf 4 Nachkommastellen gerundet wurden, gelöst werden.

Auch die Normalen brachten einige Probleme mit sich, da einige Male auf-gefallen ist, dass die im WPF berechneten Normalen besser sind, wie die selbstberechneten. Also wurde im Programm häufiger auf die WPF berech-neten Normalen zugegriffen und Normalen nur selber berechnet, wo sie eindeutig waren.

Zum Bedauern nutzt das WPF die Directx Möglichkeiten nur wenig aus. Denn Directx bietet eigentlich einen Triangulationsalgorithmus, ebenso wie Shader7 und andere nützliche Werkzeuge. Damit würde das Ergebnis zum einen schneller erreicht werden, und zum andern wäre die Optik um eini-ges schöner. 7 Shader, auch als Schattierer bezeichnet, implementieren bestimmte Effekte bei der 3D-Computergrafik. Aus technischer Sicht bezeichnet „Shader“ denjenigen Teil eines Rende-rers, der für die Ermittlung der Farbe eines Objektes zuständig ist. Shader wurden ur-sprünglich für das Shading (die Berechnung der Beleuchtung) entwickelt.

8.0 Fazit Seite 83

Die Materialeigenschaften konnten nicht wirklichkeitsnah nachgebildet werden, da die Reflektions- und Refraktionseigenschaften nicht durch WPF nachgeahmt werden können. Hier fehlt eine Schnittstelle zu den Shadern aus Directx.

8.3 Abschließende Betrachtungen

Die Umsetzung eines Algorithmus für 2D-Oberflächen war erfolgreich. Je-doch bereitete es einigen Aufwand dies zu erreichen. In den bisherigen Testläufen funktionierte er tadellos.

Als nächstes sollen auch Fensterrahmen und –sprossen visualisiert wer-den. Zudem ist und muss auch noch die eine oder andere Erweiterung implementiert werden.

9.0 Anhang Seite 84

9.0 Anhang

9.1 Literaturverzeichnis

[1]

Biographie Boris Nikolaevich Delone

http://turnbull.dcs.st-and.ac.uk/~history/Mathematicians/Delone.html

[2]

Berg / Kreveld / Overmars / Schwarzkopf: Computational Geometry. Algo-rithms and Applications. Berlin: Springer-Verlag 2002

[3]

Bern / Dobkin / Eppstein: Triangulating polygons without large angles von 1992 auf der Website http://www.ics.uci.edu/~eppstein/pubs/geom-tri.html

[4]

Bern / Eppstein Mesh: Generation and optimal triangulation von 1992 un-ter http://www.ics.uci.edu /~eppstein/pubs/geomtri.html

[5]

Bourke: Triangulate Efficient Triangulation Algorithm Suitable for Terrain

Modelling or An Algorithm for Interpolating Irregularly-Spaced Data with

Applications in Terrain Modelling von 1989 http://local.wasp.uwa.edu.au/~pbourke/

[6]

Gumhold: Vorlesungsskript http://web.inf.tu-dresden.de/ST2/cg/mitarbeiter/Gumhold/surf_points.pdf

[7]

Heller: Triangulation algorithms for adaptive terrain modeling. In Proceed-ings of the 4th International Symposium on Spatial Data Handling, pages 163-174, July 1990.

9.0 Anhang 85

[8]

Hoschek / Lasser: Grundlagen der geometrischen Datenverarbeitung, 2. Auflage. Stuttgart: B.G. Teubner 1992

[9]

Klein: Algorithmische Geometrie, 2. Auflage. Springer-Verlag

[10]

Miszalok: 3-dimensionale Vektorgraphik auf der Website http://www.miszalok.de/

[11]

Miszalok: 3-dimensionale Vektorgraphik: Meshes auf der Website http://www.miszalok.de/

[12]

Shewchuck: Delaunay Refinement Mesh Generation, Ph.D. thesis, Techni-cal Report CMU-CS-97-137, School of Computer Science,

Carnegie Mellon University, Pittsburgh, Pennsylvania, 18 May 1997 auf der Website http://www.cs.cmu.edu/~jrs /jrspapers.html

[13]

Schwanecke: 2. Vorlesung auf der Website http:// www.mi.fh-wiesbaden.de/~schwan/Vorlesungen/InCG/

[14]

Schwentick: Effiziente Algorithmen 2004 17. Algorithmische Geometrie: Einleitung auf der Website http://www.mathematik.uni-marburg.de/~tick/Pages/Lehre/EA1/geomd.pdf

9.0 Anhang 85

9.2 Bilder

Bild 41: Bohrloch

Bild 42: Senkbohrloch

9.0 Anhang 86

Bild 43: Fenster mit Kreisbögen

Bild 44: Bogen

9.0 Anhang Seite 87

Bild 45: Nichtkonvexe Ecken (ein Testbild; keine Fensterform)

9.0 Anhang Seite 88

Bild 46: Testbild