Saturday, June 8, 2019

2d - How to calculate the vector of an interception?


Given are a twodimensional space, and 1 friendly spaceship standing still, one foe is moving NOT directly to the friendly ship with known actual position, speed and direction.


The friendly ship wants to get itself into firing range to battle the foe.


Actually I am setting just a direct vector to the actual position moving ship, and recalculate it every frame, resulting in some kind of "round" flightpath.


What I want is to set a direct and straight path to the position that the foe will (presumably) will have when firing distance will be reached, assuming that foe will not change course until then.


As a first and "simple" implementation it would be enough if we assume the friend can speed up from 0 to max in no time.


Preffered implemantation would be one that considers the acceleration capabilities of the friend, and knows when interception is impossible because of the speed. It should work for every starting speed, not only from stand still. A plus would be if it even considers braking (battling at lightspeed is very energy inefficient in the given universe)



Answer



If I understand your question, you do not want the ship to steer to the target, but rather to fly in a straight line that happens to intercept the target. I'm making a tower defense game that basically has the same need for a tower's bullet, a tower wants to fire a gun such that the bullet will intercept a moving target as long as it doesn't change speed/direction. The way I solved it was by using a quadratic equation. Here is some pseudo code:


Vector totarget =  target.position - tower.position;


float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;

float t;

if (t1 > t2 && t2 > 0)
{
t = t2;
}
else
{
t = t1;
}


Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second

I found this to work so well I did not need collision detection for the shot... I was able to count on every shot hitting a bulls eye regardless of distance/direction/speed of target as long as those factors remained steady.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...