|
Hallo Martin, CSG Operationen mit Polygonalen K"opern sind ziemlich schwer. a) Du musst "K"orper" einf"uhren. b) Du musst einen CSG Baum erzeugen, der jeweils die sich verk"upften K"orper und die Operationen wie Durchschnitt, Differenz, und Vereinigung enth"alt c) Du musst die Polygone der der K"orper teilen, so dass f"ur jedes Polygon eines K"orpers A entschieden werden kann ob es vollst"andig in einem K"orper B liegt. d) entsprechend der Operationen wird der CSG Baum von den Bl"attern her abgebarbeitet. Raytracer k"onnen zwangsl"aufig sehr gut mit CSG umgehen, weil der Strahl ja nur die Schnitte mit den K"orperoberfl"achen berechnet und wenn er K"orper A trifft so kann er leicht entscheiden ob er auch innerhalb von K"orper B ist. Je nach Operation ist der Schnittpunkt sichtbar oder nicht. Eine sehr sch"one Implementation von CSG operationen (mit Polygonen und *nicht* in Mathematica) findet sich in Open Geometry OpenGL and Advanced Geomerty Georg Glaeser & Hellmut Stachel Springer-Verlag 1998 ISBN 0-387-98599-9 Kapitel 8 (Seite 193) Mathematica unterst"utzt keine K"orper oder die Darstellung von K"orpern. Es gibt als auch keine M"oglichkeit, die Entscheidung ein Punkt, eine Linie oder ein Polygon sind innerhalb eines K"orpers zu treffen. Da Mathematica nur Konvexe Polygone Darstellen kann bekommt man zus"atzlichen "Arger, denn die Schnittk"oper bestehen nicht nur aus konvexen Polygonen. Selbst wenn man das in Mathematica implementiert wird man nicht viel Freude daran haben, weil die zahlreichen Tests auf Schnitte (Raytracer verwenden BSP- oder OctTrees um die Suche zu Optimieren) in Mathematica zu lange dauern und man sehr schnell eine Unzahl von Polygonen bekommt. Deine inTubeQ[] Funktion versucht die "InK"orperQ[]" Funktion nachzubauen, letztere kann es mit einfachen Mitteln aber in Mathematica nicht geben. Schon bei dem Versuch den so erhaltenen K"orper mit einem weiteren Zylinder zu schneiden klappt das ganze nicht mehr. Die PolygonIntersections-Option k"ummert sich auch nur um die Sichtbarkeit, die nichts mit der "Innen/Aussen" Entscheidung zu tun hat. Gruss Jens Martin Kraus wrote: > > ilo@XXXXXXX.de wrote: > > > > Hallo, > > > > ich möchte einige Körper darstellen, die aus einem Würfel entstehen, z. > > B. indem man ihn zylindrisch durchbohrt oder auf seiner Oberseite eine > > Rinne von folgender Form herausnimmt: > > > > rinne = ParametricPlot3D[ {Cos[t](2.5 + 0.9 Cos[u]),Sin[t](2.5 + 0.9 > > Cos[u]), 0.9 Sin[u] + 5}, > > {t,0,Pi/2}, {u,-Pi,0}] > > > > Ich habe versucht, die Grafiken von Würfel und Rinne zu kombinieren, das > > bringt nichts, man sieht dann nur den Würfel: > > > > wuerfel = Graphics3D[Cuboid[{0,0,0},{5,5,5}]] > > Show[wuerfel, rinne] > > > > Erst wenn der Parameter u einen größeren Bereich durchläuft und die > > Torus-Teilfläche über den Würfel hinausragt, kann man etwas davon sehen, > > z. B.: > > > > Show[Graphics3D[Cuboid[{0,0,0},{5,5,5}], DisplayFunction->Identity], > > ParametricPlot3D[ {Cos[t](2.5 + 0.9 Cos[u]),Sin[t](2.5 + 0.9 Cos[u]), > > 0.9 Sin[u] + 5}, > > {t,0,Pi/2}, {u,-Pi,Pi/2}, DisplayFunction->Identity], > > DisplayFunction-> $DisplayFunction] > > > > Wie definiert man einen solchen Körper in Mathematica und wie stellt man > > ihn dar? > > > > Ina Leiß > > Gute Frage. Ich kenne keine einfache Antwort. Aber es gibt ein paar > Ansaetze fuer > eine Loesung. > > 1. Verwendung von Transparenz. Die OpenGL-Viewer fuer Mathematica > koennen wohl > fast alle auch transparente Flaechen darstellen, damit koennte man dann > zumindest > beide Koerper gleichzeitig sehen. Naja, das beantwortet aber nicht die > Frage. > > 2. Verwendung von POVRay. POVRay (ein Raytracer) kann solche Sachen > machen. > Es gibt einige Programme, die Mathematica-Graphiken in > POVRay-Beschreibungen > umwandeln koennen. Aber das beantwortet auch nicht die Frage, wie das > mit > Mathematica geht. > > 3. Definition von Skalarfunktionen, die innerhalb der Koerper einen > anderen > Wert haben als ausserhalb. Dann einen ContourPlot3D mit der Summe der > Funktionen > fuer alle Koerper und geeignetem Schwellenwert. Aber das gibt etwas > seltsame > Objekte mit abgerundeten Kanten. Ist also mehr eine theoretische > Loesung. > > 4. Anwendung von PolygonIntersections und Entfernen von einzelnen > Polygonen und > Linien. Ziemlich trickreich, benoetigt ausserdem recht viel Mathematik > und > die Ergebnisse haben meistens helle Striche in den Polygonen. Hier mal > fuer das Beispiel: > > wuerfel = > Show[Graphics3D[Cuboid[{0.001, 0.001, 0.001}, {4.999, 4.999, > 4.999}]]]; > > rinne = ParametricPlot3D[{Cos[t](2.5 + 0.9 Cos[u]), Sin[t](2.5 + 0.9 > Cos[u]), > 0.9 Sin[u] + 5}, {t, 0, Pi/2}, {u, -Pi, 0}, PlotPoints -> 15]; > > gra1 = Show[ > Graphics3D[{rinne[[1]], wuerfel[[1]]}, PolygonIntersections -> > False]]; > > Show[gra1]; > > center[pointList_] := Plus @@ pointList/Length[pointList]; > distance[p1_, p2_] := Sqrt[(p1 - p2).(p1 - p2)]; > normalized[p1_] := p1/Sqrt[p1.p1]; > inTubeQ[{x_, y_, z_}] := > If[distance[{x, y, z}, 2.5 normalized[{x, y, 0}] + {0, 0, 5}] < > 0.89, > True, False]; > > gra2 = DeleteCases[ > gra1, (Polygon | Line)[points_, ___] /; inTubeQ[center[points]], > Infinity]; > > Show[gra2, Boxed -> False]; > > Das Komplizierteste ist die Funktion inTubeQ, die True zurueck gibt, > wenn ein > Punkt innerhalb der Rinne ist und False wenn der Punkt ausserhalb ist. > Solche Funktionen muss man fuer jeden Koerper neu definieren. > Ausserdem muss man einige Werte leicht kleiner bzw. groesser machen, > damit > sich Polygone wirklich schneiden, bzw. entfernt werden. > Und dann gibt es im Ergebnis noch diese stoerenden Striche. > Aber vielleicht hilft das weiter. > > Gruesse > > Martin Kraus |