Logo Computer scientist,
engineer, and educator
• Software • Utility corner

BDC — a bullet-drop calculator in Java

Version 0.1a

What is this?

BDC is a Java command-line utility that estimates and tabulates the trajectory of a bullet fired from a gun in still air. It takes into account the aerodynamic (drag) properties of the bullet, as well as the straightforward effect of gravity. To some extent the program will work for other projectiles — clay pigeons, tennis balls, etc. — but its main application is for generating range cards for target rifle shooting, where the aerodynamic behaviour of the projectile is well-defined.


Obtain the executable JAR file bdc.jar and copy it to any convenient directory. Obtain and install a Java JVM if necessary.

Basic operation

Run the program from a command prompt like this:
java -jar /path/to/bdc.jar {parameter1} {parameter2}...
If you enter no parameters then defaults will be used; these represent a generic .22LR subsonic practice round. In practice, you will almost certainly need to override at least some of the defaults.

The program prints a summary of its input paramters, and then a table of values of bullet drop, retained energy, and sight compensations for various distances downrange. The table values are comma-separated, to make it easy to load them into a spreadsheet or graph plotter.

The usual mode of operation is to specify the distance at which the rifle sights are zeroed, and then have BDC tabulate the drop and compensation for distances other than this:

java -jar /path/to/bdc.jar --zero 75yd
Notice that all input values in BDC take units of measure. If no unit is given then a default will be used. However, I recommend entering units on all input values because the defaults might not be what you expect. A complete list of acceptable units is given later in this document.

Here is a more complicated example: tabulate the trajectory over 500 yards in 100 yard steps, for a rifle zeroed at 100 yards with a sight one inch above bore, using a 1000fps bullet of default weight, using imperial units.

$ java -jar bdc.jar --distance-step=100yd --zero=100yd --velocity=1000fps --range=500yd --sight=1in -i

Bullet weight: 38.0 gr
Muzzle velocity: 1000.0 fps
Muzzle departure angle: 19.4 moa
Calculation range: 500.0 yd
Zero point: 100.0 yd
Sight height: 1.0 in
Ballistic coefficient: 0.125

Distance(yd), Velocity(fps), Energy(ft-lb), Drop(in), MOA, Mils
0.0, 1000.0, 84.4, 1.0, 0.0, 0.0
100.0, 868.8, 63.7, 0.0, 0.0, 0.0
200.0, 775.4, 50.7, 45.2, 21.6, 6.3
300.0, 697.9, 41.1, 148.4, 47.2, 13.7
400.0, 630.7, 33.6, 323.4, 77.2, 22.5
500.0, 570.9, 27.5, 586.3, 112.0, 32.6
Note that the default is to use metric units for both input and output, because that is what the math uses. However, imperial units are probably more widely used in practice, at least in the UK and USA.

Command-line switches and parameters

Please note that most of these parameters allow units of measure to be specified (see "Units of measure" below).

-a, --angle=[angle]
The muzzle departure angle, that is, the angle that the gun muzzle makes with the line of sight to the target. This can only ever usefully be a positive (upwards) rotation, else the bullet will never cross the sight line. If this parameter is specified, the zero distance (--zero) will be ignored, as the departure angle sets the zero point. Note that the default unit of angular measure is minutes of angle; to use degrees specify, for example, "12.2deg".

The downrange distance between tabulated intervals, default 25m. Note that the calculation proceeds by time step, not distance step. To tablulate in uniform distance increments we have to interpolate between the results at specific time steps. Specify a zero value for this parameter to plot all time steps instead. This is generally a better approach if preparing data for a plot, rather than a range card.

Use the G7 drag model instead of the default G1 model.

Use the Gs (ball) drag model instead of the default G1 model.

-m, --metric
Use metric, rather than imperial, values for output.

-r, --range=[distance]
Specifies the distance over which the trajectory is to be calculated. This should be at least as far as the zero distance and, in practice, will often be mcuh further. Making the range too long adds significantly to the calculation time, and can lead to a "free fall" situation (see "Technical notes" below) which prevents the trajectory calculation completing. The default value is 300m.

