Verbinde zwei Liniensegmente

7

Wie kann ich aus zwei 2D-Liniensegmenten, A und B, die Länge des kürzesten 2D-Liniensegments C berechnen, das A und B verbindet?

    
Jason S 12.02.2009, 13:07
quelle

7 Antworten

6

Betrachten Sie Ihre beiden Liniensegmente A und B als jeweils zwei Punkte:

Linie A repräsentiert durch A1 (x, y), A2 (x, y)

Linie B repräsentiert durch B1 (x, y) B2 (x, y)

Überprüfen Sie zuerst, ob sich die beiden Linien mit diesem Algorithmus schneiden.

Wenn sie sich schneiden , dann ist der Abstand zwischen den beiden Linien Null, und das Liniensegment, das sie verbindet, ist der Schnittpunkt.

Wenn sie sich nicht schneiden , verwenden Sie diese Methode: Ссылка um den kürzesten Abstand zwischen:

zu berechnen
  1. Punkt A1 und Linie B
  2. Punkt A2 und Linie B
  3. Punkt B1 und Linie A
  4. Punkt B2 und Linie A

Das kürzeste dieser vier Liniensegmente ist Ihre Antwort.

    
Alterlife 12.02.2009, 13:57
quelle
4

Diese Seite enthält Informationen, nach denen Sie suchen können.

    
strager 12.02.2009 13:12
quelle
2

Schneller Tipp: Wenn Sie Entfernungen anhand von Punkten vergleichen möchten, ist es nicht notwendig, die Quadratwurzeln zu verwenden.

z. um zu sehen, ob P-zu-Q eine kleinere Entfernung als Q-zu-R ist, überprüfen Sie einfach (Pseudocode):

%Vor%     
joel.neely 12.02.2009 13:16
quelle
2
Gernot Hoffmann Papier (Algorithmus und Pascal-Code):

Ссылка

    
Nicolai 12.02.2009 13:12
quelle
2

Afterlife sagt: "Überprüfen Sie zuerst, ob sich die beiden Linien mit diesem Algorithmus schneiden", aber er hat nicht angegeben, welchen Algorithmus er meinte. Offensichtlich ist es der Schnittpunkt der Linie Segmente nicht die erweiterten Linien, was zählt; Alle nichtparallelen Liniensegmente (ausgenommen koinzidente Endpunkte, die keine Linie definieren) schneiden sich, aber der Abstand zwischen den Liniensegmenten ist nicht notwendigerweise Null. Ich nehme an, er meinte dort eher "Liniensegmente" als "Linien".

Der Link Afterlife gab einen sehr eleganten Ansatz, um den nächsten Punkt auf einer Linie (oder einem Liniensegment oder einem Strahl) zu einem anderen beliebigen Punkt zu finden. Dies funktioniert, um die Entfernung von jedem Endpunkt zu dem anderen Liniensegment zu finden (Beschränken des berechneten Parameters u auf nicht weniger als 0 für ein Liniensegment oder Strahl und nicht mehr als 1 für ein Liniensegment), tut dies jedoch nicht Behandle die Möglichkeit, dass ein innerer Punkt auf einem Liniensegment näher als jeder Endpunkt ist, da sie sich tatsächlich schneiden, daher ist eine zusätzliche Überprüfung des Schnittpunkts erforderlich.

Was den Algorithmus zur Bestimmung der Liniensegmentüberschneidung anbelangt, wäre ein Ansatz, den Schnittpunkt der erweiterten Linien zu finden (wenn Sie dann parallel sind) und dann zu bestimmen, ob dieser Punkt innerhalb beider Liniensegmente liegt, wie z indem das Skalarprodukt der Vektoren vom Schnittpunkt T zu den zwei Endpunkten genommen wird:

((Tx - A1x) * (Tx - A2x)) + ((Ty - Aly) * (Ty - A2y))

Wenn dies negativ (oder "Null") ist, dann liegt T zwischen A1 und A2 (oder an einem Endpunkt). Überprüfen Sie ähnlich für das andere Liniensegment. Wenn beide größer als "Null" waren, schneiden sich die Liniensegmente nicht. Dies hängt natürlich davon ab, zuerst den Schnittpunkt der erweiterten Linien zu finden, was es erforderlich machen kann, jede Linie als eine Gleichung auszudrücken und das System durch Gauß-Reduktion (etc.) zu lösen.

Aber es kann einen direkteren Weg geben, ohne nach dem Schnittpunkt zu suchen, indem man das Kreuzprodukt der Vektoren (B1-A1) und (B2-A1) und das Kreuzprodukt der Vektoren (B1- A1) nimmt A2) und (B2-A2). Wenn diese Kreuzprodukte in der gleichen Richtung verlaufen, befinden sich A1 und A2 auf derselben Seite der Linie B; wenn sie in entgegengesetzte Richtungen sind, dann sind sie auf gegenüberliegenden Seiten der Linie B (und wenn 0, dann sind eins oder beide auf Linie B). In ähnlicher Weise die Kreuzprodukte der Vektoren (A1-B1) und (A2-B1) und (A1-B2) und (A2-B2) überprüfen. Wenn eines dieser Kreuzprodukte "Null" ist oder wenn die Endpunkte von beiden Liniensegmenten auf entgegengesetzte Seiten der anderen Linie fallen, müssen sich die Liniensegmente selbst schneiden, andernfalls schneiden sie sich nicht.

Natürlich brauchen Sie eine praktische Formel, um ein Kreuzprodukt zweier Vektoren aus ihren Koordinaten zu berechnen. Oder, wenn Sie die Winkel (positiv oder negativ) bestimmen könnten, würden Sie das tatsächliche Kreuzprodukt nicht benötigen, da es die Richtung der Winkel zwischen den Vektoren ist, die wir tatsächlich interessieren (oder der Sinus des Winkels wirklich) . Aber ich denke, die Formel für produktübergreifendes (in 2-D) ist einfach:

Kreuz (V1, V2) = (V1x * V2y) - (V2x * V1y)

Dies ist die z-Achsen-Komponente des 3D-Kreuzproduktvektors (wobei die x- und y-Komponenten Null sein müssen, da die Anfangsvektoren in der Ebene z = 0 liegen), so dass Sie einfach auf die Zeichen (oder "Null").

Sie können also eine der beiden Methoden verwenden, um im Algorithmus, den Afterlife beschreibt (Verweis auf die Verknüpfung), nach einer Liniensegment-Schnittmenge zu suchen.

    
Rob Parker 15.02.2009 21:54
quelle
0

Diese Seite hat eine schöne kurze Beschreibung, um den kürzesten Abstand zwischen zwei Zeilen zu finden, obwohl die @ strager-Verknüpfung einen Code enthält (in Fortran!)

    
Ian Hopkinson 12.02.2009 13:19
quelle

Tags und Links