So berechnen Sie die Schnittfläche zwischen einem 3D-Volumen und einer 2D-Ebene

8

Hallo, wenn jemand einen Einblick in die Lösung meines Problems geben kann, wäre das großartig!

Ich möchte den Schnittbereich zwischen einem 3D-Volumen und einer 2D-Ebene berechnen. 3D-Volumen: definiert durch 6 Punkte (wird immer ein 3D-Keil sein, der einem dicken Dreieck ähnelt) 2D-Ebene: definiert durch 3 Punkte

irgendwelche Vorschläge? Gibt es Open Source-Software, die diese Aufgabe ausführen kann?

Vielen Dank Chris

Chris
quelle

Antworten:

5

Es wird keine magische Antwort auf diese Frage geben; Irgendwann müssen Sie es nur noch aufsaugen und alle Fälle berücksichtigen. Ich musste einmal den Schnittpunkt eines Dreiecks und eines Kreises berechnen ... es war schrecklich. Da Ihre 3D-Form bestimmte Symmetrien aufweist (wie die Tatsache, dass es sich immer um ein dreieckiges Prisma handelt), können Sie die Möglichkeiten erheblich einschränken.

  1. Finden Sie heraus, auf welcher Seite der Ebene jeder Punkt liegt.
  2. Wenn alle Punkte auf einer Seite sind, fertig.
  3. Wenn ein Punkt durch die Ebene von den anderen 5 getrennt ist, ist der Schnittpunkt ein Dreieck. Vermutlich verfügen Sie über Konnektivitätsinformationen, die Ihnen mitteilen, welche Flächen auf den Scheitelpunkt fallen, und Sie können die 3 Linien aufgrund von Schnittpunkten zwischen Ebene und Ebene und dann das Schnittdreieck berechnen. Am besten tun Sie dies alles in einer Parametrisierung der Schnittebene.
  4. Zwei Punkte sind getrennt, entweder befinden sich beide auf derselben dreieckigen Fläche des Prismas oder sie sind zwei entsprechende Punkte auf gegenüberliegenden dreieckigen Flächen. In beiden Fällen ist der Schnittpunkt ein Viereck.
  5. Für drei Punkte können sie alle dieselbe dreieckige Fläche oder nur zwei darauf sein. Sie haben hier zwei Fälle für ein resultierendes Dreieck oder Sechseck.

Dies sind wirklich die einzigen Fälle auf hoher Ebene. Es gibt offensichtlich Symmetrieverringerungen, die Sie anwenden müssen (in Fall 5 entspricht der Fall mit einem Punkt dem Fall mit zwei Punkten auf der anderen dreieckigen Facette).

Mein einziger Vorschlag an Sie ist, eine robuste Darstellung für Ihre Formen auszuwählen und robuste Prädikate zu verwenden, um die geometrischen Tests durchzuführen. Für die Ebene wird sie am besten als Punkt in der Ebene und als Einheitsnormalenvektor dargestellt. Das Prisma wird durch Definieren einer orthonormalen Basis (Triade) dargestellt, wobei eine Achse mit der Extrusionsrichtung des Prismas ausgerichtet ist. Lassen Sie einen Scheitelpunkt am Ursprung sein, die anderen beiden auf der dreieckigen Fläche werden in den UV-Koordinaten der Triade dargestellt, und dann müssen Sie nur seine Höhe und den globalen Versatz seines Basisscheitelpunkts speichern. Im Wesentlichen denke ich

struct plane{
    double p[3]; // point on plane
    double n[3]; // unit normal vector to plane
};
struct TriPrism{
    double basis[9]; // 3x3 orthogonal matrix of local coordinate frame (det = +1)
    // Stored columnwise, first two vectors are in the plane of the triangular face)
    // Last vector is parallel to extrusion direction, call the set [u, v, w]
    double base[3]; // global coordinates of base vertex (where the basis vectors are "rooted")
    double buv[2]; // the uv-coordinates of the second point on the triangular face
    double cuv[2]; // third point on triangular face
    // Assume that the "bottom" triangular face is formed by vertices (a,b,c)
    // with base being a, and (b-a) cross (c-a) directed along vector w (instead of against)
    double h; // height of prism ("top" triangular face is h*w offset from the "bottom" face)
};

