Ich habe die vollständigen Gleichungen dafür noch nicht durchgearbeitet, aber hier sind einige Bilder, die uns helfen sollen, das Problem in den Griff zu bekommen. Es läuft auf eine gewisse Geometrie hinaus:
( Autosymbole über Kenney )
Von jedem Startpunkt und jeder Ausrichtung aus können wir zwei Kreise mit unserem minimalen Wenderadius zeichnen - einen links und einen rechts. Diese beschreiben die Punkte auf dem engstmöglichen Weg zu unserem Weg.
Wir können das Gleiche für jede gewünschte Endposition und Ausrichtung tun. Diese Kreise beschreiben das engstmögliche Ende unseres Weges.
Jetzt reduziert sich das Problem darauf, einen Pfad zu finden, der einen der Startkreise mit einem der Endkreise verbindet und jeden entlang seiner Tangente küsst.
(Dies setzt voraus, dass wir keine Hindernisse dazwischen finden müssen, was in der Frage nicht erwähnt wurde. Stormwinds Antwort bezieht sich darauf, wie wir Navigationsdiagramminformationen für diese Art von Problemen verwenden können. Sobald wir die Folge von Knoten haben Um durchzukommen, können wir die folgende Methode auf jedes Segment des Plans anwenden.)
Wenn wir der Einfachheit halber gerade Linien verwenden, erhalten wir ungefähr Folgendes:
Dies gibt uns den Grenzfall. Sobald Sie mit dieser Methode einen Pfad gefunden haben, können Sie einen oder beide Start- und Endkreise künstlich aufblasen, um einen weniger direkten, aber glatteren Pfad zu erhalten, bis zu dem Punkt, an dem sich die beiden Kreise küssen.
Berechnung dieser Pfade
Lassen Sie uns die Fälle für eine Drehrichtung herausarbeiten - sagen wir, wir beginnen unseren Weg mit einer Rechtskurve.
Das Zentrum unseres rechten Wendekreises ist:
startRightCenter = carStart.position + carStart.right * minRadius
Nennen wir den Winkel des geraden Abschnitts unseres Pfades (gemessen von der positiven x-Achse). pathAngle
Wenn wir einen Vektor von rightCenter
dem Punkt zeichnen, an dem wir den Wendekreis verlassen (an diesem Punkt müssen wir pathAngle zugewandt sein), dann ist dieser Vektor ...
startOffset = minRadius * (-cos(pathAngle), sin(pathAngle))
Das heißt, der Punkt, an dem wir den Kreis verlassen, muss sein ...
departure = startRightCenter + startOffset
Der Punkt, an dem wir wieder in einen Wendekreis eintreten, hängt davon ab, ob wir mit einer Linkskurve oder einer Rechtskurve enden möchten:
// To end with a right turn:
reentry = endRightCenter + startOffset
// To end with a left turn: (crossover)
reentry = endLeftCenter - startOffset
Nun, wenn wir unseren Job richtig gemacht haben, verbindet die Linie departure
zu reentry
soll , dass sie senkrecht startOffset
:
dot(reentry - departure, startOffset) = 0
Und das Lösen dieser Gleichung gibt uns die Winkel, unter denen dies wahr ist. (Ich verwende hier einen Plural, weil es technisch gesehen zwei solche Winkel gibt, aber einer davon beinhaltet das Rückwärtsfahren, was normalerweise nicht das ist, was wir wollen.)
Ersetzen wir als Beispiel den Fall von Rechtskurve zu Rechtskurve:
dot(endRightCenter + startOffset - startRightCenter - startOffset, startOffset) = 0
dot(endRightCenter - startRightCenter, startOffset) = 0
pathAngle = atan2(endRightCenter - startRightCenter)
Der Crossover-Fall ist komplizierter - es ist der, für den ich noch nicht die ganze Mathematik ausgearbeitet habe. Ich werde die Antwort vorerst ohne veröffentlichen, falls es für Sie nützlich ist, während ich die verbleibenden Details ausarbeite.
Bearbeiten: Ziel innerhalb des minimalen Wenderadius
Es stellt sich heraus, dass diese Methode oft sofort funktioniert, selbst wenn das Ziel näher als unser Mindestdrehabstand liegt. Zumindest ein Teil eines der Wiedereintrittskreise endet außerhalb des Abbiegeradius, sodass wir einen brauchbaren Weg finden können, solange es uns nichts ausmacht, dass es ein bisschen wie eine Brezel aussieht ...
Wenn uns der Weg, den wir so bekommen, nicht gefällt (oder wenn einer nicht machbar ist - ich habe nicht jeden Fall gründlich geprüft - vielleicht gibt es unmögliche), können wir immer geradeaus oder rückwärts fahren, bis wir einen geeigneten finden Kusskontakt zwischen einem Start- und einem Endkreis, wie oben dargestellt.