2点間の曲線運動


15

オブジェクトを素敵な曲線運動でポイント間を移動できるようにする良い方法は何ですか?

ホーミングミサイルの軌道など、終了位置も動いている可能性があります。

回答:


11

これは、事前に計算された軌道ではなく、フレームごと(ターゲットが動いている可能性さえある)にしたい場合、これは実際には非常に簡単です:

すべてのフレームで、ミサイルの速度ベクトルとベクトル(位置ターゲット -位置ミサイル)を比較します。つまり、ミサイルからターゲットを指すベクトルです。すべてのフレームで、2つのベクトルの方向が同じでない場合は、速度ベクトルをもう一方のベクトルに向かって少し回転させます。そのため、すべてのフレームがミサイルのターゲットに少し近づきます。

2つのベクトル間の外積の符号を見ることで、時計回りに回転するか反時計回りに回転するかを決定できます。


[編集] XNA風のコード(これをテストするXNAがありません):

//Once a frame:

//Get vector spanning from missile to target
Vector2 vectorToTarget = target.Position - missile.Position;

//Convert to Vector3 to do cross-product
Vector3 vectorToTarget3 = new Vector3(vectorToTarget, 0);
Vector3 missileVelocity3 = new Vector3(missile.Velocity, 0);

//Rotate clockwise/counter-clockwise is determined by sign of cross-product
int crossProductSign = Vector3.Cross(missileVelocity3, vectorToTarget3).Z;

//Positive cross-product means rotate counter-clockwise, negative is clockwise
double rotationAngle = 0;
if(crossProductSign > 0)
    rotationAngle = -0.05;
else if(crossProductSign < 0)
    rotationAngle = 0.05;

//I'm not sure how to do rotation in XNA, but the internets tell me it's something like this:
missile.velocity = Vector2.Transform(missile.velocity, Matrix.CreateRotationZ(rotationAngle))

rotationAngle可能な値は3つしかないため、のすべての可能な値をMatrix.CreateRotationZ(rotationAngle)キャッシュできるため、フレームごとに呼び出す必要はありません。


私はこのすべてに新しいので、おそらくいくつかの擬似コードを提供してもらえますか。私は現在、2次元でのみ作業しているため、いくつかの複雑な問題が解消されています。
anonymouse

@anonymouse:確かに、これを試してください
BlueRaja-ダニーPflughoeft

15

2つの可能なテクニックがあります:

最初の手法は、フレームベースのシミュレーション実行することです。これは、ゲームプレイでホーミングミサイルのようなことをしていて、ターゲットに正確に当てる必要がない場合に適しています。

この場合、オブジェクトの位置と速度を追跡する必要があります。各フレームは、ターゲットへの方向と現在の移動方向を見て、速度を適切に調整します。

速度を即座にスナップすると、ミサイルは常にターゲットにヒットします。ただし、フレームごとに速度を少し調整すると、ミサイルはターゲットに向かって湾曲します。カーブが十分に遅い場合、ターゲットはそれを回避できます。

2番目の手法は、パラメトリック手法を使用することです。これは、ターゲットを正確かつ予測可能にしたいものをアニメーション化するのに役立ちます。この場合、通常はパラメーターとして「時間」を取り、それを何らかの関数に入れます。

特に有用な関数のセットは、高校の物理学で学んだ運動方程式です。これらを両方の軸に適用すると、弾道軌道を取得できます。少しの数学で、ターゲットにヒットするための初期パラメータを決定できます。ターゲットが予測どおりに動いた場合でも、移動するパラメータです。

XNAは、多数の補間および曲線運動機能も提供します。およびドキュメントをVector2 ご覧ください。これらは、興味深い機能を実行するために使用したり組み合わせたりすることができるいくつかの補間関数を提供します。たとえば、ミサイルの発射:(線形補間)ミサイルの位置を開始点からターゲット位置に移動し、そのターゲット位置を初期ターゲットからターゲットオブジェクトの実際の(変化する)位置に移動させます。これにより、「ロックオン」効果が得られます。MathHelperLerp

(一部の機能は、曲線を生成するためにもあり、例えば:CatmulRomHermite。これらはおそらく難しいものの、移動するターゲットで正常に使用することがあります。)

(アニメーションのコンテキストで) "緩和"を検討すると、加速などの興味深い効果を与えることができる、より興味深い補間関数を取得できます。

さて、ターゲットが動き回ると、この手法は奇妙な結果をもたらすと言うかもしれません。ただし、実際には、発射物がターゲットよりも速く動いている限り、通常は問題ありません。それが問題である場合は、おそらくフレームベースの手法を使用する必要があります。


3

正弦波または場合によってはベジェ曲線を検索できます。正弦波のアプローチが正常であるかどうかはわかりませんが、なぜそんなに貧弱になるのかわかりません。


Bスプラインでベジェ曲線を使用すると、任意の曲線をかなり正確に表現できます。精度が必要な場合、Cubic Hermitスプラインはわずかに正確です。時々、不正確さが歓迎されるような有機性を提供することに留意してください。
-doppelgreener

ベジェ曲線の場合は+1。説明した用途では、おそらく最も簡単で最も制御しやすいでしょう。
-ggambett

1

Craig Reynoldsによって定義されているSteering Behaviorsを見ることができます:http : //red3d.com/cwr/steer/

これは、NPCをターゲットに向かって移動させるためにAIでよく使用されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.