# Does anybody have a simple ballistic trajectory algorithm I can use?

## Recommended Posts

sofakng    102
Me and a friend are trying to make a Scorched Earth type of game and we can't figure out a ballistic trajectory algorithm. Does anybody have one that I can use? Ideally, I'd like to have four variables: angle, power, weight (some projectiles will "weigh" more), and wind. However, if I could get anything that simply used power + angle that would be great :) Thanks in advance

##### Share on other sites
Palidine    1315
just learn some basic physics. It's pretty easy. This page seems to describe it nicely. Make sure to start from the beginning of the page or the Projectile Trajectory section won't make any sense:

http://www.atarimagazines.com/startv5n2/physics.html

don't worry about wind to start with. But once you get there, wind in those games is just a horizontal acceleration.

-me

##### Share on other sites
try this;

assuming all floats

BulletPosX += cosf(angle) * power;
BulletPosY += sinf(angle) * power;
BulletPosX += cosf(windAngle) * windPower;
BulletPosY += sinf(windAngle) * windPower;

##### Share on other sites
sofakng    102
Palidine: Thanks for the link! Using the formulas in that page I've been able to create an algorithm that draws a parabolic curve but it doesn't factor in wind and I don't think gravity works properly.

Raymond_Porter420: Thanks for the help but I'm not sure how to use that. Don't I have to give it a time or something? I'm very confused :(

Ideally I'm planning to have an object for each projectile (missle, bullet, laser, etc). Inside that object I'm going to keep track of the x,y coordinates as well as the velocity. When the projectile is created it will generate a trajectory but every frame the trajectory will be checked for any collisions. If there is a collision with a specific object (magnetic field, etc) then I'd like to recalculate a new trajectory.

##### Share on other sites
KulSeran    3267
using the accelerated motion formula from the link above:
pos = vi + v*t + .5*a*t^2
you can calculate the tajectory once you know your accelerations (and inital v)

F=ma can calculate the acceleration you need. Supply the power as a force(F),
and devide by mass(m) to get the acceleration. The wind can also be represented as a force.

since the componets of a vector can be broken up, the sin/cos formula above
allows you to split up your power by the angle supplied.
forcex = cos(angle);
forcey = sin(angle);

##### Share on other sites
JohnBolton    1372
First, "power" is not appropriate in this situation. I think a better parameter is "kinetic energy". A gun can give a projectile a fixed amount of kinetic energy, so heavier projectiles will travel more slowly than lighter projectiles. The formula for kinetic energy is E = ms2/2, so the initial speed is this:
    s0 = sqrt( 2E/m )    m is the weight (actually mass) of the projectile
Next, the initial direction of travel, given an angle, is this:
    D0 = [ cos(angle), sin(angle) ]
Now with the initial speed and initial direction, you have the initial velocity vector:
    V0 = s * D0 = [ s*cos(angle), s*sin(angle) ]
Finally, ignoring wind and air resistance, the position of the projectile at any time is given by this formula:
    P = P0 + V0t + Agt2/2    P0 is the initial position    Ag is acceleration due to gravity [0, -9.8 ]
Now, dealing with air resistance and wind makes this much more complicated (if done accurately). You can simplify things by ignoring air resistance and treating wind as horizontal force. Since, f = ma, and thus a = f/m, you can treat wind as a simple acceleration that is included in the equation. The acceleration due to wind is this:
    Aw = [ fw/m, 0 ]
The final equation looks like this:
    P = P0 + V0t + (Ag + Aw)t2/2

So, given the energy of the gun (E), the position of the gun (P0), the angle of the gun (angle), the mass of the projectile (m), and the force of the wind (fw), you can calculate the position of the projectile with the above equation.

##### Share on other sites
sofakng    102
Quote:
 Original post by JohnBoltonFirst, "power" is not appropriate in this situation. I think a better parameter is "kinetic energy". A gun can give a projectile a fixed amount of kinetic energy, so heavier projectiles will travel more slowly than lighter projectiles. The formula for kinetic energy is E = ms2/2, so the initial speed is this:  s0 = sqrt( 2E/m ) m is the weight (actually mass) of the projectile

I'm confused on that first equation though. s0 = sqrt( 2E/m )

What does E represent?

Also, in this equation: P = P0 + V0t + Agt2/2

I'm assuming P0, V0, and Ag are all vectors right? What does t represent?

Finally, in your last equation, you have Aw did you mean Fw?

Sorry for all of the questions but I really think I'm beginning to understand all of this!

##### Share on other sites
JohnBolton    1372
Quote:
 Original post by sofakngI'm confused on that first equation though. s0 = sqrt( 2E/m )What does E represent?Also, in this equation: P = P0 + V0t + Agt2/2I'm assuming P0, V0, and Ag are all vectors right? What does t represent?Finally, in your last equation, you have Aw did you mean Fw?

