29/09/2012 - 23:20
Ich habe hier ein Git-Repo erstellt:
https://github.com/ArthurWulfWhite/Bezier-Distance/
Sie können die Quelldateien auch als Zip von dort herunterladen. Es enthält auch eine Demo, die Sie mit FlashDevelop kompilieren können. Um die Demo zu verwenden, öffnen Sie das Projekt in Flash Develop und klicken Sie auf „Projekt testen“. Klicken Sie beim Ausführen der Demo auf die LMB, um eine neue Bézier-Kurve und einen neuen Kreis zufällig auszuwählen.
Viel Glück!
Der Zip-Link ist schwer zu erkennen - verwenden Sie einfach Strg + F und geben Sie zip ein. Diese Quelle repräsentiert ein paar Wochen Forschung und Programmierung, ich hoffe es gefällt euch.
Wenn Sie vorhaben, den Bezier rekursiv in Segmente zu unterteilen und nach Kollisionen mit ihnen zu suchen, empfehle ich, ein 100.100-Array (Gitter) zu erstellen und jedes Segment auf den vier nächstgelegenen Quadraten zu platzieren, sodass Sie nur mit 4 / 10.000 der auf Kollisionen prüfen müssen segmentiert jeden Frame.
Ich denke, Sie werden sowohl als Programmierer als auch als Spieleentwickler von box2d profitieren, da es viele versteckte kleine Hürden gibt, eine "einfache" Physik-Engine zu entwickeln, die die Bewegung etwas holpriger und weniger flüssig erscheinen lässt, als sie sein könnte.
Alte Antwort: Der reine Weg.
Sie können tatsächlich feststellen, ob ein Kreis mit einer Bezier-Kurve kollidiert, indem Sie den Abstand zwischen dem Mittelpunkt des Kreises und dem nächstgelegenen Punkt auf der Kurve überprüfen.
Die Gleichung für die Entfernung (im Allgemeinen)
erklärt:
Bezier-Gleichung:
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Dies kann summiert werden zu (mit etwas Algebra) - ich werde (x, y) für die Lesbarkeit weglassen (sie sind immer noch Punkte, nicht eine Zahl)
q(t) = (start -2 * cont + end) t^2 + (-2 * start + 2 * control) + start
Die Entfernung vom Punkt (x, y) beträgt:
sqrt ((q(t).x - point.x)^2 + (q(t).y - point.y)^2)
Um den dem Ball am nächsten gelegenen Punkt auf dem Bezier zu finden, müssen Sie alle Punkte ableiten und finden, an denen die Ableitung gleich Null ist (die Wurzeln). Da es sich um ein Polynom dritten Grades handelt, können Sie eine geschlossene Formel verwenden, die jedoch möglicherweise unzuverlässig ist, da die Genauigkeit der vom Computer dargestellten Gleitkomma-Brüche möglicherweise nicht ausreicht. Es ist weitaus besser, Newton oder ähnliches zu verwenden.
Das Derivat, für das Sie die Wurzeln finden müssen, ist:
Angenommen: a = Start b = Kontrolle c = Ende d = Wirbelmittelpunkt
Der schwierige Teil ist das Multiplizieren dieser Punkte. Sie müssen das Skalarprodukt verwenden.
Wenn Sie möchten, habe ich den Code dafür und kann ihn hier in Form einer Funktion weitergeben, die einfach einen Booleschen Wert zurückgibt, wenn eine Kollision vorliegt oder nicht und einen Kollisionswinkel. Einige Probleme könnten bei der naiven Implementierung einer Kollisionsmaschine wie dieser auftreten, z. B. könnte ein sich schnell bewegender Ball zwischen zwei Kurven hängen bleiben.
Ich empfehle, es vorerst zu vermeiden, fasse einfach die Koeffizienten für die x-Achse und für die y-Achse zusammen und addiere sie.
Verwenden Sie eine zuverlässige Methode wie Newton, um die Wurzeln zu finden, überprüfen Sie den Abstand von den Wurzelpunkten auf dem Bezier, 0 <= t <= 1 zur Kreismitte, und überprüfen Sie den Abstand für die beiden Enden des Beziers (Start und Ende) zum Kreismittelpunkt, welcher am nächsten ist, zeigt an, ob eine Kollision vorliegt.
Ist der Radius kleiner als der Mindestabstand, liegt eine Kollision vor.
Der Winkel ist ungefähr derjenige zwischen dem Mittelpunkt des Kreises und dem nächstgelegenen Punkt auf dem Bezier.
Abgesehen davon, wenn Sie wirklich ein Spiel mit Kollisionsphysik machen möchten, schlage ich vor, dass Sie einfach über den Bézier iterieren
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Teilen Sie jedes Teil rekursiv in die Mitte, bis es klein genug ist, sagen wir 10 Pixel oder weniger. Bilden Sie dann den Bezier grob aus Boxen und verwenden Sie Box2d für die Physik, da es möglich ist, dass sich das Schreiben dieses gesamten Kollisionserkennungscodes als großartig herausstellt Zeitverschwendung, die das Gameplay nicht wesentlich verbessert. Der Einsatz von Box2d hat sich in der Vergangenheit in unzähligen Projekten bewährt.