2D物理演算(Z速度なし)のみを使用しているため、この問題は大幅に簡略化できます。これを行う簡単な方法は、ワールド座標に対して相対的に動くソースとターゲットの両方について考えるのをやめ、ソースに対して相対的に動くターゲットだけを考えることです(そしてソースを静止したままにします)。
Vector TargetInitialPosition = new Vector ( target.X - source.X ,
target.Y - source.Y );
Vector TargetApparentVelocity = new Vector( target.velocityX - source.velocityX ,
target.velocityY - source.velocityY );
通常、弾丸の速度は射手の速度よりもはるかに速いため、通常、弾丸は独立していると想定されますが、ヘリコプターや戦闘機から発砲するなど、これが当てはまらない場合もあります。
次に、弾丸の速度を計算する必要があります。
// Your directional vector MUST be normalized...
Vector BulletVelocity = new Vector( source.directionX * Bullet::StaticSpeed + source.velocityX ,
source.directionY * Bullet::StaticSpeed + source.velocityY );
あなたが抱えている問題は、弾丸がそれらに到達するまでにターゲットが動いていることです。
TargetPosition = TargetInitialPosition + TargetApparentVelocity * t
BulletPosition = BulletInitialPosition + BulletVelocity * t
= BulletVelocity * t
TargetPosition == BulletPositionを解くと、弾丸がターゲットに当たるはずです。これで、未知数は3つ、方程式は2つだけになりました。一次導関数を取ることで「t」を削除できます。
TargetInitialPosition + ( TargetApparentVelocity - BulletVelocity ) * t == 0
dV / dt = TargetApparentVelocity - BulletVelocity
目標を達成するために、あなたは望みdV/dt == -TargetInitialPosition * k
ます。定数はX座標とY座標で同じである必要があり、弾丸がターゲットに当たるまでにかかる秒数です。
TargetApparentVelocity.X - BulletVelocity.X == k * -TargetInitialPosition.X
k = ( BulletVelocity.X - TargetApparentVelocity.X ) / TargetInitialPosition.X
----------------------
TargetApparentVelocity.Y - BulletVelocity.Y == k * -TargetInitialPosition.Y
k = ( BulletVelocity.Y - TargetApparentVelocity.Y ) / TargetInitialPosition.Y
それらを等しくする:
( BulletVelocity.X - TargetApparentVelocity.X ) / TargetInitialPosition.X
= ( BulletVelocity.Y - TargetApparentVelocity.Y ) / TargetInitialPosition.Y
または変数を展開するには:
( source.directionX * Bullet::StaticSpeed + source.velocityX - target.velocityX + source.velocityX ) / ( target.X - source.X )
== ( source.directionY * Bullet::StaticSpeed + source.velocityY - target.velocityY + source.velocityY ) / ( target.Y - source.Y )
次に代数はあなたにあなたの最終的な方程式を与えます:
source.directionY = ( target.velocityY * ( source.X - target.X ) - 2 * source.velocityY * ( source.X - target.X ) + ( Bullet::Speed * source.directionX + 2 * source.velocityX - target.velocityX ) * ( source.Y - target.Y ) ) / ( Bullet::Speed * ( source.X - target.X ) )
次の部分は乱雑で、コードにどのように実装するかはあなた次第ですが、これを代入してベクトルを正規化するだけです。
sqrt( source.directionX ^ 2 + source.directionY ^ 2 ) == 1
結局、未知数が1つだけの方程式(source.directionX)になり、directionXの代わりにそれを解いて、代入してdirectionYを取得できます。
私はこのコードのいずれもテストしていませんし、私が行った数学上の間違いを指摘していただいてもかまいませんが、理論は正しいはずです:)。
幸運を。