The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Physics::Ballistics::External -- External ballistics formulae.

ABSTRACT

External ballistics is the study of projectiles in flight, from the time they leave the barrel (or hand, or trebuchet, or whatever), to the moment before they strike their target. This module implements mathematical formulae and functions useful in the analysis and prediction of external ballistic behavior.

ANNOTATIONS OF SOURCES

Regarding their source, these functions fall into three categories: Some are simple encodings of basic physics (like energy = 1/2 * mass * velocity**2), and these will not be cited. Others are from published works, such as books or trade journals, and these will be cited when possible. A few are products of my own efforts, and will be thus annotated.

OOP INTERFACE

A more integrated, object-oriented interface for these functions is under development.

FUNCTIONS

ebc (mass_grains, diameter_inches, [shape,] [form_factor])

Attempts to predict the G1 ballistic coefficient of a projectile, based on its mass, width, and shape. Useful for predicting the ballistic behavior of hypothetical or new, untested projectiles. When compared against the known G1 BC's of well-understood projectiles, its predictions usually come within 5% of actual.

The "shape" parameter indicates that the hypothetical projectile is closest in its shape, composition, and quality of manufacture to the named entity. Some shapes are very general ("hollowpoint", "fmj") while others are very specific to product families manufactured by particular companies ("scenar", "amax").

The "shape" parameter maps to a numerical form base (see table below), which gets tweaked a little by other factors to derive a form factor. The form factor has an inverse impact on ballistic coefficient (higher form factor means a lower coefficient). In lieu of depending on the "shape" parameter, a form factor may be specified as a parameter (mostly useful for debugging or deriving new entries in the shape table).

When no shape or form factor are provided, the "default" shape is used, which has a form base chosen to minimize the error produced by this function when its output is compared to entries in http://www.frfrogspad.com/g1bclist.xls not already covered in the shape table.

A hashfile including all of the information from g1bclist.xls with "shape" entries matching the names from the shape table below may be found here: http://ciar.org/ttk/mbt/guns/table.bc.hash

This function is the original work of the module's author.

    parameter: (float) mass of the projectile (in grains)

    parameter: (float) diameter of the projectile (in inches)

    parameter: (str) OPTIONAL: shape/composition of the projectile (see table below, default is "default")

    parameter: (float) OPTIONAL: custom form-factor of the projectile, unnecessary if "shape" is provided.

    returns: a list, containing the following values:

        * The estimated G1 ballistic coefficient,
        * The form factor (suitable for use as as form_factor parameter)
        * The "very short factor" (1.0 for most well-proportioned bullets)
        * The shape parameter used

The shape table currently contains the following entities, with the given form bases:

    '7n14'              => 111, # Very deep ogival shape and boat-tail with tight tolerances, used in military 7.62x54R specifically for sniping.
    'scenar'            => 124, # Scenar, by Lapua
    'scenar_s'          => 124, # Scenar Silver, by Lapua, appears ballistically indistinguishable from Scenar
    '7n1'               => 125, # Very deep ogival shape and boat-tail, used in military 7.62x54R.  qv http://7.62x54r.net/MosinID/MosinAmmo007.htm
    '7n6'               => 125, # Very deep ogival shape and boat-tail, used in military 5.45x39mm  qv http://7.62x54r.net/MosinID/MosinAmmo007.htm
    '7n6m'              => 125, # Synonym for 7N6
    'amax'              => 127, # A-Max, by Hornady
    'boat_tail_og'      => 128, # Catch-all for many boat-tailed projectiles with long, pointed ogival nose shapes
    'hollowpoint_ct'    => 131, # CT variation of hollowpoint "match" projectiles, by Nosler
    'bst'               => 136, # A type of flat-bottomed ogival, by Nosler
    'spire_point'       => 138, # A type of flat-bottomed ogival, by Speer
    'boat_tail_nosler'  => 138, # Nosler's line of boat-tails perform more poorly than others for some reason
    'boat_tail_ct'      => 139, # Nosler's CT variation of boat-tail
    'spitzer'           => 139, # Another flat-bottomed ogival, by Speer.  Good fit to many military bullets.
    'hollowpoint_match' => 140, # Catch-all for many hollowpoint "match" projectiles
    'accubond'          => 142, # An expansive line by Nosler offering controlled terminal expansion
    'interbond'         => 142, # A line of polymer-tipped bullets by Hornady optimized for terminal cohesion
    'vmax'              => 145, # A line of polymer-tipped bullets by Hornady optimized for terminal expansion / fragmentation
    'gold_match'        => 147, # A type of wadcutter, by Speer
    'grand_slam'        => 159, # Another wadcutter, by Speer, with less streamlined nose shape for higher overall mass
    'hollowpoint'       => 176, # Catch-all for many large-game hollowpoint projectiles
    'default'           => 179, # Catch-all for unknown/unspecified shapes; derived via best-fit to ballistic table
    'fmj'               => 187, # Catch-all for military full metal jacket with boat-tail and short nose
    'mag_tip'           => 190, # Another wadcutter, by Speer
    'afss'              => 202,
    'tsx_fb'            => 205, 
    'plinker'           => 205, # Typical of short, underweight, round-nosed, non-streamlined projectiles,
    'semispitzer'       => 224, # A foreshortened, flat-bottomed projectile, by Speer
    'round_nose'        => 228, # Catch-all for many flat-bottomed, hemispherical-nosed projectiles
    'varminter'         => 232, # Catch-all for many light hollowpoints with very large expanding cavities, for varminting
    'fmj_2'             => 268  # Woodleigh's FMJ projectiles, which are shape-optimized for travel in big game meat and bone, instead of air.

