Gregory Hildstrom Projects Publications Resume Contact About Youtube Donate

Calculating Stray Bullet Origin


On the night of March 3rd, 2017, a stray bullet went through my friend's sunroof while his truck was parked outside. His driveway is oriented almost exactly north of his house, so the truck was oriented facing south. The bullet left a perfect bullet hole in the sunroof with cracks emanating outward in all directions. The hole was directly above the driver's seat. There was also a crack in the instrument panel plastic, but no hole, and the bullet was found completely intact on the driver's floor mat. There were no other obvious impact marks. Based on the location of the hole, the cracked plastic, and the final resting place of the bullet, it appears that the bullet arrived from almost directly due north. My friend's neighbor said they have found a few stray bullets in their back yard as well, which is the north side of their house. All clues point north, but how far?

I thought it would be interesting to try to calculate the ballistic trajectory and source of the shot.

Known Variables

Since we didn't have a second through-hole or a second precise impact point to get an angle from, the deformed nose of the bullet is the next best thing. The sunroof glass and driveway were very level, so the angle of the flat spot on the bullet should give a pretty accurate impact angle. I took a very careful and well-lit photo of the bullet. I played with image rotation in the Gimp program to get an impact angle of 48.7 degrees. Yes, the .7 might be ridiculous given the other assumptions and errors involved, but there's no reason to start sloppy. I measured that between the impact flat and the non-deformed cylinder side.

My calipers show it to be a 0.40 SW.

My scale shows it to be a 180 grain bullet. The photo shows 11g, but a few toothpicks showed that it was closer to 12g. I chose 11.6g for my calculations.

We know the exact impact location in NW San Antonio, the elevation, and the weather conditions (not raining, low wind, ~60F/15C, etc). We also know the approximate compass direction the bullet came from, north.

Unknown Variables

We had no clue about the distance to the shooter, the angle the shooter fired into the sky, or the speed of the bullet as it penetrated the sunroof.

Ballistic Calculators

The online ballistic and trajectory calculators I found were totally useless for this purpose. Most were set up for long-range shooters to predict bullet drop given well-defined initial conditions, like firing angle and distance to target. They are not set up to solve for these initial conditions, which is the opposite problem. I thought about manually iterating inputs, but the angles and distances I'm working with here are outside the scope of most calculator input ranges and most calculators do not output the terminal angle. I found a few that would calculate things in this range, but they all neglected air resistance and produced totally unrealistic distances and perfect parabolas.

Ballistic Flight with Air Resistance

I found an extremely helpful NASA page called Flight Equations with Drag. Unfortunately, I had some difficulty testing their Java applets and then I realized I did not like some of the assumptions made on the page. For example, they assume the projectile is traveling at terminal velocity for the entire descent. During vertical descent, "there is no net force acting on the ball and the vertical acceleration is zero." That's incorrect. At the flight apex, vertical velocity is zero because the projectile is not ascending or descenting for a moment. At the end of the flight, there is significant non-zero vertical velocity as the projectile hits the ground. Acceleration is change in velocity, so, there is obviously vertical acceleration taking place during descent. I found many of the equations, descriptions, and links on the page to be very helpful though and I used it as a starting point to calculate what I wanted.


I chose to do everything in metric units for simplicity. In the source code, I used "T" for θ (theta) to represent angles. I did far too many searches to list all of the relevant links here, but the relevant values and variables are documented in the code comments. I had to search for a while to get the drag coefficient for a simple bullet. Most resources want to discuss ballistic coefficient, which is how a bullet's drag compares to another bullet shape, but I eventually found a few resources that led me to choose the 0.25-0.29 drag coefficients I assumed for the G1 bullet shape traveling at the speeds I'm concerned with here.

I calculated the cross-sectional area of the bullet in m2, from radius in mm, with
A = π * r2 / 10002

Instead of deriving a set of equations to describe the position and orientation of the bullet at any instant in time, I chose to calculate the position and orientation of the bullet at just the next instant in time (n) and integrate in software. I thought this approach was simpler and faster, but it meant I had to iterate some to find relevant solutions instead of solving sets of equations.

Given an initial velocity Vi and an initial angle θi, the position of the bullet a fraction of a second later can be calculated. You don't need to do anything special in polar coordinates, but to convert to more useful Cartesian coordinates I needed to use sine and cosine functions to break the vector up into its vertical (y) and horizontal (x) components. Also, I cannot neglect gravity and drag, and it is important to note that the drag must be applied in the direction the bullet is traveling. I calculated the initial vertical and horizontal components of velocity.
Viy = sin(θi) * Vi
Vix = cos(θi) * Vi

I used the drag equation from NASA's page to calculate drag force and drag acceleration (deceleration).
Fd = Cd * A * 0.5 * ρ(air density) * Vn-12
ad = Fd / m

After calculating the drag acceleration using Vn-12, from the direction the bullet is traveling, I calculated the vertical and horizontal components of the drag acceleration. This allows them to be applied separately to the changes in vertical and horizontal velocity. That is necessary so I can also take gravity into account for the change in vertical velocity.
ady = sin(θn-1) * ad
adx = cos(θn-1) * ad

With a velocity vector and accelerations, I can calculate a new velocity vector and a new position a fraction of a second later. I used 1 millisecond as the time step; larger time steps increase error.
Vny = Vn-1y - ady * 0.001 - ag(9.80665) * 0.001
Vnx = Vn-1x - adx * 0.001
θn = tan-1(Vny / Vnx)
Vn = Vny / sin(θn)
Δy = Vny * 0.001
Δx = Vnx * 0.001

After doing that once, it's just a matter of looping through time steps and summing Δy and Δx. These steps all looped together effectively integrate to get the instantaneous speed, direction, and position along the path of the bullet. Because I didn't manually solve a derived equation, I had to iterate through a few initial angles, θi, for each Cd until I arrived at the measured terminal angle of impact, θt. I could have automated this programmatically, but it didn't take long to manually run the program a few times to get really close. The code has all of the details for constants, variables, and algorithm.



Impact velocity was around 76 m/s, 170 mph, 250 fps, which is definitely fast enough to do some serious damage to a person. That's similar to the speed of a paintball at close range, but with a much denser, sharper, and less forgiving projectile.

The distance is estimated to be around 1500m +/- 100m and the shooter likely shot into the air somewhere around 21-23 degrees above the horizon.

A little Google Earth work later, and I had an approximate location on the map. The elevation in that area is very similar to where the bullet struck. The search area is centered on a multi-acre property with another multi-acre property adjacent north of that. Interesting.

There is definitely room for improvement in my method and implementation, like recalculating air density based on instantaneous bullet altitude, recalculating drag coefficient based on instantaneous bullet speed, and not converting back and forth between degrees and radians, but I believe the assumptions and calculations I used are sufficient my purpose.

Source Code

Here is the source code: bullet.c