Diese Darstellung ist robust gegenüber dem Bewegen des Prismas und sollte für alle außer den pathologischsten Fällen eine hohe relative Präzision beibehalten.

Für robuste Prädikate empfehle ich die robusten Prädikate von Shewchuk, vorausgesetzt, Sie verwenden gewöhnliche Gleitkommazahlen. Sie würden hauptsächlich verwenden orient3d.

Wählen Sie zur Darstellung des endgültigen Ausgabepolygons eine geeignete Parametrisierung der Ebene. Die beste Wahl ist meiner Meinung nach, zuerst eine orthonormale Basis in der Ebene zu wählen, die von Gram-Schmidt auf dem Normalenvektor der Ebene bestimmt wird ( siehe geom_maketriad3d hier ). Dann sei der Ursprung dieser 2D-Parameterebene die Projektion des Prismenbasispunkts in die Ebene. Dies stellt sicher, dass Ihre Parametrisierung tatsächlich in der Nähe des resultierenden Polygons verwurzelt ist, um eine effektive Verwendung der Bits der beteiligten Gleitkommazahlen sicherzustellen. Führen Sie alle verbleibenden Berechnungen mit dieser Parametrisierung durch, wenn dies überhaupt möglich ist.

Im Allgemeinen ist die geometrische Berechnung aufgrund dieser dummen numerischen Überlegungen mit Gefahren behaftet (ein geringfügiger Fehler mit einem Scheitelpunkt in der Nähe der Ebene in Fall 5 oben könnte das Ergebnis drastisch von einem 4-Gon auf einen 6-Gon ändern). Ich schlage vor, Sie behandeln jeweils einige Fälle und versuchen, das Ergebnis zu visualisieren. Ich habe hier ein ziemlich einfaches Viewer-Programm mit einer Art Postscript-ähnlichen Eingabesprachenfunktion. Sie können die Facetten des Prismas entleeren und die Ebene zeichnen sowie die resultierenden Polygone zeichnen und sie visuell überprüfen, um festzustellen, ob sie richtig sind.

Nachtrag : Ich habe vergessen, dass Sie ursprünglich den Bereich des Schnittpolygons wollten. Es ist trivial, aber falls Sie es nicht wissen, müssen Sie es, sobald Sie die Sammlung von Linien haben, die die Kanten des Polygons in der Schnittebene definieren, in eine Scheitelpunktdarstellung konvertieren. Da Sie die Schnittpunkte aus Schnittpunkten von Facettenebene und Ebene konstruiert haben, sollten Sie in der Lage sein, die Reihenfolge der Linien und damit die Reihenfolge der Kanten um das Polygon herum zu verfolgen. Sie müssen nur den Schnittpunkt aufeinanderfolgender Paare dieser Linien berechnen, um die Eckpunkte zu erhalten. Sobald Sie die Eckpunkte haben, ist es einfach, den Bereich zu erhalten ( siehe z . B. geom_polygon_area2d hier ). Wenn Sie vollständig in UV-Koordinaten der Schnittebene gearbeitet haben, können Sie diese direkt einer solchen Funktion zuführen, um den Bereich zu erhalten.

Ich sollte hinzufügen, dass es einen offensichtlichen dummen Ansatz gibt, nämlich einen geeigneten großen Bereich in der Schnittebene auszuwählen und Punkte zufällig abzutasten und zu überprüfen, ob sie sich im Prisma befinden (was billig ist, da es konvex ist). Dann können Sie die Fläche als Verhältnis von Punkten innerhalb zu Gesamtpunkten multipliziert mit der Fläche des Abtastbereichs berechnen. Wenn Sie sich wirklich nicht um Genauigkeit kümmern, wird dies wahrscheinlich schneller sein, aber ansonsten sollte die Analysemethode trotz ihrer kombinatorischen Komplexität nicht viel langsamer sein.

Victor Liu
quelle