I've read through several other solutions here on stackexchange and not find a straight forward solution for this problem.
I've have a sourcePoint and targetPoint. The target has a targetVelocity (speed and direction), and source has sourceSpeed.
I need a way to calculate sourceDirection (which becomes sourceVelocity using sourceSpeed)
I've been looking at the math and it must be some kind of equation where the function may sometime return false, ie. the bullet can't catch up to the target, depending on targetVelocity and sourceSpeed
My current solution gives a direction but doesn't take into account the additional length required to reach the target as it's based on the length to target at firing time.
Also, if I can avoid Sqrt/Normalize that would be great for performance, but I'm looking for fairly simple/elegant solution.
/// Returns sourceVelocity
public static Vector2 calcBullet(Vector2 source, float sourceSpeed, Vector2 target, Vector2 targetVelocity)
{
var diff = target - source;
var dist = Vector2.Distance(diff, Vector2.Zero);
diff += targetVelocity * (dist / sourceSpeed);
diff.Normalize();
return diff * sourceSpeed;
}
If the sourceSpeed is greater than the targetSpeed (magnitude of the targetVelocity), then there is always at least one solution. If the sourceSpeed is smaller or equal to the targetSpeed, there might or might not be any solutions.
You can parametrize the path of the target by the amount of time that it takes for the target to get there, t. You want to solve an equation (which turns out to be quadratic) for the equality between the time it takes for the bullet to get there (distance(t)/sourceSpeed) and the time it takes for the target to arrive, t, and only solutions for nonnegative t will work.
distance(t) = magnitude(target + t*targetVelocity - source)
= sqrt((target.x-source.x + t*targetVelocity.x)^2 + (target.y-source.y + t*targetVelocity.y)^2)
= sqrt(quadratic(t))
So, you want to solve
t = sqrt(quadratic(t))/sourceSpeed
t* sourceSpeed = sqrt(quadratic(t))
t^2 * sourceSpeed^2 = quadratic(t)
If the t^2 terms cancel (which happens when the target speed equals the source speed), you get a linear equation (which would give you a division by 0 if you tried to use the quadratic formula). Otherwise, you get a quadratic equation you can solve using the quadratic formula, although you should check whether the discriminant b^2-4ac is negative before trying to take the square root. If the discriminant is negative, there are no solutions. Only nonnegative real solutions give you a way to shoot the target.
If there are two positive real solutions, you have to pick one. Once you find the correct value of t, t_solution, you know where the target will be, (target + t_solution * targetVelocity), and you can aim in that direction from the source.