Effizienter mathematischer Algorithmus zur Berechnung von Schnittpunkten
Für ein Spiel, das ich entwickle, ich brauche einen Algorithmus, der berechnen kann Schnittpunkte. Ich habe das problem gelöst, aber die Art und Weise, ich habe getan, es ist wirklich böse, und ich hoffe, dass jemand hier vielleicht eine elegantere Lösung.
Ein paar Punkte stellen die Endpunkte einer Linie zwischen Ihnen gezogen. Gegeben zwei Paare von Punkten, tun die gezeichneten Linien schneiden, und wenn ja, an welcher Stelle?
Also beispielsweise Anruf-Linien (A. x, A. y)-(B. x, B. y) und (C. x, C. y)-(D. x, D. y)
Kann jeder denken, der eine Lösung? Eine Lösung, die in jeder Sprache tun.
Edit: Ein Punkt, den ich gemacht haben sollte klarer sein, muss der Algorithmus gibt false zurück, wenn der Schnittpunkt wird über die Längen der Liniensegmente.
InformationsquelleAutor der Frage | 2008-12-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Meisten Antworten bereits hier zu Folgen scheint die Allgemeine Idee, dass:
Aber bei Kreuzung nicht oft auftreten, ein besserer Weg ist wohl umkehren diese Schritte:
Hinweis: Schritt 2 überprüfen Sie, ob (C. y - a(C. x) - b) und (D. y - a(D. x) - b) haben das gleiche Vorzeichen. Schritt 3 ist ähnlich. Schritt 5 ist nur standard Mathe aus den beiden Gleichungen.
Darüber hinaus, wenn Sie vergleichen müssen jeder Zeile segment mit (n-1) anderen Liniensegmente, precomputing Schritt 1 für alle Zeilen spart Ihnen Zeit.
InformationsquelleAutor der Antwort PolyThinker
Wenn Sie die chance bekommen, Sie sollten wirklich check out die Kollisionserkennung Bibel "Real-Time Collision Detection", wenn Sie planen, etwas zu tun, nicht trivial. Ich bin nicht ein Profi-Spiel Programmierer und ich habe es verstanden und anwenden konnten die Konzepte in der es mit wenig Mühe.
Amazon - Echtzeit-Kollisionserkennung
Grundsätzlich, macht einen Satz von Linien-Schnittpunkt-tests ist teuer, egal was. Was Sie tun, ist die Dinge, wie Bounding Boxen (Achse ausgerichtet oder orientiert) über Ihre komplexe Polygone. Dies ermöglicht es Ihnen, schnell eine worst-case O(N^2) prüfen der Kollision zwischen den einzelnen "Objekt". Dann können Sie die Dinge beschleunigen sogar noch weiter, indem unter Verwendung von Geo-Bäume (Binäre Partitionierung oder QuadTrees) nur durch überprüfen der Schnittpunkte von Objekten in der Nähe zu einander.
Dies ermöglicht es Ihnen zu beschneiden, viele, viele Kollision tests. Die beste Optimierung ist nicht etwas überhaupt. Nur, sobald Sie haben eine Kollision zwischen den bounding-Boxen tun Sie Ihre teure Linie Schnittpunkte zu bestimmen, ob die Objekte wirklich kreuzen oder nicht. Dies ermöglicht Ihnen das skalieren der Anzahl der Objekte, während immer noch halten die Geschwindigkeit angemessen.
InformationsquelleAutor der Antwort mmcdole
Formeln entnommen aus:
Line-line-intersection - Wikipedia
InformationsquelleAutor der Antwort Tom Wijsman
Eine einfache Optimierung, die möglicherweise sparen Sie eine Menge Zeit ist, um die axis-aligned bounding boxes der Leitungen vor dem einsteigen in die Schnittpunkt-Berechnung.
Wenn Sie die bounding-Boxen sind vollständig disjunkt, dann können Sie sicher sein, es gibt keinen Schnittpunkt.
Dies ist natürlich abhängig von den Daten, die Sie haben. wenn eine Kreuzung ist sehr wahrscheinlich bei jedem check Sie machen dann könnten Sie sich selbst zu finden, Zeit zu verschwenden auf ein Häkchen, das ist immer wahr.
InformationsquelleAutor der Antwort shoosh
Prüfen, ob der Schnittpunkt ist nicht über die ursprüngliche Länge der Linie, so stellen Sie sicher, dass
0<r<1
und0<s<1
InformationsquelleAutor der Antwort Graviton
Unten ist meine Linie-Linie-Kreuzung, wie beschrieben in MathWorld. Für Allgemeine Kollisionserkennung/Kreuzung, möchten Sie vielleicht Blick auf die Separating Axis Theorem. Ich fand dieses tutorial am SA sehr informativ.
InformationsquelleAutor der Antwort Ozgur Ozcitak
Gut, der Mathematik und der skalaren Produkte können helfen.
- Sagen Sie, Sie wollen zu schneiden Segmente [AB] und [CD]
- Nehmen wir an, die Linie Schnittpunkt der Linien ist M
M ist im inneren segment [ÅB], wenn und nur, wenn
Vektor(AB) . Vector(AM) >= 0
und
Vektor(AB) . Vector(MB) >= 0
Wo der Punkt "." bezeichnet ein Skalarprodukt : u . v = ux * vx + uy * vy
So, Ihr algo :
- finden Sie M
- M ist in beiden segment, wenn und nur wenn die 4 eq-unten sind wahre
Vektor(AB) . Vector(AM) >= 0
Vektor(AB) . Vector(MB) >= 0
Vector(CD) . Vector(CM) >= 0
Vector(CD) . Vector(MD) >= 0
Hoffe, das hilft
InformationsquelleAutor der Antwort Pascal T.
(Ich würde dies als Kommentar, außer ich habe noch nicht herausgefunden, wie dies zu tun.)
Möchte ich nur hinzufügen, als alternative/Ergänzung zu einer bounding-box-test, Sie könnte auch test um festzustellen, ob der Abstand zwischen der Mitte der Punkte der Linien werden mehr als die Hälfte der Gesamtlänge der Linien. Wenn dem so ist, können die Linien nicht möglicherweise überschneiden.
Stellen Sie sich ein minimal einschließenden Kreis wird für jede Zeile, dann testen, Kreis Kreuzung. Dies ermöglicht eine vorab-Berechnung (zumindest für statische Linien, und Linien, die Erhaltung Ihrer Länge) und ein effizienter Weg, um auszuschließen, eine Menge von möglichen Schnittpunkten.
InformationsquelleAutor der Antwort Jo Are By
InformationsquelleAutor der Antwort Galindo