-s, --sight=[distance]
Height of the gun sight above the centre of barrel bore. The default value is 1cm, which is approximately correct for open sights; scopes may require much larger values, perhaps as much as 10cm. An error here typically translates to an error at least as large at the target, so even though the value is small it should be specified.

-v, --velocity=[velocity]
Muzzle velocity of the projectile. The default value is just below the speed of sound. By default the value is set in metres/second.

-w, --weight=[weight]
Weight (more properly mass) of the projectile. The default unit is kilograms, which is rather large for a bullet. To specify a weight in grains use, for example, --weight=50gr.

-z, --zero=[distance]
Specifies the distance at which the gun is correctly "sighted in," and which will be used as the reference position for adjustments for other ranges. The default value is 100m.

Units of measure

BDC uses the following abbrevations for units, both for input and output. If no unit is given, the default will be used, but it is generally a good idea to specify the units explicitly.

Distance: m (metres), yd (yards), cm (centimetres), ft (feet), in (inches); default: m

Velocity: mps (metres per second), fps (feet per second); default: mps

Mass: kg (kilograms), g (grams), gr (grains, not grams); default: kg

Angle: moa (minutes of angle), deg (degrees); default: moa

For input values, units can be given with or without spaces: "50 m" is the same as "50m." However, the command-line shell might misinterpret spaces as separators, so it's probably safer to write "50m".

Technical notes

  • In case it isn't obvious: a negative value of drop is a rise; that is, the projectile is above the sight line.
  • By default BDC assumes that the projectile follows the "G1" drag model, but G7 and Gs can alternatively be specified using the --G7 and --Gs switches. The Gs model nominally suits spherical projectiles like musket balls.
  • BDC will attempt to find the muzzle departure angle that gives the specified zero distance with a tolerance of 10cm.
  • The elapsed time between iterations of the trajectory calculator is fixed at 10 msec.
  • Free fall: a bullet is assumed to be in free fall if it moves less than 1mm in the horizontal direction between time steps. Generally the program will not present results if the range of calculation leads to free fall. A range too great can cause problems when determining the sighting distance as well as calculating the trajectory.
  • Bullet weight: bullet weight makes almost no difference to trajectory. A 1kg projectile will follow essentially the same path as a 1g projectile, if launched at the same speed and angle. This result only seems anomalous because, in practice, you can't launch a projectile that weighs 1kg at the same speed as one that weighs 1g, except from a canon. BDC uses the projectile weight simply to display the retained downrange energy.

Bugs and limitations

  • BDC does not check whether the specific units of measure are sensible or not. You will get odd results if you specify an angle in feet per second, for example.
  • Air density, which affects drag, is fixed at a typical value of 1.225 kg/m3.
  • It can be very difficult to calculate a trajectory with a zero point that is very close (less than 30m or so). This is because BDC must determine the muzzle departure angle that provides that particular zero point and, in these circumstances, even tiny variations in the muzzle departure angle will cause very large differences in the zero distance. This can defeat the algorithm that attempts to find the departure angle. If this happens, it can be more effective to specify the departure angle (--angle) explicitly, and adjust it by trial-and-error to give the desired zero point (which will be the point where the tabulated drop values switch from negative to positive).
  • Be careful — "g" is an abbreviation for "grammes," whilst "gr" is an abbreviation for "grains." Both are small measures of mass/weight.
  • The fastest muzzle velocity that can be accomodated is Mach 5, because that is the highest speed for which coefficient-of-drag data for projectiles is available. This will rarely be a limitation in target rifle shooting or, indeed, any other kind of shooting.
  • At present, BDC handles only still air, and has no provision for estimating windage, or the effects of head or tail winds.

Further information

For a description of the mathematical algorithm used by this program, see this article.

Legal and author

BDC is maintained by Kevin Boone (kevin at railwayterrace dot com), as an example how to perform certain kinds of computational math using Java. The program source is distributed according to the terms of the GNU Public Licence, version 2.0. There is no warranty of any kind


Java source code
Executable JAR file
Copyright © 1994-2015 Kevin Boone. Updated Oct 06 2015