This hash table is exported as %Physics::Ballistics::External::Bullet_Form_Factors_H, so that users and modules may easily modify/add its content without resorting to editing sources.

flight_simulator (drag_function, ballistic_coefficient, muzzle_velocity_fps, sight_height_inches, shot_angle_deg, [bore_to_sight_angle_deg,] zero_range_yards, wind_speed_fps, wind_angle_deg, [max_range_yards])

Attempts to predict the flight characteristics of a projectile in flight, providing a data point for every yard of progress it makes downrange.

This is a pure-perl port of the "SolveAll" function from GNU-Ballistics gebc-1.07 lib/ballistics/ballistics.cpp, and as slow as one might expect from a pure-perl port of an arithmetic-intensive algorithm.

On my system it takes about an eighth of a second to simulate a 1200-yard flight. This may be supplemented at some point with an Inline::C equivalent.

Note that most manufacturers report G1 ballistic coefficients. Using the wrong drag function for a given ballistic coefficient will produce ludicrously incorrect results.

To ascertain the correct bore elevation to hit a target at a specific distance, change the shot_angle_deg parameter on successive calls to flight_simulator(), and converge on drop_inches == 0.0 at the given range via binary search. I should get around to providing a function for that at some point (GNU-Ballistics has such a function, I just didn't port it).

    parameter: (str) drag_function is exactly one of: 'G1', 'G2', 'G5', 'G6', 'G7', 'G8'.

    parameter: (float) ballistic_coefficient, qv: http://en.wikipedia.org/wiki/Ballistic_coefficient

    parameter: (float) muzzle_velocity_fps is the velocity of the projectile at time=0 (feet per second)

    parameter: (float) sight_height_inches is the distance from the center of the sight to the center of the bore (inches)

    parameter: (float) shot_angle_deg is the bore elevation (degrees, 0 = horizontal, 90 = vertical)

    parameter: (float) OPTIONAL: bore_to_sight_angle_deg is the difference in angle between the bore elevation and the sight elevation. Set to undef or -1 to have flight_simulator() calculate it for you from the zero_range_yards parameter (degrees)

    parameter: (float) wind_speed_fps is the velocity of the wind (feet per second)

    parameter: (float) wind_angle_deg is the direction the wind is blowing (degrees, 0 = shooting directly into wind, 90 = wind is blowing from the right, perpendicular to flight path, -90 = wind is blowing from the left, perpendicular to flight path)

    parameter: (float) OPTIONAL: max_range_yards is the maximum range to which the flight will be simulated (yards, default is 2000)

    returns: a reference to an array of hash references, one per yard, denoting the projectile's disposition when it reaches that range. All data fields are floating-point numbers:

        range_yards     How far downrange the projectile has travelled, in yards.
        drop_inches     How far below the horizontal plane intersecting the muzzle the projectile has travelled, in inches.
        correction_moa  The angle from the muzzle to the projectile in the vertical plane, relative to the path from the muzzle to the target, in minutes.
        time_seconds    How much time has elapsed since leaving the muzzle, in seconds.
        windage_inches  How far in the horizontal plane the projectile has moved due to wind, in inches.
        windage_moa     The angle from the muzzle to the projectile in the horzontal plane, relative to the path from the muzzle to the target, in minutes.
        vel_fps         The velocity of the projectile, in feet per second.
        vel_horiz_fps   The horizontal component of the velocity of the projectile, in feet per second.
        vel_vert_fps    The vertical component of the velocity of the projectile, in feet per second.

g1_drag (velocity_fps)

The canonical function for computing instantaneous velocity drop at a given velocity, per the G1 drag model.

    parameter: (float) velocity_fps is the velocity of the projectile (in feet per second)

    returns: (float) the deceleration of the projectile from drag (in feet per second per second)

muzzle_energy (mass_grains, velocity_fps, [want_joules_bool])

A convenience function for computing kinetic energy from mass and velocity. Despite its name, it is useful for computing the kinetic energy of a projectile at any point during its flight.

    parameter: (float) mass_grains is the mass of the projectile (in grains)

    parameter: (float) velocity_fps is the velocity of the projectile (in feet per second)

    parameter: (boolean) OPTIONAL: set want_joules_bool to a True value to get Joules instead of foot-pounds (boolean, default=False)

    returns: (float) the kinetic energy of the projectile (in foot-pounds or Joules)

muzzle_velocity_from_energy (mass_grains, energy_ftlbs)

A convenience function for computing velocity from mass and kinetic energy. Despite its name, it is useful for computing the velocity of a projectile at any point during its flight.

If all you have is Joules, divide by 1.3558179 to get foot-pounds.

    parameter: (float) mass_grains is the mass of the projectile (in grains)

    parameter: (float) energy_ftlbs is the kinetic energy of the projectile (in foot-pounds)

    returns: (float) the velocity of the projectile (in feet per second)

TODO

Contact Geoffrey Kolbe (Inventor at Border Barrels Limited) and ask for permission to publish his splendid implementations:

 * Bullet drag calculator - http://www.border-barrels.com/cgi-bin/drag_working.cgi

 * Barrel weight calculator - http://www.border-barrels.com/cgi-bin/swamped_barrel_weight.cgi

His drag calculator seems better than my own ebc function.