Ich habe ein System, in dem Sie einmal klicken können, um einen Knoten in einer Szene zu platzieren. Wenn Sie 3 Knoten platzieren, bildet sich ein Dreieck. Wenn Sie zukünftige Knoten platzieren, wird ein neues Dreieck erstellt, indem dieser Knoten mit den 2 nächstgelegenen vorhandenen Knoten verbunden wird.
Dies funktioniert die meiste Zeit gut, ist jedoch fehlerhaft, wenn es in der Nähe von Dreiecken mit sehr spitzen Winkeln verwendet wird, da einer der beiden nächstgelegenen Knoten häufig nicht verwendet werden sollte.
Siehe zum Beispiel das Bild unten. Das magentafarbene Dreieck ist das erste, das platziert wird. Wenn ich dann auf die mit X gekennzeichnete Position klicke, erhalte ich ein neues Dreieck, in dem sich die blaue Überlagerung befindet. Was ich will, ist ein neues Dreieck, in dem sich die grüne Überlagerung befindet. (dh in diesem Beispiel symmetrisch zum Magenta-Dreieck. Erläuterung: Das grüne und das Magenta-Dreieck überlappen sich nicht - das grüne Dreieck erstreckt sich unter dem blauen zum Knoten ganz links.)
Wie kann ich bestimmen, welche 2 vorhandenen Scheitelpunkte beim Erstellen neuer Dreiecke verwendet werden sollen, damit Dreiecke nicht so überlagert werden?
BEARBEITEN : Die Suche nach der nächsten Kante liefert bessere Ergebnisse, aber keine perfekten. Betrachten Sie diese Situation:
Der Test der nächsten Kante ist mehrdeutig und kann AB oder AC zurückgeben (da der nächstgelegene Punkt zu X für beide bei A liegt). Das gewünschte Ergebnis wäre AC, um das ACX-Dreieck ohne überlappende Kanten zu bilden. Wie könnte ich dieses Ergebnis sicherstellen? (Ich möchte lieber keine einzelnen Kantenüberlappungstests als Verbindungsunterbrecher durchführen, wenn dies möglich ist, da ich befürchte, dass der nächste Kantentest nicht unbedingt erkennt, dass die 2 aufgrund von Gleitkommapräzisionsproblemen genau gleich weit voneinander entfernt sind.)
Antworten:
Anstatt den Mindestabstand zu den Knoten zu ermitteln, ermitteln Sie den Mindestabstand zur Kante (dh das durch die Knoten definierte Liniensegment).
Wenn der nächste Punkt ein Scheitelpunkt ist (für den Sie einen Gleitkomma-Epsilon ** -Test verwenden müssen), vergleichen Sie den Winkel zwischen der Linie vom neuen Punkt zum Scheitelpunkt und jeder der mit diesem Scheitelpunkt verbundenen Kanten. Wählen Sie den mit dem minimalen absoluten Winkel:
** Um zu vermeiden, dass entartete Dreiecke hinzugefügt werden, die den Epsilon-Test stören könnten, sollten Sie einen Bereich um jeden Scheitelpunkt legen, in dem das Hinzufügen von Punkten nicht zulässig ist (etwa das Nichtzulassen von Punkten innerhalb eines Vielfachen des oben verwendeten Epsilons).
quelle
Nachdem das erste Dreieck platziert wurde, werden beim Platzieren eines neuen Scheitelpunkts immer zwei neue Kanten generiert. Die dritte Kante für das neue Dreieck ist immer eine gemeinsame Kante mit einem vorherigen Dreieck. Wenn Sie einen Weg finden könnten, die gemeinsame Kante zu bestimmen, würden Sie wissen, mit welchen Scheitelpunkten eine Verbindung hergestellt werden soll, aber das ist der schwierige Teil. Ich glaube, Sie können dies auf eine Weise tun, indem Sie eine Linie von Ihrem neuen Scheitelpunkt zur Mitte jeder der letzten drei erzeugten Kanten (oder wahrscheinlich der drei nächstgelegenen Kanten) ziehen.
Wenn die Linie von Ihrem Scheitelpunkt zur Mitte der Kante nicht beiden anderen Kanten kreuzt, haben Sie Ihre gemeinsame Kante. Die gemeinsame Kante gibt an, mit welchen zwei Scheitelpunkten Ihr neuer Scheitelpunkt verbunden werden soll.
Jimmy brachte den Fall für einen Punkt vor, der nicht eindeutig ist, wohin das neue Dreieck so führen würde:
Das gibt Ihnen die Möglichkeit, zwischen zwei gültigen Dreiecken zu wählen. Vielleicht ist das Brechen der Krawatte, welcher Mittelpunkt am nächsten ist.
In Anbetracht Ihres Updates ist meine Lösung zwar komplexer, führt jedoch nur dann zu einem Gleichstand, wenn Sie zwei gültige Dreiecke haben. Mit dieser Methode würde Ihr zweites Beispielbild das gewünschte Ergebnis erzielen.
quelle
Wenn Sie Ihr magentafarbenes Dreieck ABC haben, fügen Sie dann einen neuen Scheitelpunkt X ein. Ich denke, es ist offensichtlich, dass es zwei Linien gibt, die bei D beginnen und sich nicht zwischen den Kanten des Dreiecks ABC schneiden.
Diese beiden Leitungen können AX & BX, BX & CX oder AX & CX sein. Sie können Ihr Problem dann als das klassische Problem behandeln, dass sich zwei Linien schneiden. Sie können dann überprüfen, welches dieser Linienpaare sich nicht mit einer der ABC-Dreieckskanten schneidet, beispielsweise nach einer der Methoden aus dieser Frage . Daher haben Sie die zwei neuen Kanten des neuen Dreiecks.
quelle
Es ist ziemlich einfach herauszufinden, ob Sie sich in einem der eindeutigen Bereiche (1, 2, 3 unten) befinden: Behandeln Sie jede Kante Ihres Dreiecks als 2D-Ebene und testen Sie, auf welcher Seite der Ebene sich Ihr neuer Punkt befindet. Wenn Sie sich innerhalb von zwei, aber außerhalb eines befinden, entspricht dieser dem Rand des Dreiecks, der zwei Eckpunkte zu Ihrem neuen Dreieck beiträgt.
Wenn Sie sich innerhalb von eins und außerhalb von zwei befinden, befinden Sie sich in einem mehrdeutigen Fall, in dem der Ihrem neuen Punkt am nächsten liegende Teil des Dreiecks eine Ecke ist. In diesem Fall können Sie eine 2D-Ebene aus dem Mittelpunkt der gegenüberliegenden Kante (derjenige, in der Sie sich befinden) und dem nächsten Scheitelpunkt (der von den beiden Ebenen, außerhalb derer Sie sich befinden) teilen. Sie können eine Kante auswählen, je nachdem auf welcher Seite dieser Ebene sich Ihr neuer Punkt befindet.
Beachten Sie, dass ein Ebenentest in 2D genauso funktioniert wie in 3D: Punktieren Sie einen Vektor von einer beliebigen Stelle in der Ebene bis zu Ihrem Punkt mit der Normalen der Ebene (in 2D ist dies die Senkrechte der Linie).
(Im Übrigen werden die durch Magenta getrennten Bereiche in diesem Bild Voronoi-Bereiche genannt. Sie sind die Bereiche des Raums, die Punkte enthalten, die einem bestimmten Merkmal - Kante oder Scheitelpunkt - des Dreiecks am nächsten liegen. Bearbeiten: Meine Terminologie hier ist eigentlich nicht ganz richtig, das sind nicht gerade Voronoi-Regionen.)
quelle