これについてはまだ完全な方程式を検討していませんが、問題を理解するのに役立つビジュアルをいくつか示します。それはいくつかのジオメトリに要約されます:
(ケニー経由の車のアイコン)
任意の開始点と方向から、最小回転半径で2つの円を描くことができます-1つは左側、もう1つは右側です。これらは、私たちのパスへの可能な限りタイトなスタートのポイントを説明しています。
目的の終了位置と方向についても同じことができます。これらの円は、私たちの道の可能な限り厳しい目的を説明しています。
これで問題は、開始円の1つと終了円の1つを結ぶパスを見つけ、接線に沿ってそれぞれにキスすることに減少します。
(これは、質問の中で言及されていない、障害物の間のパスファインドをする必要がないことを前提としています。Stormwindの答えは、これらのタイプの問題のナビゲーショングラフ情報をどのように使用できるかということです。ノードのシーケンスを取得したら通過するには、プランの各セグメントに以下の方法を適用できます。)
簡単にするために直線を使用すると、次のようになります。
これは私たちに限定的なケースを与えます。この方法で経路を見つけたら、開始円と終了円の一方または両方を人工的に膨らませて、2つの円が接する点まで、直接ではないが滑らかな経路を取得できます。
これらのパスを計算しています
1つの方向転換のケースを考えてみましょう-右折することから経路を開始するとします。
右回転円の中心は次のとおりです。
startRightCenter = carStart.position + carStart.right * minRadius
パスの直線部分の角度を呼び出します(正のx軸から測定) pathAngle
からrightCenter
回転円を離れるポイント(pathAngleに向いている必要があるポイント)までベクトルを描画すると、そのベクトルは...
startOffset = minRadius * (-cos(pathAngle), sin(pathAngle))
つまり、円を離れるポイントは...
departure = startRightCenter + startOffset
ターニングサークルに再び入るポイントは、左折か右折かで異なります。
// To end with a right turn:
reentry = endRightCenter + startOffset
// To end with a left turn: (crossover)
reentry = endLeftCenter - startOffset
さて、私たちの仕事が正しくできていれば、departure
にreentry
つながる線はに垂直でなければなりませんstartOffset
。
dot(reentry - departure, startOffset) = 0
そして、この方程式を解くと、これが当てはまる角度が得られます。(技術的にはそのような2つの角度があるため、ここでは複数を使用しますが、そのうちの1つは、通常私たちが望んでいないリバースでの運転を伴います)
例として、右折の場合を右折に置き換えてみましょう。
dot(endRightCenter + startOffset - startRightCenter - startOffset, startOffset) = 0
dot(endRightCenter - startRightCenter, startOffset) = 0
pathAngle = atan2(endRightCenter - startRightCenter)
クロスオーバーのケースはもっと複雑です-それは私がまだすべての数学を理解していないものです。残りの詳細を確認する際に役立つ場合に備えて、今のところ回答を掲載しません。
編集:最小回転半径内の目的地
結局のところ、この方法は目的地が最小旋回距離よりも近い場合でも、すぐに使用できることがよくあります。再突入円の1つの少なくとも一部が回転半径の外側に到達するため、少しプレッツェルのようになってもかまわない限り、実行可能なパスを見つけることができます...
私たちがその道をたどる経路が気に入らない場合(または実行可能でない場合-私はすべてのケースを徹底的にチェックしていません-多分不可能なケースがあるかもしれません)、適切な状態になるまで常に直進または後退できます上図のように、開始円と終了円の間の接触をキスします。