Quick Maths 1: Projectiles and Targeting
This is the first in a series of quick tutorials on helpful maths, physics and algorithms, and their ActionScript implementations. Today we’re going to learn how to shoot a projectile out of the sky. Sweet.
First, let’s define the algorithm’s structure. We’re going to pass the time to collision. The algorithm will return the muzzle velocity that our projectile requires to hit a moving target out of the air after this specified amount of time.
function solveMuzzleVelocity( timeToImpact:Number ) : Vector
Next, we have to define the equations of motion:

x1 is a particle’s position after t seconds. x0 is the original position and the dots represent the first and second positional derivatives (velocity and acceleration, respectively). This equation allows us to solve for position after any specified time (given constant acceleration). Referring to our algorithm’s structure, we know t (timeToImpact) to be defined. This means that we can determine where the target will be when we hit it, which gives us a point of impact:
//point of impact var poi:Vector = target.position.plus( target.velocity.times( timeToImpact ) ); poi.plusEquals( new Vector( 0, Projectile.G * timeToImpact * timeToImpact * 0.5 ) );
It’s assumed that the only accelerative force is gravity (Projectile.G here), that we know the starting position of the target and our projectile, and the current velocity of the target.
Plugging this point of impact in for our projectile’s equation of motion (as x1), we eliminate all unknowns except the muzzle velocity. Through basic algebraic manipulation, we can isolate and solve for this unknown:

Finally, divide each side of the equation by t:

The algorithm will return this value. Here’s my implementation, in full:
1 2 3 4 5 6 7 8 9 10 11 12 13 | private function solveMuzzleVelocity( timeToImpact:Number ) : Vector { //point of impact var poi:Vector = target.position.plus( target.velocity.times( timeToImpact ) ); poi.plusEquals( new Vector( 0, Projectile.G * timeToImpact * timeToImpact * 0.5 ) ); var diff:Vector = poi.minus( projectile.position ); diff.y -= Projectile.G * timeToImpact * timeToImpact * 0.5; return diff.dividedBy( timeToImpact ); } |
Super simple! Now you can integrate dynamically and knock some shit out of the sky.
Here’s a verbose implementation that doesn’t use my Vector class and isn’t dependent on my application:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private function solveMuzzleVelocity( t:Number, xp:Point, xt:Point, vt:Point, pixelToMeterRatio:Number = 40 ) : Point { const g:Number = 9.81; var vDotTerm:Number = g * pixelToMeterRatio * t * t * 0.5; var poiX:Number = xt.x + vt.x * t; var poiY:Number = xt.y + vt.y * t + vDotTerm; var diffX:Number = poiX - xp.x; var diffY:Number = poiY - xp.y - vDotTerm; return new Point( diffX / t, diffY / t ); } |
t is time to impact, xp holds the x and y coordinates of the projectile’s starting position, xt is the target’s starting position, vt is the target’s starting velocity and pixelToMeterRatio defines how many pixels represent one meter.

Genius.
Srsly, though, neat.
Awesome, I don’t think there is one post of yours that i haven’t learned something or have it become more clear. Thanks.
Thanks, Ryan- I’m happy to hear it’s helpful!
Great!
Wow! Thank you very much for putting this together. It is really interesting and useful to see math in action in such a way. I look forward to future installments.
Cheers,
Joel
Thanks! This is really great, I’ll be looking forward to the rest of the series.
Hey, that’s pretty sweet!
I’m working on something similar, and I was wondering if you could give me some pointers. I’ve got one stationary object shooting at a moving object. I want the shooting object to be able to lead the moving object so its projectile will hit it, assuming the projectile and the moving object both maintain constant velocities.
I’m guessing I could work from your algorithm, remove gravity (it’s a top-down POV), and somehow solve for the shortest time until impact? Any help would be greatly appreciated!