Docs  /  A Point-Mass External-Ballistics Firing-Solution Engine for Long-Range Target Shooting

A Point-Mass External-Ballistics Firing-Solution Engine for Long-Range Target Shooting

Tyler Crockett — Macdaddy4sure.ai AugmentedIntelligence v11.0 · Ballistics Subsystem (ShootingCore, ShootingELRCore)


Abstract

We describe the external-ballistics firing-solution engine implemented in the _AugmentedIntelligence runtime for the long-range target-shooting disciplines (F-Class, PRS, benchrest, and extreme-long-range steel). The engine integrates a point-mass trajectory under a tabulated G1/G7 drag law and a standard-atmosphere density model to produce elevation and windage corrections, time of flight, and retained velocity and energy. For extreme ranges it augments the point-mass core with the deterministic secondary effects that dominate beyond ~1000 yd — gyroscopic (spin) drift, Coriolis and Eötvös deflection, aerodynamic jump, and atmospheric density altitude — and provides a Monte-Carlo uncertainty model that reports a probability of hit and an input-sensitivity (error) budget. We give the governing equations, the numerical method, validation against a reference load, and an explicit statement of the model's limitations. This is a marksmanship training and planning aid; all computed dope must be verified against live fire.


1. Introduction and scope

A firing solution is the set of sight corrections a shooter dials (or holds) to place a projectile on a target at a known distance under known conditions. For the target-shooting sports the relevant outputs are the elevation come-up and wind hold, expressed in the shooter's scope units (milliradians or minutes of arc), together with supporting quantities — bullet drop, wind drift, time of flight, and retained velocity and energy.

The physics is a classical initial-value problem: projectile motion under gravity and aerodynamic drag. It is deterministic and well understood; the engineering difficulty lies in (i) an accurate drag description, (ii) the secondary effects that become first-order at long range, and (iii) the uncertainty in the inputs, which at extreme range dominates the achievable precision. This paper documents how the engine addresses each.

The engine deliberately targets known-distance, static-target shooting. It is a calculator, not a fire-control system.


2. Coordinate system and problem statement

We integrate in the vertical plane containing the line of sight (LOS) — the axis from the shooter's eye through the scope to the aim point — with a lateral axis for wind and spin effects. Let:

  • s — distance traveled along the LOS (down-range),
  • h — height of the projectile relative to the LOS (positive up),
  • z — lateral offset (positive right).

The sight sits a distance H (sight height) above the bore, so the projectile begins at h = −H. The bore is elevated above the LOS by a small launch angle φ (determined by the zero, §7). The reported drop is h at the target range; the come-up is the angle that must be added to the LOS to place the bore such that h = 0 at that range.


3. Governing equations

3.1 Drag deceleration

For a point-mass projectile the aerodynamic drag produces a deceleration anti-parallel to the velocity vector v relative to the air:

a_drag = ρ · C_D(M) · |v|² / (2 · B)          [m/s²]

where ρ is air density, C_D(M) is the drag coefficient of the standard reference projectile at Mach number M = |v|/c, and B is the ballistic coefficient expressed as an SI areal density (kg/m²). This form folds the projectile's mass, diameter, and form factor into B, which is the shooter-known quantity. The equivalence follows from the standard definition B = m / (i · d²) and C_D,bullet = i · C_D,std, giving a_drag = (π/8)·ρ·|v|²·C_D,std / B; absorbing the geometric constant into the tabulated C_D and the unit conversion yields the expression above.

BC units. Shooters quote the G1 (or G7) BC in imperial lb/in². We convert once at input:

B[kg/m²] = BC_imperial · 703.06957

3.2 Equations of motion

Decompose the velocity into along-LOS (v_s), perpendicular (v_h), and lateral (v_z) components. With a crosswind w (positive from the left, §8), the air-relative lateral velocity is v_rz = v_z − w, and |v| = √(v_s² + v_h² + v_rz²). The accelerations are:

a_s =  −a_drag · (v_s  / |v|)
a_h =  −a_drag · (v_h  / |v|)  −  g·cos(α)
a_z =  −a_drag · (v_rz / |v|)

where g = 9.80665 m/s² and α is the look (incline) angle; the factor cos(α) is the component of gravity perpendicular to the LOS (the "rifleman's" correction for uphill/downhill shots). Wind enters through v_rz, so lateral drift emerges naturally from the integration rather than a closed-form add-on.

3.3 Auxiliary quantities

Speed of sound (m/s) from air temperature T_F (°F), with T_C in Celsius:

c = 331.3 · √(1 + T_C/273.15)

Muzzle/retained energy (ft·lb) from bullet weight w_gr (grains) and velocity v_fps:

