Skip to main content
GameDev.net gamedev.net
🔒 Locked

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

Started by sofakng Jul 18, 2005 at 1:06 PM 21 replies 23.9k views
Original Post
sofakng
sofakng
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
Palidine
Palidine
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
Raymond_Porter420
Raymond_Porter420
try this;

assuming all floats

BulletPosX += cosf(angle) * power;
BulletPosY += sinf(angle) * power;
BulletPosX += cosf(windAngle) * windPower;
BulletPosY += sinf(windAngle) * windPower;
sofakng
sofakng
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.

Am I going about this whole thing wrong?
KulSeran
KulSeran
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);
JohnBolton
JohnBolton
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:
    s<sub>0</sub> = sqrt( 2E/m )    m is the weight (actually mass) of the projectile 
Next, the initial direction of travel, given an angle, is this:
    D<sub>0</sub> = [ cos(angle), sin(angle) ] 
Now with the initial speed and initial direction, you have the initial velocity vector:
    V<sub>0</sub> = s * D<sub>0</sub> = [ 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 = P<sub>0</sub> + V<sub>0</sub>t + A<sub>g</sub>t<sup>2</sup>/2    P<sub>0</sub> is the initial position    A<sub>g</sub> 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:
    A<sub>w</sub> = [ f<sub>w</sub>/m, 0 ] 
The final equation looks like this:
    P = P<sub>0</sub> + V<sub>0</sub>t + (A<sub>g</sub> + A<sub>w</sub>)t<sup>2</sup>/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.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
sofakng
sofakng
Quote:
Original post by JohnBolton
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:
    s<sub>0</sub> = sqrt( 2E/m )    m is the weight (actually mass) of the projectile 

Thanks for the detailed reply!

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!
JohnBolton
JohnBolton
Quote:
Original post by sofakng
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?


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.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
sofakng
sofakng
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?
Nitage
Nitage
Quote:
Original post by sofakng
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?


E here represents how much energy is used to launch the projectile, which is a variable you should supply.
sofakng
sofakng
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!
DrEvil
DrEvil
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?
sofakng
sofakng
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...
Raxvan
Raxvan
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.

Raxvan
Raxvan
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.
sofakng
sofakng
Quote:
Original post by Anonymous Poster
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.

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.
Unwise owl
Unwise owl
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.
JohnBolton
JohnBolton
Quote:
Original post by sofakng
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)


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.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
JohnBolton
JohnBolton
Quote:
Original post by Unwise owl
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


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; 

John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.