E is the kinetic energy output of the gun. s0 is the muzzle velocity. The equation is simply a rearrangment of the standard kinetic energy equation E = mv2/2. This doesn't match reality but it should be good enough.

P0, V0, Ag, and Aw are vectors. t is elapsed time.

Aw is the acceleration due to the wind. It comes from the force of the wind parameter and the equation a = f/m.

##### Share on other sites
sofakng    102
Wouldn't I need to know the value for E and m to calculate s0 = sqrt( 2E/m )? Does that mean I calculate E = mv2/2 first (by giving it a mass and a velocity [angle?]) and then using the E value for the other equation?

##### Share on other sites
Nitage    1107
Quote:
 Original post by sofakngWouldn't I need to know the value for E and m to calculate s0 = sqrt( 2E/m )? Does that mean I calculate E = mv2/2 first (by giving it a mass and a velocity [angle?]) and then using the E value for the other equation?

E here represents how much energy is used to launch the projectile, which is a variable you should supply.

##### Share on other sites
sofakng    102
That worked perfectly!! Thank you!

Is it much more difficult to add air resistence?

Also, do you have any formulas to tell me the peak height of the projectile, time it will be in the air, or the formulas backwards? (if I give an x,y target coordinate, what angle (and power, etc) will I need to hit it? (this would be for the AI)

I think I can use those formulas to have special effects (eg. at the peak height I can remove the projectile and generate two or three new projectiles, which will look like the bomb split off into two pieces)

Thank you again -very- -very- much for your help!

##### Share on other sites
DrEvil    1148
I'm curious why you need to calculate this anyhow.

If you send a projectile along a vector at some magnitude, and add your gravity vector * deltatime and your wind vector * delta time to the velocity each game frame you would get your trajectory for free. Are you calculating it to look into the future or something?

##### Share on other sites
sofakng    102
Yes, I'd like to look into the future of a projectile so I can have special effects at the height of my trajectory, etc.

I've run into another problem... (this will be my last question, honest!)

JohnBolton's formulas use "t" for time. In my program I'm using a loop that increments time by 0.1 and then plots the new x and y coordinates. The problem is that it's not a nice smooth graph. Instead, I'll have a dot at (10, 20) say but instead of having the next point at (11, 21) it might jump to (15, 30).

I'd like to get all possible x,y values so I can animate the projectile moving very smoothly. Is this possible?

[EDIT] Damn, this wouldn't work either. I just realized that if I do this it will seem as if the projectile has the same speed across the entire trajectory...

##### Share on other sites
Raxvan    100
I cad find out a really complicated formula used for calculating object trajectory starting from a point with speed angle and weight.it is used in physics and i learned it last ear. if you need it i can ask someone to tell me again.

##### Share on other sites
DrEvil    1148
You can still use the simpler vector methods to do effects at the height of the projectiles. Simply look for when the vertical velocity goes from positive to negative.

##### Share on other sites
Raxvan    100
Another method is using the sin function graphic.On a specific interval the graphic looks like a ballistic trajectory
this is the moast sinple method ever.

##### Share on other sites
Guest Anonymous Poster
Quote:
 Original post by sofakngAlso, do you have any formulas to tell me ... the formulas backwards? (if I give an x,y target coordinate, what angle (and power, etc) will I need to hit it? (this would be for the AI)

It can be done, but that would make a horrible AI if it knew the exact numbers to plug in, It would essentually turn the computer into a unbeatable opponent unless the human player did the calculations as well.

Have the AI start with a random power and angle that makes sence, and check to see where it lands. Record each input and outcome of each of the AI's guesses and tweak the power and angle accordingly to what the computer has already tried.

If you want levels of difficulty
easy - Random guess at first and use gained knowledge to make guess better. Which would be used in every level of difficulty, even expert. Stated above.

medium - use the backward equations, a.k.a take the equations and solve for power. Only let the AI know an angle and power being some number between +/- 10 degrees and units of power from the actual power and angle. It wont know anything else besides the output returned. It would not know that it would be bewteen +/- 10 units and degrees off.

hard - Decrease the number that the power and angle could be off that was returned by the medium AI to perhaps 3 power units and degrees off.

expert - Return the correct numbers for power and angle... make sure that the human player goes first. He only had one shot at it. May as well make it count.

This would not be totally perfect if you have terrain that may block the projectile, in which case the angle or power may need to be adjusted. Most likely the angle would need to be changed along with power to compensate for the gain/loss in the angle.

Note: the amount that each AI setting could be off are just guesses on what they should be, test it a couple times until you tweak the amount of the educated guesses to an approperate level.

##### Share on other sites
Guest Anonymous Poster
Quote:
 Original post by sofakngYes, I'd like to look into the future of a projectile so I can have special effects at the height of my trajectory, etc.I've run into another problem... (this will be my last question, honest!)JohnBolton's formulas use "t" for time. In my program I'm using a loop that increments time by 0.1 and then plots the new x and y coordinates. The problem is that it's not a nice smooth graph. Instead, I'll have a dot at (10, 20) say but instead of having the next point at (11, 21) it might jump to (15, 30).I'd like to get all possible x,y values so I can animate the projectile moving very smoothly. Is this possible?[EDIT] Damn, this wouldn't work either. I just realized that if I do this it will seem as if the projectile has the same speed across the entire trajectory...

If you want to make it smooth, you will have to remove the 0.1 loop increment and use actual frame time to update the current x,y coordinate.

##### Share on other sites
sofakng    102
Quote:
 Original post by Anonymous PosterIf you want to make it smooth, you will have to remove the 0.1 loop increment and use actual frame time to update the current x,y coordinate.

Can you elaborate on this a little more?

I'm using DelphiX (DirectX for Delphi) and it has a timer object which I can set to fire as often as I want. Typically this is set to 1 millisecond. Every time the timer fires I draw a frame...

How/where do I get the frame time and how do I implement that into my equation?

Again, I really appriciate everybodys help with this.

##### Share on other sites
Guest Anonymous Poster
The problem is that timer will not most likely trigger in one millisecond in reality (probably at a much greater interval), and even if it does, don't expect your game to take one millisecond to update...

Measure time taken since last frame, and either multiply your velocities and accelerations by that, or, increase it by a certain number of physics updates, each with a fixed length.

##### Share on other sites
Unwise owl    158
Err the previous poster was me.

There are really lots of articles on this, check the Articles section here on GD. However, it's really simple if you're don't mind huge errors:

To elaborate more, let's say you got an object with these vectors:

Position.
Velocity.
Acceleration (is calculated independently).

In my lame pseudo-code below I've left out variables types; they should be floats of either double or single precision (single precision typically works best while processing graphics simultaneously, but will lead to greater precision errors).

Now, in to use the first approach you get the delta time as I said. You have to find the best timer function you can, because this approach requires a very high resolution. Now, if the timer function returns the number of seconds since the system was started (dt is delta time or time difference):

function UpdatePhysics()
time_thisframe = GetElapsedTime()
dt = time_thisframe - time_lastframe
//insert everything else in between here
time_lastframe = time_thisframe //this should really the last bit in the function

//I guess you can also send dt as an argument to this function, it probably results in cleaner
//code, but it spreads out the example pseudo code further
end function

Now, delta time should be in seconds so if the timer returned milliseconds you will have to divide by 1000 etc.

For each object (called obj here), you will typically do this after you've calculated the acceleration of it in every frame:

obj.velocity.x += obj.acceleration.x * dt
obj.velocity.y += obj.acceleration.y * dt
obj.position.x += obj.velocity.x * dt
obj.position.y += obj.velocity.y * dt

Now, as can be seen, the only acceleration that would influence a projectile already fired is gravity..

I don't recommend this for anything but singleplayer games that don't require particulary stable physics. And finding a good enough timer is still a problem (the Windows function QueryPerformanceCounter() should do though).

Basically, the other methods is to do physics updates in fixed steps, and vary the number of steps depending on how many already was done in the last second or so. Of course, this sampling period may be a bit greater though to better ensure a good average. Delta time is constant in this model, but the UpdatePhysics() function is called a different number of times. It has the advantage of the model being much easier to predict and debug, and can also help networking games a lot.

##### Share on other sites
JohnBolton    1372
Quote:
 Original post by sofakngIs it much more difficult to add air resistence?Also, do you have any formulas to tell me the peak height of the projectile, time it will be in the air, or the formulas backwards? (if I give an x,y target coordinate, what angle (and power, etc) will I need to hit it? (this would be for the AI)

Air resistance is much more complicated because it involves differential equations. There are ways to approximate it, but I still recommend that you do without it for now seeing that you are already in pretty deep.

##### Share on other sites
JohnBolton    1372
Quote:
 Original post by Unwise owlFor each object (called obj here), you will typically do this after you've calculated the acceleration of it in every frame:obj.velocity.x += obj.acceleration.x * dtobj.velocity.y += obj.acceleration.y * dtobj.position.x += obj.velocity.x * dtobj.position.y += obj.velocity.y * dt

This is called Euler integration and it should be avoided because not only is it very inaccurate, but the results change according to the frame rate.

When the acceleration is constant, the exact solution can be computed with this code. Note that the order of the lines is critical.
    obj.position.x += obj.velocity.x * dt + obj.acceleration.x * dt * dt * 0.5f;    obj.position.y += obj.velocity.y * dt + obj.acceleration.y * dt * dt * 0.5f;    obj.velocity.x += obj.acceleration.x * dt;    obj.velocity.y += obj.acceleration.y * dt;