Search code examples
artificial-intelligencephysicsgame-physics

Need help deciphering a formula for Projectile Motion


I need to implement a bit of AI to figure out how to hit a target with projectile motion.

I found this over at wikipedia:

Angle required to hit coordinate

Which looks like just the thing I need, especially since I have the added problem launching the projectile from above zero height. However, my maths skills aren't great so it all looks like complete nonsense to me and I have no idea how to translate any of it into code.

If anyone can break this down into something I can understand with basic operators (+ - * %) and functions (sin, cos, sqrt etc.), I'd really appreciate it.


Solution

  • If xTarget/yTarget is the position of the target, xProj/yProj the initial position of the projectile and v the initial velocity of the projectile (in meters per second), then the formula would translate to the following pseudo code:

    x = xTarget - xProj;
    y = yTarget - yProj;
    g = 9.8;
    
    tmp = pow(v, 4) - g * (g * pow(x, 2) + 2 * y * pow(v, 2));
    
    if tmp < 0
       // no solution
    else if x == 0
       angle1 = pi/2;
       if y < 0
          angle2 = -pi/2;
       else
          angle2 = pi/2;
       end
    else
       angle1 = atan((pow(v, 2) + sqrt(tmp)) / (g * x));
       angle2 = atan((pow(v, 2) - sqrt(tmp)) / (g * x));
    end
    

    g is the graviational constant (~9.8 m/s^2), atan is the arcus tangent function and pow is the power function. The if-statement is necessary, because the formula can have no solution (if the target is not reachable with the initial velocity), one solution (then angle1 == angle2) or two solutions (as can be seen in this animation; this is also why you have the +/- sign in the formula).

    In most programming languages you will also find atan2, in which case you should be able to replace some code with

    if tmp < 0
       // no solution
    else
       angle1 = atan2(pow(v, 2) + sqrt(tmp), g * x);
       angle2 = atan2(pow(v, 2) - sqrt(tmp), g * x);
    end