E = w_gr · v_fps² / 450240

Angular conversions (small-angle sight corrections): 1 rad = 3437.75 MOA = 1000 mil. The come-up and wind hold are atan2(|drop|, R) and atan2(drift, R) scaled to the shooter's units, where R is the slant range.


4. Drag models

The engine ships two standard drag functions, tabulated as C_D versus Mach and linearly interpolated:

  • G1 — the classic flat-base reference projectile. Appropriate for conventional bullets; the drag rises sharply through the transonic region and peaks near Mach 1.3.
  • G7 — a boat-tail, secant-ogive reference projectile. A markedly better match for modern long, sleek match bullets, with correspondingly lower and flatter C_D.

The choice of model must match the BC the shooter supplies (a bullet's G7 BC is numerically ~half its G1 BC). Selecting the correct reference is the single largest fidelity lever short of a radar-measured custom drag curve.


5. Standard atmosphere

Air density is expressed as a ratio to the G1 standard metro condition (59 °F, 29.92 inHg, sea level), because the tabulated C_D is referenced to that standard:

ρ/ρ₀ = (P / 29.92) · (518.67 / (T_F + 459.67))

with pressure P in inHg. When only altitude is known, ICAO pressure altitude supplies P. For field use we also report density altitude (DA), the single number that captures the combined temperature/pressure/altitude effect on drag:

PA   = (29.92 − P) · 1000                    [ft, pressure altitude]
DA   = PA + 118.8 · (T_F − (59 − 3.57·PA/1000))

Humidity is a small second-order effect and is neglected.


6. Numerical integration

The trajectory is advanced with a fixed-step semi-implicit (symplectic) Euler scheme at Δt = 2×10⁻⁴ s. Velocities are updated from the accelerations, then positions from the new velocities; this is stable and conserves the qualitative structure of the motion far better than explicit Euler at the same step. At each step the drag magnitude is re-evaluated at the current Mach number. When the along-LOS coordinate first exceeds the target range, the solution (drop, drift, time of flight, velocity) is linearly interpolated to the exact range so that outputs are not quantized by the step size. Time of flight at extreme range is 5–10 s, so the small step is necessary to keep integrated error negligible.


7. Zeroing

A rifle is zeroed at a chosen range R₀ (commonly 100 yd): the shooter adjusts the sight so the trajectory crosses the LOS at R₀. The engine solves for the bore launch angle φ such that h(R₀) = 0 by bisection, exploiting the monotonic dependence of h(R₀) on φ. All subsequent solutions integrate at the fixed φ; the reported come-up at range R > R₀ is the additional elevation needed beyond the zero.


8. Wind model

Wind is entered as a speed and a clock direction (the o'clock position the wind blows from; 3 o'clock is a pure right-to-left crosswind). The crosswind component driving lateral drift is

w = −W · sin(θ_clock),     θ_clock = (clock/12)·2π

so a 9-o'clock wind (from the left) pushes the bullet right, a 3-o'clock wind pushes left, and 12/6-o'clock (head/tail) winds produce no lateral drift. Because w enters the air-relative velocity, drift accumulates through the full flight rather than via a lag-time approximation.


9. Extreme-long-range corrections

Beyond ~1000 yd several effects that are negligible at short range become first-order (feet, not inches). These are deterministic given their inputs and are therefore computed, not learned or guessed. They are added to the point-mass solution.

9.1 Gyroscopic stability (Miller)

The Miller formula estimates the gyroscopic stability factor S_g from bullet mass m (gr), diameter d (in), length in calibers l = L/d, and twist in calibers t = T/d, corrected for velocity and atmosphere:

S_g = [ 30·m / (t²·d³·l·(1+l²)) ] · (v/2800)^(1/3) · (T_R/518.67) · (29.92/P)

S_g < 1.4 flags marginal stability — a warning that the bullet may destabilize as it decelerates through the transonic region.

9.2 Spin drift (Litz approximation)

A gyroscopically stabilized bullet precesses, drifting laterally in the direction of barrel twist. We use Litz's empirical form (inches; positive right for right-hand twist):

SD = 1.25 · (S_g + 1.2) · TOF^1.83

9.3 Coriolis and Eötvös deflection

Earth's rotation deflects the long-flight-time projectile. With rotation rate Ω = 7.2921×10⁻⁵ rad/s, latitude L, azimuth of fire A (0 = north, 90 = east), range R, and time of flight T:

Horizontal (right in N. hemisphere):  Δz = Ω · R · T · sin(L)
Vertical (Eötvös; high shooting east): Δh = Ω · R · T · cos(L) · sin(A)

The horizontal term is azimuth-independent; the vertical term makes east-bound shots print high and west-bound shots low.

9.4 Aerodynamic jump

A crosswind imparts a small vertical deflection at launch (angular, roughly constant with range), modeled as ≈ 0.01 · S_g · W_cross (mil). It is small but non-negligible at ELR and, unlike wind drift, acts vertically.

9.5 Powder-temperature velocity shift

Muzzle velocity varies with propellant temperature. Given a per-load sensitivity k (fps/°F) and a reference (v₀, T₀), the corrected velocity is v = v₀ + k·(T − T₀). At extreme range a 10 fps error is a foot or more of vertical impact shift, so this correction is material.


10. Uncertainty quantification

At long range the precision of a firing solution is limited less by model fidelity than by the uncertainty of its inputs — principally wind, then muzzle velocity, then range. The engine therefore provides a Monte-Carlo dispersion model. The mean shot is zeroed once; then N samples perturb the uncertain inputs (muzzle velocity σ_v, wind σ_w, range σ_R, BC σ_BC) by independent Gaussians and re-integrate at the fixed launch angle. The engine reports:

  • Probability of hit (P_h) — the fraction of samples landing inside the target box;
  • the dispersion (standard deviation of vertical and horizontal miss);
  • an input-sensitivity budget — impact shift per 10 fps of MV, per mph of wind, and per yard of range error, computed by finite difference.

This reframes the extreme-range problem honestly: the output is not a single number to dial but a cone, and the sensitivity budget shows which input dominates it (almost always wind).


11. Truing

A generic solution is made rifle-specific by truing to observed impacts. Given a measured drop at a known range, the engine solves (by bisection on velocity) for the muzzle velocity that reproduces it — the first and most effective rung of personalization. A learned residual model (a small neural network trained on a shot log, confined to the observed envelope) is the natural next step for the subsonic-drag error a single BC cannot capture; it is intentionally physics-anchored so it corrects only what theory misses and never extrapolates.


12. Solution method: the _AugmentedIntelligence firing-solution pipeline

The preceding sections define the individual physical models; this section describes how the engine composes them into a single firing solution, and the design philosophy behind that composition. A solve is layered by order of trust: a deterministic physics backbone first, then an honest uncertainty estimate, then optional data-driven personalization — never the reverse.

Step 1 — Assemble the inputs. A solve takes a Shot (muzzle velocity, BC and its drag model, bullet weight, sight height, zero range, temperature, pressure, wind speed and clock, look angle) and, for long range, a Rifle (diameter, length, twist rate and hand, shooter latitude and firing azimuth, and the scope's click value). These are the only quantities the shooter must supply.

Step 2 — Establish the atmosphere. From temperature and pressure the engine computes the air-density ratio (§5) and the speed of sound (§3.3). The density ratio scales the drag force; the speed of sound converts every velocity to a Mach number so the correct point on the drag curve is used. This is done once and held for the trajectory.

Step 3 — Zero the rifle (solveZeroAngle). Before any range solution the engine finds the bore launch angle φ that puts the trajectory on the line of sight at the zero range, by bisection (§7). This encodes the rifle's actual sight-in and is the reference against which all come-ups are reported.

Step 4 — Integrate the trajectory (integrate). Launching at φ, the engine steps the point-mass equations of motion (§3.2) with the semi-implicit Euler scheme (§6). At every step it re-evaluates the Mach number, looks up C_D from the selected G1 or G7 table, and applies the drag, gravity-perpendicular, and wind accelerations. When the down-range coordinate first passes the target range it interpolates drop, drift, time of flight, and velocity to the exact distance. This single routine yields the elevation, windage, TOF, and retained velocity/energy — the core of the solution.

Step 5 — Convert to sight units. Drop and drift are converted from linear offset to the shooter's angular units — milliradians or MOA — via atan2, and then to turret clicks using the scope's click value. This is what the shooter actually dials.

Step 6 — Apply the deterministic long-range corrections (solveFull). For extreme range the engine adds the effects of §9 that are computable from the inputs: it evaluates the Miller stability factor S_g, then adds Litz spin drift, Coriolis (horizontal) and Eötvös (vertical) deflection, and aerodynamic jump, and folds them into the total elevation and windage. It raises a transonic/stability flag when S_g is marginal or the bullet has slowed below Mach 1.2. Crucially, these are added analytically to the point-mass result rather than learned or guessed — the engine computes everything theory can determine.

Step 7 — Quantify the uncertainty (monteCarlo). Recognizing that at long range the limiting factor is input uncertainty, not model form, the engine zeroes once and then re-integrates the trajectory hundreds of times with the muzzle velocity, wind, range, and BC perturbed by their standard deviations. It returns a probability of hit for the target, the dispersion ellipse, and a sensitivity budget. The firing "solution" is thus delivered honestly as a center plus a cone, with the sensitivity budget naming the dominant error (typically wind).

Step 8 — Personalize by truing (trueVelocity). Finally, the generic solution is made rifle-specific: from an observed drop at a known range the engine solves for the muzzle velocity that reproduces it, shifting the whole trajectory to match the shooter's actual dope. A physics-anchored learned residual (§11) is the optional next layer for the subsonic-drag error a single BC cannot express.

Design principle. The pipeline embodies one rule: compute what is knowable, learn only the irreducible residual, and never present a point estimate where a distribution is honest. Steps 1–6 are pure, deterministic physics; step 7 makes the residual uncertainty explicit; step 8 closes the loop with the shooter's own data. Deterministic effects (Coriolis, spin drift, stability) are never delegated to a model — they are derived — so any learned component is confined to the small, genuinely uncertain part of the problem and is barred from extrapolating outside the data that trained it. This is what makes the solution both physically faithful and trustworthy at the ranges where naïve models quietly fail.

13. Validation

The engine is exercised by an automated behavioural test suite (suite_shooting.cpp, suite_shootingelr.cpp) covering unit conversions, the atmosphere model, drag tables, monotonicity properties, and a reference load. For a .308 Winchester, 175 gr SMK, G1 BC 0.505, 2600 fps, 1.9 in sight height, 100 yd zero, standard conditions, the engine produces:

Range (yd) Come-up (mil) Retained V (fps) TOF (s) Spin drift (in) Coriolis H (in)
100 0.00 2456
1000 10.05 1349 1.61 10.7 3.0

with S_g = 2.40 (stable) and, under a Monte-Carlo model (σ_v = 10 fps, σ_w = 2 mph, σ_R = 3 yd), a horizontal dispersion (15.7 in) that substantially exceeds the vertical (5.1 in) — correctly reproducing the field truth that wind is the dominant error source. Velocity truing recovers a synthetic reference muzzle velocity to within the test tolerance.

The come-up and retained velocity are in the expected range for this load; the model is slightly optimistic at extreme range (§14).


14. Limitations

  1. Single flat BC. The point-mass core uses one BC per drag model. Real BC degrades below Mach ~1.2, so the model under-predicts drag transonically and is optimistic at extreme range. G7 selection and, ideally, a banded or radar-measured custom drag curve reduce this.
  2. Point-mass, not 6-DOF. Spin drift and aerodynamic jump are empirical approximations, not a full rigid-body (epicyclic) solution. Yaw-of-repose and dynamic-stability transitions are not modeled.
  3. Single-layer atmosphere and wind. One density and one wind value are used; at ELR both vary appreciably over the trajectory's tens-of-feet apex.
  4. Transonic dispersion is physical, not modeled. As a bullet decelerates through Mach 1 it may lose dynamic stability and disperse unpredictably; no solver overcomes an unstable load.
  5. Estimates, not guarantees. All outputs are planning estimates. Verified live-fire dope always supersedes the model.

15. Implementation notes

The physics is implemented as dependency-free, header-only C++ cores (ShootingCore.hpp, ShootingELRCore.hpp) that are unit-tested in isolation, with a thin typed-command layer (shoot …) and Lua bindings for the host runtime. A companion MySQL schema (sql/shooting_schema.sql) logs profiles, the dope diary, computed solutions, chronograph strings, groups, and truing history — the dataset that feeds the truing and residual-learning workflow.


References

  1. R. L. McCoy, Modern Exterior Ballistics: The Launch and Flight Dynamics of Symmetric Projectiles, 2nd ed., Schiffer, 2012.
  2. B. Litz, Applied Ballistics for Long Range Shooting, 3rd ed., Applied Ballistics LLC, 2015.
  3. D. Miller, "A New Rule for Estimating Rifling Twist," Precision Shooting, March 2005 (gyroscopic stability formula).
  4. A. J. Pejsa, Modern Practical Ballistics, 2nd ed., 1991.
  5. Ballistics standard reference drag functions (G1, G7), derived from the Gâvre/Ingalls and BRL/ARDC projectile drag measurements.
  6. E. Eötvös, on the latitude/azimuth dependence of apparent vertical acceleration for east–west motion (Eötvös effect).

Prepared as internal technical documentation for the _AugmentedIntelligence ballistics subsystem. For target-shooting sport and educational use.

Generated from the project markdown docs on 2026-07-24. This is a static, self-contained site.