Search code examples
algorithmxna-4.0game-physics

Finding initial speed and angle to hit a known position (parabolic trajectory)


I am currently doing a small turn based cannon game with XNA 4.0. The game is very simple: the player chooses the speed and angle at which he desires to shoot his rocket in order to hit another player. There is also a randomly generated wind vector that affects the X trajectory of the rocket. I would like to add an AI so that the player could play against the computer in a single player mode.

The way I would like to implement the AI is very simple: find the velocity and angle that would make the rocket hit the player directly, and add a random modifier to those fields so that the AI doesn't hit another player each time.

This is the code I use in order to update the position and speed of the rocket:

            Vector2 gravity = new Vector2(0, (float)400);   // 400 is the sweet spot value that i have found works best for the gravity
            Vector2 totalAcceleration = gravity + _terrain.WindDirection;
            float deltaT = (float)gameTime.ElapsedGameTime.TotalSeconds; // Elapsed time since last update() call

            foreach (Rocket rocket in _instantiatedRocketList)
            {
                rocket.RocketSpeed += Vector2.Multiply(gravity, deltaT);  // Only changes the Y component
                rocket.RocketSpeed += Vector2.Multiply(_terrain.WindDirection, deltaT);   // Only changes the X component
                rocket.RocketPosition += Vector2.Multiply(rocket.RocketSpeed, deltaT) + Vector2.Multiply(totalAcceleration, (float)0.5) * deltaT * deltaT;

                // We update the angle of the rocket accordingly
                rocket.RocketAngle = (float)Math.Atan2(rocket.RocketSpeed.X, -rocket.RocketSpeed.Y);

                rocket.CreateSmokeParticles(3);
            }

I know that the basic equations to find the final X and Y coordinates are:

  • X = V0 * cos(theta) * totalFlightTime

  • Y = V0 * sin(theta) * totalFlightTime - 0.5 * g * totalFlightTime^2

where X and Y are the coordinates of the player I want to hit, V0 the initial speed, theta the angle at witch the rocket is shot, totalFlightTime is, like the name says, the total flight time of the rocket until it reaches (X, Y) and g is the gravity (400 in my game).

Questions:

What I am having problems with, is knowing where to add the wind in those formulas (is it just adding "+ windDirection * totalFlightTime" in the X = equation?), and also what to do with those equations in order to do what I want to do (finding the initial speed and theta angle) since there are 3 variables (V0, theta and totalFlightTime) and only 2 equations?

Thanks for your time.


Solution

  • You can do this as follows:

    Assuming there is no specific limit to V0 (i.e. the robot can fire the rocket at any desired speed) and using the substitutions

    T=totalFlightTime 
    Vx=V0cos(theta)
    Vy=V0sin(theta)
    

    Choose an arbitrary value for Vx. Now your first equation simplifies to

    X=VxT  so T=X/Vx
    

    to solve for T. Now substitute the value of T into the second equation and solve for Vy

    Y=VyT + gT^2/2  so Vy = (Y - gT^2/2)/T
    

    Finally you can now solve for V0 and theta

    V0 = Sqrt(Vx^2 + Vy^2)  and Theta = aTan(Vy/Vx)
    

    Note that your initial choice of Vx will determine the trajectory the missile will take - if Vx is large then T will be small and the trajectory will be almost a straight line (like a bullet fired at a nearby target) - if Vx is small then T will be large and the trajectory will be an arc (like a mortar round's path). You dis start with three variables (V0, totalFlightTime, and theta) but they are dependent variables so choosing any one (or in this case Vx) plus the two equations solves for the other two. You could also pre-determine flight time and solve for Vx, Vy, theta and V0, or predetermine theta (although this would be tricky as some theta wouldn't provide a real solution.