Boolean Operators for Java 3D
Semesterarbeit von Urs Frick, Samuel Gerber
Fachhochschule Aargau FHA
University of Applied Science Aargau
Departement Technik
Studiengang Informatik
Betreuende Dozenten Prof. Dr. Manfred Vogel
Prof. Titus Jakob
Datum 27. Februar 2004
1
Zusammenfassung
Im Rahmen einer Semesterarbeit wurden die Booleschen Operatoren
f¨r Java 3D in einem abgeschlossenen Packet implementiert. Die Imple-
u
mentation setzt auf der Repr¨sentation von soliden K¨rpern als B-Reps
a o
an. Das Packet wurde im Anschluss an die Semesterarbeit in die Applika-
tion C3dQ der Firma CCT aus Griechenland integriert.
¨
In der nachfolgenden Dokumentation wird eine Ubersicht uber Repr¨sen-
¨ a
tationen von soliden K¨rpern gegeben und einige L¨sungsans¨tze disku-
o o a
tiert. Anschliessend wird die Implementation des Packetes im Detail be-
schrieben, sowie gezeigt wie das Packet verwendet werden kann.
1 Einleitung 4
1 Einleitung
Boolesche Operatoren k¨nnen auf solide K¨rper angewandt werden und Resul-
o o
tieren wiederum in soliden K¨rpern. Die Operationen die dabei zur Verf¨gung
o u
stehen sind die Vereinigung, die Differenz und die Schnittmenge. Diese Opera-
toren werden verwendet um neue K¨rperformen zu generieren. Diese Methode
o
findet in 3D Entwicklungsumgebungen eine breite Anwendung.
Im Rahmen unserer Semesterabeit ging es darum, diese Operatoren f¨r das
u
Produkt C3dQ von CCT zu implementieren. Bei C3dQ1 handelt es sich um einen
Viewer, der zur Darstellung von 3D-Modellen verwendet wird. Dieser Viewer un-
terst¨tzte bis Dato die Booleschen Operatoren nicht.
u
Bei der Integration der Booleschen Operatoren in das C3dQ wurden zwei L¨sungs-
o
ans¨tze vorgegeben. Die beiden L¨sungsans¨tze basieren auf verschiedenen Re-
a o a
pr¨sentationen der K¨rper im 3D Modell. Der eine Ansatzt setzt dabei auf der
a o
Repr¨sentation mittels B-Reps an, w¨hrend der zweite Ansatz auf einer L¨sung
a a o
mit NURBS2 basiert.
Als Ausgangslage diente uns die Diplomarbeit von Christian Miest und Peter
Langhart (“Boolean Operators For Nurbs Using Java 3D“). In dieser Diplom-
arbeit wurde der erstere Ansatz teils gel¨st. Die Implementation von Miest und
o
Langhart wies allerdings zu Beginn unserer Semesterarbeit noch Fehler auf. Die
Booleschen Operationen wurden im Zuge der Diplomarbeit in das Datenmodell
von C3dQ integriert, die Darstellung der resultierenden K¨rper war allerdings
o
fehlerbehaftet.
Die urspr¨ngliche Zielsetzung unserer Semesterarbiet war es, die Fehler in
u
der Bestehenden L¨sung zu eliminieren und uns anschliessend auf den L¨sungs-
o o
ansatz mit NURBS zu konzentrieren. Da die Form dieser Semesterarbiet nicht
ein spezifischer Auftrag sondern mehr eine Studie war, wurden die Zielsetzungen
in regelm¨ssigen Sitzungen angepasst. Grund f¨r diese Form war, dass man die
a u
Machbarkeit dieser Ans¨tze nicht garantieren konnte, insbesondere konnte man
a
nicht voraussagen, ob die L¨sungen in n¨tzlicher Frist realisiert werden konnten.
o u
Beim L¨sen des ersten Ansatzes bevorzugten wir es ein Packet losgel¨st von
o o
C3dQ zu entwickeln, dass aber anschliessend leicht in das Programm integriert
werden konnte. Das Packet setzte dabei auf dem L¨sungsansatz von Booleschen
o
Operatoren auf B-Reps an, wie sie in Java 3D verwendet werden um K¨rper o
darzustellen.
Die L¨sung mit NURBS blieb unrealisiert, da insbesondere die Behandlung von
o
Spezialf¨llen in der L¨sung mit B-Reps sehr viel Zeit in Anspruch nahm.
a o
Das Packet wird im Nachzug unserer Semesterarbeit von Samuel Gerber vor
Ort bei CCT in Griechenland in C3dQ integriert.
1 See 3d and Query
2 Non Unified Rational B-Splines
1 Einleitung 5
¨
Nachfolgend wird in diesem Bericht eine Ubersicht uber die Darstellung von
¨
o u ¨
soliden K¨rpern gegeben. Dieser Teil soll eine einf¨hrende Ubersicht uber ver-
¨
schiedene Repr¨sentationsarten von soliden K¨rpern im Raum geben. Ansch-
a o
liessend wird unser L¨sungsansatz ausf¨hrlich beschrieben.
o u
Dieses Dokument richtet sich an Personen, die das Packet f¨r ihre eigenen
u
Zwecke anwenden wollen, und tiefergreifendere Informationen wollen als die Ja-
vadokumentation bietet. Insbesondere ist diese Dokument an Personen gerichtet,
die an diese Arbeit ankn¨pfen wollen.
u
An dieser Stelle sei auch Dank an die betreuenden Dozenten M. Vogel und
T. Jakob ausgesprochen, die uns w¨hrend der Semesterarbeit mit Tat und Rat
a
unterst¨tzt haben.
u
2 Solid Modeling 6
2 Solid Modeling
F¨r eine breite Palette von Anwendungen wird die Repr¨sentation von Soli-
u a
den K¨rpern ben¨tigt. Oft ist es wichtig zwischen Innen- und Aussenseite ei-
o o
nes K¨rpers zu unterscheiden, z.B. um Kollisionen von K¨rpern zu detektieren,
o o
um Lichtbrechungen zu berechnen und entsprechend darzustellen oder bei der
Finite-Elemente-Analyse um Belastungen und Temperaturen zu berechnen.
¨
Die Nachfolgende Ubersicht stellt eine Zusammenfassung des Kapitels “Solid
Modeling“ aus dem Standardwerk von Foley [4] dar. Hier sollen die M¨glichkeint
o
zur Darstellung solider K¨rper beschrieben werden. Dabei wird insbesondere
o
auf die verschiedenen Repr¨sentationsarten eingegangen, wo grunds¨tzlich zwi-
a a
schen Boundary- und Spatial-Partitioning-Repr¨sentation unterschieden wird.
a
Erl¨utert wird auch die Eignung der jeweiligen Repr¨sentation f¨r Boolesche
a a u
Operatoren.
2.1 Repr¨sentationen
a
An die Repr¨sentation werden gewisse Anspr¨che gestellt. Je nach Anwendung
a u
muss man Kompromisse eingehen, da entweder auf Performance oder Genau-
igkeit verzichtet werden muss. Aus diesem Grund werden in einem Modeling-
System oft mehrere Repr¨sentationen verwendet.
a
Eine Repr¨sentation kann nur eine gewisse Klasse von Objekten darstellen.
a
Sehr anschaulich wird dies am Beispiel des Instance-Modeling dargestellt. Da-
bei k¨nnen nur eine definierte Anzahl von Primitiven instanziert und f¨r die
o u
Dartstellung verwendet werden.
Eine Repr¨sentation muss unmissverst¨ndlich sein. Bei der Repr¨sentation
a a a
eines W¨rfels mittels seiner Kannten ist z.B. nicht gegeben, ob es sich dabei um
u
ein Gitternetz oder um einen soliden W¨rfel handelt. Entsprechende Informa-
u
tionen m¨ssen in der Repr¨sentation enthalten oder grunds¨tzlich definiert sein.
u a a
Die Eindeutigkeit einer Repr¨sentation sagt aus, ob f¨r ein gegebenes Objekt
a u
die Repr¨sentation immer die selbe ist. Per Definition ist somit eine Repr¨sen-
a a
tation eindeutig, wenn f¨r jedes gegebene Objekt nur eine einzige Encodierung
u
m¨glich ist. Dabei ist das Objekt durch Lage, Form und Orientierung definiert.
o
Repr¨sentationen unterscheiden sich auch in der Genauigkeit in welcher
a
K¨per dargestellt werden k¨nnen. Oft k¨nnen K¨rper nur approximiert werden.
o o o o
Weiter unterscheiden sich Repr¨sentationen in der Einfachheit der Darstellung
a
und somit auch in der Kompaktheit. Kompakte Repr¨sentationen sind insbe-
a
sondere bei verteilten Systemen w¨nschenswert.
u
2.2 Boolesche Operatoren 7
2.2 Boolesche Operatoren
Die Booleschen Operatoren sind eine einfache und intuitive M¨glichkeit um
o
Objekte miteinander zu Verkn¨pfen. Aus den Booleschen Operatoren entstehen
u
neue Objekte in der Form von Vereinigungen, Differenzen und Schnitten der
Urspr¨nglichen Objekte wie in Abb. 1 gezeigt.
u
Abbildung 1: Boolesche Operatoren: (a) Objekte A und B, (b) A ∪ B, (c) A ∩
B, (d) A − B, (e) B − A
Als Resultat von Booleschen Operationen auf solide K¨rper erwartet man,
o
dass man wiederum einen soliden K¨rper erh¨lt. Dies ist bei den normalen Boo-
o a
leschen Operatoren nicht der Fall. Ber¨hren sich, z.B. zwei W¨rfel nur mit einer
u u
Grenz߬che so ist das Resultat ein Rechteck. Aus den normalen Booleschen Ope-
a
ratoren k¨nnen so solide K¨rper, Fl¨chen, Linien, Punkte und das Null-Objekt
o o a
entstehen.
F¨r unsere Zwecke verwenden wir deshalb die regul¨ren Booleschen Opera-
u a
toren [1]. Diese f¨hren zu einem soliden K¨rper oder zum Null-Objekt.
u o
2.3 Primitiven-Instanzierung
Bei der Primitiven-Instanzierung enth¨lt das Modelierungssystem einen be-
a
grenzten Satz von parametrisierten Objekten. Als Beispiel k¨nnen Zahnr¨der
o a
angegeben werden. Zahnr¨der werden definiert durch einen Radius, die Dicke,
a
einer Anzahl von Z¨hnen und die Form der Z¨hne. Die Repr¨sentation von
a a a
Primitiven-Instanzierung bietet keine M¨glichkeit Objekte mit Booleschen Ope-
o
ratoren zu kombinieren.
2.4 Sweep Repr¨sentation
a
Bei der Sweep Repr¨sentation werden 2D-Fl¨chen einer definierten Kurve ent-
a a
lang gef¨hrt. Den Raum den die Fl¨che ducrhf¨hrt, bildet den resultierenden
u a a
K¨rper. Folgt die 2D-Fl¨che einer linearen Bahn, so spricht man von einem
o a
translationalen Sweep oder Extrusions-Sweep (siehe Abb. 3). Bei Rotations-
Sweeps wird die 2D-Fl¨che um eine definierte Achse rotiert und bildet so einen
a
Rotationsk¨rper. Die generelle Form der Sweeps ¨ndert beim Entlangfahren der
o a
2.4 Sweep Repr¨sentation
a 8
Abbildung 2: Zwei Zahnr¨der definiert mit Primitive Instancing
a
2D-Fl¨che an der Kurve die Form der 2D-Fl¨che. Diese sog. generellen Sweeps
a a
resultieren nicht in einem Soliden K¨rper, wenn die 2D-Fl¨che koplanar zu sich
o a
selbst verschoben wird.
Das Resultat einer Booleschen Operation auf Sweeps stellt im Normalfall kei-
nen einfachen Sweep dar und eignet sich deshalb auch nicht zur Anwendung der
Booleschen Operatoren.
Abbildung 3: Sweeps. (a) 2D Fl¨chen um (b) translationale Sweeps und (c)
a
rotationale Sweeps zu generieren.
2.5 Boundary Repr¨sentation
a 9
2.5 Boundary Repr¨sentation
a
Bei der Boundary Representation3 werden solide K¨rper durch ihre Grenz-
o
fl¨chen definiert. Bei der Boundary Repr¨sentation werden oft Polygone als
a a
Fl¨chenelemente verwendet. Geschwungene Formen k¨nnen dadurch nur apro-
a o
ximiert werden.
Eine Spezialisierung der Boundary Repr¨sentation ist die Darstellung mit
a
Polyedern. Ein Polyeder ist ein solider K¨rper, der nur durch Polygone begrenzt
o
wird.
Eine weitere Spezialisierung ist die Winged-Edge Repr¨sentation. Hier wird
a
jede Kannte des K¨rpers durch Pointer auf die Eckpunkte der Kannte definiert.
o
Weiter verweist die Kante auf die anliegenden Fl¨chen und auf jeweils zwei
a
austretende Kanten an den Eckpunkten. Diese Repr¨sentation erm¨glicht es
a o
Punkte und Fl¨chen die mit einer Kante assoziiert sind in konstanter Zeit zu
a
bestimmen.
2.5.1 Ansatz f¨ r Boolesche Operatoren auf B-Reps
u
Der Ansatz die Booleschen Operatoren auf diese Repr¨sentationen anzuwen-
a
den besteht darin jedes Polygon zu untersuchen und n¨tigenfalls zu schneiden.
o
Anschliessend werden alle Polygone darauf hin untersucht, ob sie relativ zum
zweiten Objekt innerhalb oder ausserhalb liegen. Die Polygone werden klassi-
fiziert in Polygone, die komplett innerhalb, komplett ausserhalb oder auf der
Oberfl¨che des schneidenden K¨rpers liegen. Um ein Polygon zu klassifizieren
a o
folgt man der Normalen der Polygon߬che. Schneidet der Strahl dabei kein Po-
a
lygon der zweiten Figur, so befindet sich das Polygon ausserhalb. Schneidet
der Strahl ein Polygon, so werden die Richtungen der Normalenvektoren der
beiden Polygone mittels Kreuzprodukt untersucht. Ein positives Kreuzprodukt
indiziert, dass das originale Polygon innerhalb des Objektes liegt. Bei einem
negativen Kreuzprodukt liegt das originale Polygon ausserhalb des Objektes.
Die weiteren Polygone k¨nnen klassifiziert werden, indem man den Nachbarn
o
¨
von klassifizierten Polygonen folgt. Uberschreitet man keine Randpolygone, so
erh¨lt das Nachbarpolygon die gleiche Klassifizierung.
a
2.5.2 Nicht polyedrale B-Reps
Wie bereits erw¨hnt k¨nnen mit Polyedern gekr¨mmte Fl¨chen nur aproximiert
a o u a
werden. Ein Ansatz besteht darin, B-Reps mit Fl¨chen, die durch Kurven defi-
a
niert werden, darzustellen.
Um Boolesche Operatoren auf solche Fl¨chen anzuwenden, wurden Algorithmen
a
entwickelt, die mit nicht abgeschlossenen K¨rpern umgehen k¨nnen.
o o
3 kurz B-reps
2.6 Spatial-Partitioning Representations 10
2.6 Spatial-Partitioning Representations
Bei dieser Art der Repr¨sentation wird ein solider K¨rper in eine Sammlung
a o
von angrenzenden K¨rpern zerlegt, welche primitiver sind als der urspr¨ngliche
o u
K¨rper. Diese Primitiven k¨nnen in gr¨sse Position und Paramter variieren.
o o o
2.7 Cell-Decomposition
In einem System, in dem die Repr¨sentation der Cell-Decomposition angewen-
a
det wird, besteht ein Set von parametrisierten, primitiven Objekten, den sog.
Zellen. Diese Zellen werden “aneinander geklebt“ um den gew¨nschten K¨rper
u o
darzustellen. Diese Form der Repr¨sentation ist allerdings nicht eindeutig, d.h.
a
en K¨rper kann auf verschiedene Arten zusammengef¨gt werden.
o u
2.8 Spatial-Occupancy Enumeration
Die Spatial-Occupancy Enumeration ist ein Spezialfall der Cell-Decomposition.
Hier werden immer gleiche Zellen verwendet, die in einem Raster angeordnet
sind. Die Zellen werden Voxels (Volumen-Elemente) genannt, in Analogie zu den
Pixels. In dieser Darstellung wird also nur unterschieden, ob ein Voxel vorhanden
ist oder nicht. Alle K¨rper, die nicht aus Kanten rechtwinklig zu den Koordina-
o
tenachsen bestehen, m¨ssen mit dieser Darstellungsform approximiert werden.
u
Entsprechend ist f¨r eine saubere Darstellung eine hohe Aufl¨sung n¨tig, welche
u o o
eine grosse Datenmenge zur Folge hat.
Boolesche Operatoren lassen sich auf Objekte in dieser Repr¨sentation einfach
a
und intuitiv anwenden. Es handelt sich dabei um einfach Mengenoperationen
auf die Zellen.
Abbildung 4: Darstellung eines Torus mittels Spatial-Occupancy Enumeration
2.9 Octrees 11
2.9 Octrees
Octrees sind eine hierarchische Variante der Spatial-Occupancy. Das Bild wird
zuerst durch eine einzige Zelle repr¨sentiert, welche das ganze Objekt einsch-
a
liesst. Die Zelle wird so lange in Oktanten unterteilt, bis ein Oktant komplet
ausserhalb des Objektes liegt oder ein Grenzwert von Unterteilungen erreicht
worden ist. Ein Oktant wird je nach Deckungsgrad mit dem Objekt schwarz,
weiss oder grau markiert. Weisse und schwarze Oktanten werden nicht mehr
weiter unterteilt, w¨hrend graue Oktanten rekursiv untersucht werden m¨ssen.
a u
Diese Repr¨sentation kann in einem Baum dargestellt werden. Der Baum enth¨lt
a a
dabei weisse, schwarze und graue Knoten. Blattknoten k¨nnen dabei nur schwarz
o
oder weiss sein.
Die Booleschen Operationen lassen sich direkt im Baum anwenden.
Abbildung 5: Objekt dargestellt mittels (a) Spatial-Occupancy Enumeration
und (b) mittels Quadtree.
2.10 Constructive Solid Geometry
In einem CSG-Baum werden primitive Typen mit Booleschen Operatoren ver-
bunden. Die Blattkonten sind primitive Typen, w¨hrend Nicht-Blattknoten Boo-
a
lesche Operatoren oder Transformationen enthalten. Der Baum wird mit depth-
first-search traversiert um das Objekt darzustellen.
3 Aufbau des Packetes 13
3 Aufbau des Packetes
In folgendem Abschnitt wird das Packet beschrieben. Die einzelnen Klassen
werden kurz beschrieben und die wichtigsten Methoden erl¨utert. Anschlies-
a
send wird erkl¨rt wie das Packet verwendet werden kann.
a
F¨r Anwender dieses Packetes steht auch ein detaillierte Javadokumentation
u
uber das API4 des Packetes zur Verf¨gung.
¨ u
Das Packet arbeitet mit dem Java 3D 1.3 API [6]. Um dieses Kapitel zu
verstehen sollten grunds¨tzliche Kenntnisse von Java 3D vorhanden sind.
a
3.1 Die Klassen
Das Packet besteht aus den Klassen Triangle, Line, Ray, AnyBoolOp, Con-
vexBoolop, GeometryConverter, MyBoundingBox und SimpleMerge sowie dem
Interface J3Boolop und TriangleOptimizer.
Abbildung 8 zeigt das Klassendiagramm des Packetes.
3.1.1 Interface J3DBoolop
Das Interface Boolop ist die Schnittstelle um mit dem Packet zu arbeiten. Es
stellt folgende drei Methoden zur Verf¨gung:
u
• void calculateNewSurface(TriangleArray l, TriangleArray r, int operator,
TriangleOptimizer optimizer) Mit dieser Methode wird aus l und r eine
neue Ober߬che berechnet, mittels der Booleschen Operation die mit ope-
a
rator spezifiziert wird. Mit l und r wird bezeichnet welche Oberfl¨che links
a
(l) und welche rechts (r) des Operators steht. Die TriangleArrays m¨ssen
u
jeweils Farbe und Normalen haben, und die entsprechenden Capabilities
um die Koordinaten, Anzahl Punkte, Normalen sowie die Farbe zu lesen.
Das heisst es muss jeweils f¨r :
u
– ALLOW COORDINATE READ
– LLOW NORMAL READ
– ALLOW COUNT READ
– ALLOW COLOR READ
die Methode setCapability des jeweiligen TriangleArays aufgerufen wer-
den (falls diese noch nicht gesetzt sind). Der TriangleOptimizer Parameter
kann entweder null sein, wenn keine Optimierung der geschnittenen Drei-
ecke stattfinden soll. Oder es kann eine entsprechende Klasse ubergeben
¨
werden, die die resultierenden Dreiecke optimiert.
4 Application Programming Interface
3.1 Die Klassen 14
• void setOperator(int operator) Mit dieser Methode kann der Boolesche
Operator ge¨ndert werden. Die Operation ben¨tigt keine neue Berech-
a o
nung, es m¨ssen nur die entsprechenden Listen kombiniert werden.
u
• TriangleArray getResultingSurface() Diese Methode gibt die neu resul-
tierende Oberfl¨che zur¨ck die mit oben genannter Methode berechnet
a u
wurde.
Die beiden Klassen AnySurfaceBoolOp und ConvexSurfaceBoolOp implemen-
tieren diese Schnittstelle.
3.1.2 ConvexSurfaceBoolop
Diese Klasse kann verwendet werden um Boolesche Operatoren auf geschlos-
sene konvexe Ober߬chen anzuwenden. Diese Klasse funktioniert aufgrund des
a
verwendeten Algorithmus zur Bestimmung ob ein Dreieck innerhalb oder aus-
serhalb liegt, nur f¨r konvexe Oberfl¨chen. Ist dadurch jedoch performanter als
u a
die Klasse AnySurfaceBoolOp.
3.1.3 AnySurfaceBoolOp
Diese Klasse ist geeignet, um Boolesche Operatoren auf jegliche geschlossene
Ober߬chen anzuwenden. Da der Algorithmus, der bestimmt ob ein Dreieck
a
innerhalb oder ausserhalb liegt, aufwendiger ist erh¨ht sich die Laufzeit zur
o
Berechnug der neuen Oberfl¨che betr¨chtlich.
a a
3.1.4 Interface TriangleOptimzer
Dieses Interface wird verwendet um eine Liste von Dreiecken zu optimieren. Das
heisst, dass die Anzahl der Dreiecke vermindert wird, ohne die Geometrie, die
die Dreiecke darstellen, zu ver¨ndern.
a
3.1.5 SimpleMerge
Diese Klasse ist ein TriangleOptimizer der versucht benachbarte Dreiecke zu
vereinen, sofern dies M¨glich ist.
o
3.1.6 Triangle
Die Klasse Triangle representiert ein Dreieck im dreidimensionalen Raum. Mit
Hilfe dieser Klasse werden die Dreiecke der beiden Ober߬chen geschnitten und
a
in neue Dreicke unterteilt.
Die Klasse bietet Methoden an die, das Schneiden von Dreiecken, das Berech-
nen von Distanzen zu Punkten, sowie die Berechnung von Schnittpunkten mit
Linien und Strahlen erm¨glichen.
o
Ein Dreieck wird representiert durch (siehe auch Figur 7):
3.1 Die Klassen 15
Abbildung 7: Representation des Dreiecks
• Winkel um zu bestimmen ob ein Punkt innerhalb oder ausserhalb liegt:
cosA, cosB
• Linen der Kanten: lines[3] (Array aus drei Linien)
• Eckpunkte: p1, p2, p3
• Normalen f¨r jeden Eckpunkt: norm1, norm2, norm3
u
• Normale zur Ebene: normal
x
• Mathematische Representation einer Ebene: normal ∗ y = D
z
3.1.7 MyBoundingBox
Die Klasse MyBoundingBox wird ben¨tigt um zu uberpr¨fen, ob sich zwei Ob-
o ¨ u
jekte ber¨hren. Die BoundingBox ist achsenparallel zum Koordinatensystem,
u
dadurch werden nur zwei Punkte ben¨tigt um die Box zu repr¨sentieren. Des
o a
weiteren erlaubt die Achsenparallelit¨t eine performante Implementation der
a
Algorithmen um zu pr¨fen, ob sich zwei BoundingBoxen ber¨hren, sowie die
u u
Pr¨fung ob die BoundingBox ein anderes Objekt enth¨lt oder ber¨hrt.
u a u
3.1.8 Line
Die Klasse Line stehlt eine Linie im dreidimensionalen Raum dar. Eine Line
wird dargestellt durch einen Startpunkt sowie einem Vektor. Wird der Vektor
3.2 Verwendung des Packetes 16
zum Startpunkt addiert erh¨lt man den Endpunkt. Der Vektor zeigt also in
a
Richtung des Endpunkts und die L¨nge des Vektors entspricht der L¨nge der
a a
Linie.
3.1.9 Ray
Die Klasse Ray stellt einen Strahl im dreidimensionalen Raum dar. Ein Strahl
wird durch einen Startpunkt sowie eine Vektor, der die Richtung des Strahls
festh¨lt, repr¨sentiert.
a a
3.1.10 GeometryConverter
Die Klasse GeometryConverter ist eine Hilfsklasse die es erlaubt verschiedene
Java 3D GeometryArray Typen (QuadArray, TriangleStripArray, . . . ) in einen
Java 3D TriangleArray zu konvertieren.
3.2 Verwendung des Packetes
Um das Packet zu verwenden, muss eine Klasse die das Interface J3DBoolop im-
plementiert, erzeugt werden. Im Packet stehen dazu die Klasse AnySurfaceBoo-
lOp und ConvexSurfaceBoolOp zur Verf¨gung. Anschliessend kann die Methode
u
combineSurface aufgerufen werden. Mit getResultingSurface kann der resultie-
rende TriangleArray abgerufen werden. Die Methode combineSurface erwartet
zwei TriangleArrays. Um von anderen GeometryArrays umzuwandeln, steht die
Klasse GeometryConverter zur Verf¨gunng.
u
Das folgende Code Fragment soll die Anwendung illustrieren.
...
TriangeStripArray tsa = someSurface();
QuadStripArray qsa = anOtherSurface();
TriangleArray l = GeometryConverter.createTriangles(tsa);
//If tsa has no color call:
//Color3f cl=new Color3f(1, 0, 0);
//TriangleArray l = GeometryConverter.createTriangles(tsa, cl);
TriangleArray r = GeometryConverter.createTriangles(qsa);
//If qsa has no color call:
//Color3f cr=new Color3f(0, 1, 0);
//TriangleArray r = GeometryConverter.createTriangles(qsa, cr);
//Set the needed Capabilities
l.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
l.setCapability(GeometryArray.ALLOW_NORMAL_READ);
l.setCapability(GeometryArray.ALLOW_COUNT_READ);
l.setCapability(GeometryArray.ALLOW_COLOR_READ);
r.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
r.setCapability(GeometryArray.ALLOW_NORMAL_READ);
3.2 Verwendung des Packetes 17
r.setCapability(GeometryArray.ALLOW_COUNT_READ);
r.setCapability(GeometryArray.ALLOW_COLOR_READ);
//Create a Boolen Operator and calculate the Differnce from l to r
J3DBoolop bool = new AnySurfaceBoolOp();
bool.combineSurfaces(l,r J3DBoolop.DIFFERENCE, null); //l - r
TriangleArray res = bool.getResultingSurface();
....
3.2.1 Fehler
Bei Ober߬chen die aus sehr kleinen Dreiecken bestehen kann es vorkommen,
a
dass Dreiecke falsch klassifiziert werden. Dadurch erscheinen nach der Boole-
schen Operation, Dreiecke die nicht dargestellt werden sollten. Im Kapitel 4.5
wird noch detailliert auf diese Fehler eingegangen.
3.2 Verwendung des Packetes 18
Abbildung 8: Klassendiagramm
4 Beschreibung der Algorithmen 19
4 Beschreibung der Algorithmen
In diesem Kapitel wird im Detail auf die Algorithmen eingegangen.
Der Leser sollte mit dem Java 3D 1.3 API [6] vertraut sein, da Klassen aus
diesem API verwendet werden. Die Prinzipien die den Algorithmen zugrunde
liegen, ben¨tigen jedoch keine Kenntnisse des Java 3D 1.3 API. Kenntnisse in
o
linearer Algebra sind jedoch von Vorteil um die Algorithmen zu verstehen.
4.1 Allgemeine Funktionsweise
Der allgeimene Ansatz ist leicht erkl¨rt, er besteht grunds¨tzlich aus drei Schrit-
a a
ten. Nehmen wir an wir wollen die Ober߬chen A und B schneiden, dann sieht
a
der Ablauf wie folgt aus:
1. Es wird jedes Dreick von A mit B geschnitten, anschliessend jedes von B
mit A.
2. Die neuen Dreieck von A werden bez¨glich der Orientierung zu B in Listen
u
f¨r A einsortiert (innen von B, ausssen von B, sowie Spezialf¨llen wenn
u a
zwei Dreiecke koplanar sind) und umgekehrt.
3. Die Dreiecke werden aus den verschiedenen Listen (je nach Operatoren)
zu einer neuen Oberfl¨che zusammengef¨gt.
a u
Diese drei Schritte sind sowohl in der Klasse AnySurfaceBoolOp wie auch in
der Klasse ConvexSurfaceBoolOp gut ersichtlich. Folgende Codeauschnitte aus
AnySurfaceBoolOp sollen dies verdeutlichen.
Schneiden und Bestimmung der Orientierung (einsortieren in die entspre-
chenden Listen):
private void calculateNewSurface(List origL, List origR,
MyBoundingBox boundsL,
MyBoundingBox boundsR) {
//List of new triangles with cuts
List newLeft = new LinkedList();
List newRight = new LinkedList();
//Split left TriangleArray in inside
//and outside right TriangleArray
split(origL, origR, boundsR, newLeft);
//Split right TriangleArray in inside
//and outside left TriangleArray
split(origR, origL, boundsL, newRight);
4.1 Allgemeine Funktionsweise 20
//Check orientation of triangles from right Triangles
decideOrientation(origL, newRight, outsideR, insideR,
bothSameR, bothDiffR, boundsL);
//Check orientation of triangles from left Triangles
decideOrientation(origR, newLeft, outsideL, insideL,
bothSameL, bothDiffL, boundsR);
}
Zusammenstellen der entsprechenden Listen:
private List difference() {
List result = new LinkedList(outsideL);
Iterator it = insideR.iterator();
while (it.hasNext()) {
Triangle tmp = (Triangle) it.next();
result.add(tmp.invert());
}
result.addAll(bothDiffL);
return result;
}
private List intersect() {
List result = new LinkedList(insideL);
result.addAll(insideR);
result.addAll(bothSameL);
return result;
}
private List union() {
List result = new LinkedList(outsideL);
result.addAll(outsideR);
result.addAll(bothSameL);
return result;
}
4.1.1 Zusamenstellung der Listen
Im Programm verwenden wir folgende acht Listen:
• outsideL
• insideL
• bothSameL
• bothDiffL
4.2 Alogrithmen in der Klasse Triangle 21
• outsideR
• insideR
• bothSameR
• bothDiffR
In der Liste outsideL sind alle Dreiecke der linken Oberf¨che, welche ausser-
a
halb der rechten Ober߬che liegen. In der Liste outsideR sind alle Dreiecke der
a
rechten Oberf¨che, welche ausserhalb der linken Oberfl¨che liegen.
a a
In der Liste insideL sind alle Dreiecke der linken Oberf¨che, welche innerhalb
a
der rechten Ober߬che liegen. In der Liste insideR sind alle Dreiecke der rechten
a
Oberf¨che, welche innerhalb der linken Oberfl¨che liegen.
a a
In bothSameL werden jene Dreiecke von der linken Ober߬che gespeichert,
a
welche nicht eindeutig innerhalb oder ausserhalb der rechten Ober߬che liegen
a
(z.B. bei konplanren Dreiecken), aber aufgrund des Vergleiches der Normalen
nur bei der Bildung der Schnittmenge oder der Vereinigung miteinbezogen wer-
den m¨ssen.
u
In bothDiffL werden jene Dreieck gespeichert die ebenfalls nicht eindeutig
innerhalb oder ausserhalb liegen, aber aufgrund des Vergleiches der Normalen
nur bei der Differenz ber¨cksichtigt werden m¨ssen.
u u
In bothSameR und bothDiffR werden die Dreieck von der rechten Oberfl¨che
a
bez¨glich der linken, analog zu bothSameL und bothDiffL, gespeichert.
u
Dies ergibt nun folgende Kombinationen der Listen:
bei Union: outsideL, outsideR, und bothSameL
bei Intersect: insideL, insideR und bothSameL
bei Difference: outsideL, insideR (hier m¨ssen bei insideR noch die Nor-
u
malen invertiert werden da diese in die entgegengesetzte Richtung zeigen),
und botDiffL
4.2 Alogrithmen in der Klasse Triangle
In der Klasse Triangle geschieht das eigentliche Schneiden der Dreieicke. Die
Schnitte werden in der Methode cut, mithilfe einiger Methoden die hier be-
schrieben werden, berechnet.
4.2 Alogrithmen in der Klasse Triangle 22
4.2.1 Berechnug des Schnittpunktes Line - Ebene
Methode:
public Point3f intersection(Line l, float intersectTol, float insideTol)
Aufgrund der Darstellung des Dreieckes und der Linie (siehe auch Kapitel
3.1) kann mit der Gleichung (1) lamda berechnet werden.
N ormale ∗ Startpunkt
lamda = D − (1)
Richtung ∗ N ormale
Liegt nun lamda zwischen 0 und 1 liegt ein Schnittpunkt mit der Ebene vor. Es
ist aber noch nicht bestimmt ob dieser innerhalb des Dreieckes liegt.
Mit dem Parameter intersectTol kann bestimmt werden wieveil lamda unter 0
oder uber 1 sein kann um trotzdem noch zu schneiden.
¨
4.2.2 Bestimmung der Lage eines Schnittpunktes
Methoden:
public bool liesInside(Point3f p, float intersectTol, float insideTol)
private bool liesInside(Point3f p, float insideTol)
Die Lage eines Punktes wird aufgrund der Cosinuswerte der Winkel berech-
net (siehe auch Abbildung 9):
• cosA1 = winkel zwischen linie 0 und der linie die mit p1 und p gebildet
wird
• cosA2 = winkel zwischen linie 2 und der linie die mit p1 und p gebildet
wird
• cosB1 = winkel zwischen linie 0 und der linie die mit p2 und p gebildet
wird
Wenn nun cosA1 und cosA2 kleiner cosA sind sowie cosB1 kleiner als cosB,
liegt der Punkt innerhalb, ansonsten ausserhalb. Mit dieser Methode wird jedoch
nicht gepr¨ft, ob der Punkt auch in der Ebene liegt. Dies ist im Fall eines
u
Schnittpunktes auch nicht n¨tig. Deshalb gibt es zwei Methoden um die Lage
o
eines Punktes zu bestimmen. Die eine ist public und berechnet zuerst noch die
Distanz zur Ebene und anschliessend die Winkel. Die andere ist privat und
berechnet die Distanz nicht.
Der Parameter insideTol bestimmt um wieviel cosA und cosB beim Vergleich
vergr¨ssert werden.
o
4.2.3 Orientierung zu einem anderen Dreieck
Methode:
public int getOrientationTo(Triangle t, float tol)
4.2 Alogrithmen in der Klasse Triangle 23
Abbildung 9: Bestimmung der Lage
Es wird die Distanz von jedem Punkt des zu bestimmenden Dreiecks zu dem
bestimmenden Dreieck gemessen (siehe auch Kapitel 4.2.4). Wenn alle positiv
sind, liegt das Dreieck ausserhalb. Wenn alle negativ sind, liegt das Dreieck
innerhalb. In allen anderen F¨llen wird gepr¨ft ob die Dreiecke koplanar sind.
a u
Ist dies der Fall wird aufgrund der Normalen bestimmt ob das Dreieck zur
Differenz oder zur Schnittmenge geh¨rt.
o
Der Parameter tol gibt an, wie gross die Distanz sein muss damit der Punkt als
nicht auf dem Dreieck liegend klassifiziert wird.
4.2.4 Berechnung der Distanz zu einem Punkt
Methode:
public double distance(Point3f p)
Die Distanz wird berechnet mit der Gleichung (2).
normal ∗ punkt − D = dist (2)
Die Distanz ist vorzeichenbehaftet, das heisst wenn der Punkt zu dem die Di-
stanz gemessen wird in der Richtung der Normalen liegt, ist die Distanz positiv
ansonsten negativ.
4.2.5 Bestimmung der neu entstehenden Dreiecke
Methode:
private List makeCut(Triangle t, float intersectTol, float insideTol, float same-
PointTol, float orientTol)
4.2 Alogrithmen in der Klasse Triangle 24
Vorgehen:
Triangle A = zu schneidendes Dreieck
Triangle B = schneidendes Dreieck
1. Mit allen Linien von A wird untersucht ob ein Schnittpunkt in B entsteht.
Falls ein Schnittpunkt entsteht, wird uperpr¨ft ob der Schnittpunkt nicht
¨ u
ein Eckpunkt von A ist. Liegt der Schnittpunkt nicht auf einem Eckpunkt,
wird der Schnittpunkt in Verbindung mit der Line, auf der er liegt, ge-
speichert (darum ein Set key = Nummer der Line, value = Schnittpunkt).
Ansonsten wird der Schnittpunkt als Eckpunkt gespeichert.
2. Falls in 1 nicht schon zwei verschieden Schnittpunkte gefunden wurden,
wird mit allen Linen von B gepr¨ft, ob ein Schnittpunkt in A ensteht. Falls
u
in 1 schon ein Schnittpunkt entsteht, wird uberpr¨ft ob der gefundene
¨ u
Schnittpunkt nicht schon existiert. Falls dieser nicht schon existiert, wird
ein Schnittpunkt der innerhalb von A liegt gespeichert.
Aus 1 und 2 entstehen nun folgende f¨nf F¨lle wie das Dreieck geschnitten
u a
werden kann (siehe auch Abbildung 10, das hellere Dreieck ist dasjenige das
geschnitten wird):
1. Zwei Punkte auf Kanten
2. Ein Punkt auf einer Kante, einer innerhalb
3. Zwei Punkte innerhalb
4. Ein Punkt auf einem Eckpunkt, einer auf der Kante
5. Ein Punkt auf einem Eckpunkt, einer innerhalb
4.2.6 Die Methode cut
In der Methode cut wird die Methode makeCut f¨r jedes Dreieck in der Liste
u
cutted augerfuen. Zu beginn befindet sich in der Liste cutted nur ein Dreieck (die
eigene Referenz). In der Methode makeCut wird das Dreieck nun, mit Hilfe der
in den obigen Abschnitten beschriebenen Methoden, geschnitten. Als Resultat
wird eine Liste mit den geschnittenen Dreiecken zur¨ckgegeben. In der Liste
u
cutted werden diese anstelle des vorherigen Dreieckes eingetragen.
Die Methode cut:
public void cut(Triangle t, float intersectTol, float insideTol,
float samePointTol, float orientTol) {
List newCutted = new LinkedList();
Iterator it = cutted.iterator();
while (it.hasNext()) {
Triangle current = (Triangle) it.next();
newCutted.addAll(current.makeCut(t, intersectTol, insideTol,
4.3 Algorithmen in der Klasse AnySurfaceBoolOp 25
Abbildung 10: Schnittf¨lle: (a) Fall 1, (b) Fall 2, (c) Fall 3, (d) Fall 4, (e) Fall 5
a
samePointTol, orientTol));
it.remove();
}
cutted = newCutted;
}
4.3 Algorithmen in der Klasse AnySurfaceBoolOp
In der Klasse AnySurfaceBoolOp werden alle Dreieck geschnitten und in die
richtigen Listen eingeordnet. Sind die neuen Dreiecke berechnet, wird ein Tri-
angleArray erstellt, der die neue Ober߬che representiert.
a
4.3.1 Schneiden der Dreiecke
Methode:
private void split(List origL, List origR, MyBoundingBox rBounds, List new-
Left)
In der Methode split wird jedes Dreieck aus der Liste origL (der linken
Ober߬che) mit allen Dreiecken aus der Liste origR (der rechten Ober߬che)
a a
geschnitten und anschliessend in die Liste newLeft eingetragen. Die Bounding-
Box wird ben¨tig um zu uberpr¨fen, ob uberhaupt ein Schnitt m¨glich ist.
o ¨ u ¨ o
Diese Methode wird zweimal aufgerufen, da immer nur die Dreiecke aus origL
geschnitten werden.
Da die geschnittenen Dreiecke in einer separaten Liste abgespeichert werden,
bleibt die urspr¨ngliche Oberfl¨che erhalten. Diese wird sp¨ter auch noch ben¨tigt
u a a o
um das Einordnen der Dreiecke in die entsprechende Listen zu vereinfachen und
zu beschleunigen.
4.3 Algorithmen in der Klasse AnySurfaceBoolOp 26
4.3.2 Einordnen der Dreieck
Methode:
private void decideOrientation(List otherSurface, List toDecide, List toAddOut,
List toAddIn, List toAddSame, List toAddDiff, MyBoundingBox bounds)
Hier wird f¨r jedes Dreieck aus toDecide (der Oberfl¨che deren Dreiecke
u a
einsortiert werden sollen) ein Strahl berechnet der dem Mittelpunkt des Drei-
eckes entspringt und in Richtung der Normalen des Dreieckes zeigt. Nun wird
in jedem Dreieck aus der Liste otherSurface (der Ober߬che zu der die Dreiecke
a
einsortiert werden sollen) nach einem Schnittpunkt gesucht. Das Dreieck aus
der Liste otherSurface das am n¨chsten bei dem momentan zu vergleichenden
a
Dreieck ist, wird gespeichert.
Am Ende wird aufgrund des gefundenen Dreieckes die Orientierung entschieden.
Wurde kein Dreieck vom Strahl getroffen, liegt das Dreieck ausserhalb. Wurde
eines getroffen, muss aufgrund des Vergleiches der Normalen entschieden wer-
den. Dies geschieht mit Hilfe des Vektorproduktes. Dies liefert den Cosinus des
Winkels zwischen den beiden Geraden. Nun werden vier F¨lle unterschieden:
a
1. cosinus = 1 und geringe Distanz =¿ Liste f¨r Differenz
u
2. cosinus = −1 und geringe Distanz =¿ Liste f¨r Schnittmenge
u
3. cosinus >= 0 =¿ Innerhalb
4. cosinus < 0 =¿ Ausserhalb
4.3.3 Toleranzen
In der Klasse AnySurfaceBoolOp sind folgende Toleranzen definiert:
• INTERSECTION TOLERANCE bestimmt bei Ber¨hrung zweier Dreie-
u
cke, ob ein Schnitt stattfindet oder nicht.
• ORIENTATION TOLERANCE bestimmt wie sensitiv die Lage zu einem
anderen Dreieck berechnet wird.
• ORIENTATION TOLERANCE2 bestimmt den Schwellenwert, ab wann
zwei Dreiecke als koplanar gelten. Diese Einordnung erfolgt aus einem Ver-
gleich der Normalen. Ist das Kreuzprodukt der beiden Normalen gr¨sser o
als dieser Schwellenwert oder kleiner als das Negative dieses Schwellenwer-
tes, gelten die Dreiecke als koplanar.
• INSIDE TOLERANCE bestimmt ob ein Punkt noch innerhalb oder aus-
serhalb eines Dreieckes liegt.
• SAMEPOINT TOLERANCE bestimmt wie nahe zwei Punkte liegen m¨ssen,
u
um als die selben betrachtet zu werden.
4.4 Algorithmen in der Klasse ConvexSurfaceBoolOp 27
All diese Toleranzen beinflussen, wie die Dreiecke geschnitten und sortiert wer-
den. Die Default-Werte sollten nicht ver¨ndert werden, da diese f¨r die meis-
a u
ten F¨lle optimal sind. Die Default-Werte wurden mittels mehreren Tests eru-
a
iert. Sollten die Werte trotzdem einmal ver¨ndert werden m¨ssen, kann auf
a u
diese direkt zugegriffen werden, da die Felder public sind. Sie sollten jedoch nur
ver¨ndert werden, wenn man den Code, in dem mit den Toleranzen gerechnet,
a
wird eingehend studiert hat. Ausser der Toleranz ORIENTATION TOLERANCE2,
werden alle f¨r Aufrufe von Methoden aus der Klasse Triangle verwendet (siehe
u
Kapitel 4.2);
4.4 Algorithmen in der Klasse ConvexSurfaceBoolOp
Die Klasse ConvexBoolop erlaubt nur konvexe Ober߬chen mit Booleschen Ope-
a
ratoren zu berechnen. Es wird jedoch nicht uberpr¨ft ob dies der Fall ist. Bei
¨ u
Berechnungen mit nicht konvexen Ober߬chen entstehen daher falsche Resul-
a
tate. Das Schneiden der Dreiecke erfolgt wie bei der Klasse AnySurfaceBoolOp
(siehe Kapitel 4.3), daher wird hier nur auf das Einordnen der Dreiecke einge-
gangen.
4.4.1 Einordnen der Dreieck
Methode:
private void decideOrientation(List otherSurface, List toDecide, List toAddOut,
List toAddIn, List toAddSame, List toAddDiff, MyBoundingBox bounds)
Die Methode heisst gleich jedoch wird zur Bestimmung der Lage ein anderer
Algorithmus verwendet.
Es wird jedes Dreieck aus der Liste toDecide mit den Dreiecken aus der Liste
otherSurface verglichen. Dies geschieht mittels der Methode getOrientationTo
aus der Klasse Triangle (siehe Kapitel 4.2). Wird nun ein Dreieck als ausserhalb
oder zur gemeinsamen Differenz oder zur gemeinsamen Schnittmenge markiert,
wird es sogleich in die entsprechende Liste eingeordnet und mit dem n¨chs- a
ten fortgefahren. Das Dreieck wird als innerhalb eingeordnet, falls es bei allen
Vergleichen nie als ausserhalb eingordnet wurde.
4.4.2 Toleranzen
In der Klasse ConvexSurfaceBoolOp sind folgende Toleranzen definiert:
• INTERSECTION TOLERANCE bestimmt bei Ber¨hrung zweier Dreie-
u
cke, ob ein Schnitt stattfindet oder nicht.
• ORIENTATION TOLERANCE bestimmt wie sensitiv die Lage zu einem
anderen Dreieck berechnet wird.
• INSIDE TOLERANCE bestimmt, ob ein Punkt noch innerhalb oder aus-
serhalb eines Dreieckes liegt.
4.5 Fehler und Performance 28
• SAMEPOINT TOLERANCE bestimmt wie nahe zwei Punkte liegen m¨ssen
u
um als die selben betrachtet zu werden.
All diese Toleranzen beinflussen, wie die Dreiecke geschnitten und sortiert wer-
den. Die Default-Werte sollten nicht ver¨ndert werden, da diese f¨r die meis-
a u
ten F¨lle optimal sind. Die Default-Werte wurden mittels mehreren Tests eru-
a
iert. Sollten die Werte trotzdem einmal ver¨ndert werden m¨ssen, kann auf
a u
diese direkt zugegriffen werden, da die Felder public sind. Sie sollten jedoch nur
ver¨ndert werden wenn man den Code, in dem mit den Toleranzen gerechnet
a
wird, eingehend studiert hat.
Alle Toleranzen werden f¨r Aufrufe von Methoden aus der Klasse Triangle ver-
u
wendet (siehe Kapitel 4.2);
4.5 Fehler und Performance
Die Berechnung von Booleschen Operation aufgrund von B-reps ist numerisch
gesehen nicht optimal [3]. Bei unserer Implementation k¨nnen wenn Boolesche
o
Operationen auf Ober߬chen mit kleinen Dreiecken angewandt werden, manch-
a
mal Fehler auftreten. Genau genommen k¨nnen diese Fehler auftreten, sobald
o
Dreiecke verwendet werden, bei denen zwei Punkte sehr nahe beieinander liegen.
Wir vermuten, dass aufgrund der geringen Distanzen zwischen den Punkten der
Dreiecke, die Normalen nicht gen¨gend exakt bestimmt werden k¨nnen.
u o
Um dieses Problem zu l¨sen, gibt es verschiedene Ans¨tze. Anstelle mit float
o a
Werten zu rechnen, k¨nnte man double Werte verwenden.
o
Ein anderer Ansatz w¨hre zu uberpr¨fen, ob die resultierenden Dreiecke zusam-
a ¨ u
menh¨ngend sind. Dies k¨nnte zum Beispiel mit Hilfe eines Graphen geschehen,
a o
der die Dreiecke verbindet. Diejenigen Dreiecke die nun keine Verbindungen im
Graphen haben, k¨nnten so rausgefiltert werden.
o
Ein schon teilweise implementierter Ansatz ist, dass die Dreiecke, die aus ei-
ner Booleschen Operation resultieren, reduziert werden. Dazu bietet das Inter-
face TriangleOptimizer jetzt schon die M¨glichkeit. Bei der Booleschen Ope-
o
ration kann ein Objekt, das diese Interface implementiert, mitgegeben werden.
W¨hrend der Berechnug wird f¨r jede Liste des J3DBoolOp die Methode optim-
a u
ze(List l) des TriangleOptimizer aufgerufen. Dadurch kann vermieden werden,
dass solche ung¨nstige Dreiecke entstehen.
u
Bez¨glich Performance haben wir einiges ausprobiert und implementiert. So
u
verwenden wir BoundingBoxes um zu uberpr¨fen ob ein Schnitt uberhaupt n¨tig
¨ u ¨ o
ist. Auch beim Klassifizieren der Dreiecke kommen die BoundingBoxes zu Ein-
satz.
Des weiteren ertellten wir eine Variante, bei der die geschnittenen Dreiecke
als Graphen dargestellt werden. Da die geschnittenen Dreiecke bez¨glich Lage
u
bestimmt sind, kann nun mittels depth-first-search uber den Graphen iteriert
¨
werden und so alle Dreiecke eingeordnete werden. Das Aufbauen des Graphen
war jedoch aufwendiger als die Berechnung, die dadurch eingespart wurden. So-
4.5 Fehler und Performance 29
mit ist dieser L¨sungansatz bez¨glich Performance nicht zu empfehlen.
o u
Der Ansatz bietet jedoch die M¨glichkeit den oben beschriebenen Fehler zu
o
vermeiden, da die Dreiecke nicht uber einen Vergleich der Normalen eingeord-
¨
net werden. Aufgrund von Zeitmangel haben wir diesen Ansatz nicht weiter
verfolgt. Er k¨nnte jedoch einfach in das bestehende Packet integriert werden.
o
Dazu muss nur eine neue Klasse, die das Interface J3DBoolOp implementiert,
geschrieben werden. Das Schneiden kann aus den Klassen AnySurfaceBoolOp
oder ConvexSurfaceBoolOp ubernommen werden. Das heisst, einzig die Metho-
¨
de decideOrientation der Klasse AnySurfaceBoolOp oder ConvexSurfaceBoolOp
m¨sste ge¨ndert werden. Zus¨tzlich musste in der Klasse Triangle noch uber-
u a a ¨
pr¨ft werden, ob die Dreiecke nach einem Schnitt die richtige Klassifizierung
u
aufweisen. Die jetzige Implementation st¨tzt sich nicht darauf, dass die Dreiecke
u
nach einem Schnitt richtig Klassifiziert sind. Daher kann nicht davon ausgegan-
gen werden, dass die Klassifizierung stimmt.
Ein Problem bei diesem Ansatz ist, dass Dreiecke die koplanar sind, nicht in die
richtige Liste eingeordnet werden k¨nnen (da das einordnen uber die Schnei-
o ¨
denden Dreiecke erfolgt, zu diesem Zeitpunkt weiss mann nicht ob das Dreieck
allenfalls koplanar ist). Dieser Fall tritt zwar nur ein wenn zwei Ober߬chen sich
a
ber¨hren, doch auch dieser Spezialfall sollte abgedeckt werden.
u
Optimierungen bez¨glich Performance und Speicherbedarf, k¨nnen allenfalls
u o
noch durch umschreiben des Codes erzielt werden. Wie zum Beispiel das beim
Schneiden der Dreieck zweimal durch alle Dreiecke der beiden Ober߬chen ite-
a
riert wird.
Auch die Liste zum speichern der geschnitten Dreiecke ist nicht unbedingt not-
wendig.
Durch solche Optimierungen wird jedoch die Leserlichkeit des Codes vermin-
dert, weshalb wir davon abliessen.
5 Testumgebungen 30
5 Testumgebungen
Um das Packet zu testen und nach Fehler zu suchen, schrieben wir einige kleine
Programme.
5.1 Darstellung in Mapple
In der Klasse DebugUtils befindet sich ein Methode mit der eine Liste von Drei-
ecken in ein Maple5 Befehl geschrieben werden kann. In Maple muss dann noch
die Bibiliothek plot (Befehl with(plots):) eingebunden werden. Anschliessend
k¨nnen die Dreiecke in Mapple dargestellt werden. Dies war hilfreich um zu
o
testen, ob die Dreiecke richtig geschnitten und eingeordnet wurden.
5.2 Kontrolle der Schnitte
Die Klasse TriangleTest schneidet Dreiecke so, dass alle m¨glichen Schnitf¨lle
o a
auftretten und schreibt f¨r jeden Schnitfall ein File mit dem Maple-Befehl, wel-
u
cher die geschnittenen Dreiecke darstellt. So kann uberpr¨ft werden, ob die
¨ u
Schnitte richtig berechnet werden.
5.3 Das Visualisationstool
Um das Packet Debugen zu k¨nnen, entwickelten wir ein kleines Programm das
o
verschiedene Ober߬chen darstellen und kombinieren kann (siehe auch Abb.
a
11).
Das Programm bietet ausser dem Darstellen der urspr¨nglichen Oberfl¨chen
u a
und der resultierende Ober߬che noch einiges mehr:
a
• Die Objekte k¨nnen interaktiv per Maus verschoben, rotiert und gezoomt
o
werden
• Solide oder Drahtgitter Darstellung
• Einstellen der Toleranzen
• Interaktive Wahl des Booleschen Operators
• Statistik uber Laufzeit der Berechnung.
¨
5.3.1 Kurze Bedinungsanleitung
Das obere Menu zeigt die Oberfl¨chen an die f¨r den linken (rot) und den rechten
a u
(gr¨n) Operand gew¨hlt werden k¨nnen. Durch Anklicken wird die entsprechen-
u a o
de Ober߬che im oberen Fenster dargestellt.
a
5 Mathematikprogramm: http://www.maplesoft.com/
5.3 Das Visualisationstool 31
Das untere Menu bietet acht verschiedene Schalt߬chen an. Die Erste ist
a
ein Dropdown Menu mit dem der Operator festgelegt werden kann. Der But-
ton Calculate berechnet die gew¨nschte Oberfl¨che. Die berechnete Oberfl¨che
u a a
wird dan im unteren Fenster dargestellt. Mit dem Button Settings k¨nnen die
o
Toleranzen eingestellt werden, und mit Show Statistics wird die Statistik f¨r
u
die letzte Berechnung angezeigt. Mit den beiden untersten Schalt߬che kann
a
die Geometrie aus dem unteren Fenster f¨r die gr¨ne oder rote Oberfl¨che, im
u u a
oberen Fenster, ubernommen werden.
¨
In beiden Fenster kann mit der Maus:
• Mit gedr¨ckter rechter Maustaste die Oberfl¨che (¨ber der sich der Maus-
u a u
zeiger zum Zeitpunkt des dr¨cken befand)rotiert werden.
u
• Mit gedr¨ckter linker Maustatse die Oberfl¨che verschoben werden.
u a
• Mit gedr¨ckter linker Maustaste wird durch bewegen der Maus die ganze
u
Szene gezoomt.
5.3 Das Visualisationstool 32
Abbildung 11: Visualisierung
6 Schluss 33
6 Schluss
Den Ansatz, f¨r den wir uns zu Beginn der Semesterarbeit entschieden haben,
u
das Package losgel¨st von C3dQ zu entwickeln, hat zu einem generell einsetzt-
o
baren Package mit einer einfachen Schnittstelle gef¨hrt.
u
Das Packet weist allerdings auch am Schluss der Semesterarbeit noch kleine-
re Fehler auf, die in der Dokumentation zum Code erw¨hnt wurden. Wir k¨nnen
a o
an dieser Stelle lediglich Vermutungen f¨r m¨gliche Fehlerquellen angeben.
u o
Der L¨sungsansatz mit NURBS wurde im Zuge dieser Semesterarbeit kaum
o
behandelt. Wir haben einige Literatur uber NURBS [2][5] gelesen, hatten je-
¨
doch zuwenig Zeit uns vertieft in dieses Thema einzuarbeiten. Daher k¨nnen
o
wir so auch keine Aussage uber die Machbarkeit eines solchen Ansatzes in der
¨
Form einer Semesterarbeit machen. Wir empfehlen darum diesbez¨glich noch
u
Nachforschungen zu t¨tigen.
a
Das Packet wird im Anschluss an die Semesterarbeit bei CCT in Athen in
die Applikation integriert.
LITERATUR 34
Literatur
[1] B. Br¨derlein. Computergrafik und Geometrisches Modellieren. Teubner,
u
2001.
[2] H.-J. Bungartz. Einf¨hrung in die Computergraphik. vieweg, 2002.
u
[3] D. Cazier. Reliable boolean operations on polyhedral solids thanks to
3d refinement. Technical report, Laboratoire des Sciences de l’Image, de
l’Informatique et de la Tldtection Strassbourg, ?
[4] J. D. Foley. Computer Graphics - Principle and Practice. Pearson - Addison
Wesley, second international edition, 1997.
[5] L. Piegl. The NURBS Book. Springer, second edition, 1997.
[6] Sun, http://java.sun.com. Java 3D 1.3 API Documentation.
7 Ehrlichkeitserkl¨rung
a 35
7 Ehrlichkeitserkl¨rung
a
Hiermit erkl¨ern wir, Urs Frick und Samuel Gerber, die vorliegende Semester-
a
arbeit selbstst¨ndig und unter Verwendung der aufgef¨hrten Hilfsmittel erstellt
a u
zu haben.
Windisch, 25. Februar 2004
Urs Frick Samuel Gerber