Skip to main content

Numerical launch-angle solver for moving targets under gravity and quadratic drag.

Project description

Official repository notice

This is the only official repository for ballistic-solver.

Official repository: https://github.com/ujinf74/ballistic-solver

Do not download ZIP files, binaries, or installers from third-party copies, mirrors, or reuploads. Use only the Releases page of this repository.

banner

CI Release Native + PyPI PyPI License

ballistic-solver is a native C/C++ numerical solver that computes launch angles to intercept moving targets under gravity and quadratic air drag, with optional wind.

Unlike vacuum / closed-form solvers, this project simulates the projectile and solves the intercept numerically, aiming for robust real-time use even when trajectories are strongly curved.


Quick start

Python (PyPI)

pip install ballistic-solver

Requires Python >= 3.10.

import ballistic_solver as bs

result = bs.solve(
    relPos0=(120, 30, 5),
    relVel=(2, -1, 0),
    v0=90,
    kDrag=0.002,
)

print(result["theta"], result["phi"], result["miss"])
print(result["success"], result["status"], result["message"])

For tighter convergence without manually tuning every knob:

params = bs.params_preset("precise")
result = bs.solve((120, 30, 5), (2, -1, 0), 90, 0.002, params=params)

For repeated solves, Python also provides a thin convenience wrapper:

solver = bs.Solver.preset("precise")
result = solver.solve((120, 30, 5), (2, -1, 0), 90, 0.002)

Demo (Unity)

Highly curved trajectories under strong air drag, still converging to a hit against moving targets.

https://github.com/user-attachments/assets/c0c69cdd-0dd4-4606-9c7d-f21dd002d7f7


Why this solver

Many launch-angle solvers depend on vacuum assumptions or partially linearized models. This project instead simulates the projectile and solves the intercept numerically, targeting robustness in real-time simulations and integration scenarios.


Key properties

  • Moving targets supported
  • Constant-acceleration targets supported via the extended API
  • Strong air resistance (quadratic drag) supported
  • Low / High arc selection (since v0.2)
  • Wind vector supported (since v0.3)
  • Extended C ABI utilities (since v0.4)
  • Fast / balanced / precise solver presets
  • Physical drag helper: kDrag = 0.5 * rho * Cd * area / mass
  • Robust in strongly nonlinear regimes (no analytic assumptions)
  • Best-effort result returned even without perfect convergence
  • Explicit success / failure reporting (+ diagnostic message)
  • Stable C ABI for multi-language use
  • Header-only C++ core
  • Easy install via PyPI: pip install ballistic-solver

Python API

solve(...)

solve(relPos0, relVel, v0, kDrag, arcMode=0, params=None) -> dict
  • relPos0: target relative position at t=0 (x,y,z)
  • relVel: target relative velocity (x,y,z)
  • v0: muzzle speed (scalar)
  • kDrag: quadratic drag coefficient
  • arcMode: 0/1 or "low"/"high" (case-insensitive)
  • params: optional BallisticParams for advanced tuning (gravity, wind, integrator and solver knobs)

Returned dict keys include:

  • success (bool)
  • theta, phi (radians)
  • miss (closest-approach distance)
  • tStar (time of closest approach)
  • relMissAtStar (3-vector miss at tStar)
  • status (SolveStatus integer)
  • message (short diagnostic string)
  • plus convergence diagnostics (iterations, acceptedSteps, lastLambda, lastAlpha)

Utilities

params = bs.params_preset("fast")  # or "balanced", "precise"
kDrag = bs.k_drag_from_physical(
    airDensity=1.225,
    dragCoefficient=0.30,
    area=0.00426,
    mass=0.145,
)

For constant-acceleration targets:

result = bs.solve_accel(
    relPos0=(120, 30, 5),
    relVel=(2, -1, 0),
    relAcc=(0, 0.2, 0),
    v0=90,
    kDrag=0.002,
    params=bs.params_preset("precise"),
)

Solver validity note

The solver internally integrates projectile motion using:

  • 4th-order Runge–Kutta (RK4)
  • Fixed timestep dt
  • Quadratic drag
  • Wind as air velocity

To match in-game ballistics, your runtime simulation must use the same physical model and integrator configuration.

If your game uses a different integrator (e.g., Euler) or a different timestep, the computed launch angles may not hit even if the solver reports success.


C ABI (stable interface)

Primary intercept API:

void ballistic_inputs_init(BallisticInputs* in);
int32_t ballistic_solve(const BallisticInputs* in, BallisticOutputs* out);

Since v0.4.0, additional utility functions are available:

void ballistic_rk4_step(...);

int32_t ballistic_simulate_trajectory(...);
int32_t ballistic_simulate_trajectory_from_angles(...);

int32_t ballistic_find_closest_approach(...);

int32_t ballistic_vacuum_arc_angles_to_point(...);
void ballistic_initial_guess_vacuum_lead(...);

Additional extended APIs include:

void ballistic_accel_inputs_init(BallisticAccelInputs* in);
int32_t ballistic_solve_accel(const BallisticAccelInputs* in, BallisticOutputs* out);
int32_t ballistic_inputs_apply_preset(BallisticInputs* in, int32_t preset);
int32_t ballistic_k_drag_from_physical(...);
int32_t ballistic_make_relative_motion(...);

See ballistic_solver_c_api.h for full signatures and parameter definitions.

This enables usage from:

  • C / C++
  • Python (ctypes via the C ABI)
  • C# / .NET / Unity (P/Invoke)
  • Others via FFI

Prebuilt native binaries are provided via GitHub Releases.


Arc mode (since v0.2)

C ABI convention:

  • arcMode = 0 → Low
  • arcMode = 1 → High

High arc example:

https://github.com/user-attachments/assets/4334ed87-597e-4ad4-b21e-c1a1a17e8cd8


Wind (since v0.3)

C ABI convention:

  • wind[3] = air velocity vector (same frame as relPos0/relVel)
  • Drag uses relative airspeed: v_rel = v_projectile - wind

Wind demo:

https://github.com/user-attachments/assets/1cd998cf-34db-4a74-8817-c6393227ef4e


Using prebuilt binaries (C ABI)

Download the archive for your platform from Releases.

Each release contains:

  • Shared library

    • Windows: ballistic_solver.dll
    • Linux: libballistic_solver.so
    • macOS: libballistic_solver.dylib
  • C ABI header: ballistic_solver_c_api.h


C# / Unity usage

A C# P/Invoke example is available in:

examples/dotnet/

On Windows, place ballistic_solver.dll next to the executable (or ensure it is discoverable via PATH), then call ballistic_solve via DllImport.

This works directly inside Unity.


How it works (high level)

  1. Simulate projectile motion using RK4 integration with drag (+ wind)
  2. Track the closest approach between projectile and target
  3. Express the miss at closest approach as an angular residual
  4. Solve the nonlinear system using damped least squares (Levenberg–Marquardt)
  5. Accelerate Jacobian updates with Broyden-style refinement
  6. Return the best solution found

Failure cases are explicitly detected and reported.


Status codes (SolveStatus)

BallisticOutputs.status / Python result["status"] corresponds to:

  • 0 = Ok
  • 1 = InvalidInput
  • 2 = InitialResidualFailed
  • 3 = JacobianFailed
  • 4 = LMStepSingular
  • 5 = ResidualFailedDuringSearch
  • 6 = LineSearchRejected
  • 7 = LambdaTriesExhausted
  • 8 = MaxIterReached

message contains a short diagnostic string.


Build from source

cmake -S . -B build
cmake --build build -j
ctest --test-dir build

The shared library target is ballistic_solver.

Regression and benchmark

Python regression and local benchmark scripts are available:

python -c "import importlib.util; s=importlib.util.spec_from_file_location('rr','tests/random_regression.py'); m=importlib.util.module_from_spec(s); s.loader.exec_module(m); m.test_random_linear_cases(); m.test_acceleration_api_smoke()"
python benchmarks/linear_cases.py

On a local Windows release build, 500 generated linear-target cases produced:

fast:     median 0.107 ms, p95 0.233 ms, p95 miss 3.399e-02 m
balanced: median 0.219 ms, p95 0.492 ms, p95 miss 7.287e-03 m
precise:  median 0.265 ms, p95 0.583 ms, p95 miss 7.655e-06 m

ABI notes

  • Plain C layout across the ABI boundary
  • Fixed-size arrays only
  • No dynamic allocation across the boundary

License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ballistic_solver-0.5.0.tar.gz (31.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ballistic_solver-0.5.0-cp312-cp312-win_amd64.whl (123.9 kB view details)

Uploaded CPython 3.12Windows x86-64

ballistic_solver-0.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (149.2 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

ballistic_solver-0.5.0-cp312-cp312-macosx_10_13_universal2.whl (237.0 kB view details)

Uploaded CPython 3.12macOS 10.13+ universal2 (ARM64, x86-64)

ballistic_solver-0.5.0-cp311-cp311-win_amd64.whl (122.7 kB view details)

Uploaded CPython 3.11Windows x86-64

ballistic_solver-0.5.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (147.6 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

ballistic_solver-0.5.0-cp311-cp311-macosx_10_9_universal2.whl (236.6 kB view details)

Uploaded CPython 3.11macOS 10.9+ universal2 (ARM64, x86-64)

ballistic_solver-0.5.0-cp310-cp310-win_amd64.whl (121.9 kB view details)

Uploaded CPython 3.10Windows x86-64

ballistic_solver-0.5.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (146.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

ballistic_solver-0.5.0-cp310-cp310-macosx_10_9_universal2.whl (234.5 kB view details)

Uploaded CPython 3.10macOS 10.9+ universal2 (ARM64, x86-64)

File details

Details for the file ballistic_solver-0.5.0.tar.gz.

File metadata

  • Download URL: ballistic_solver-0.5.0.tar.gz
  • Upload date:
  • Size: 31.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ballistic_solver-0.5.0.tar.gz
Algorithm Hash digest
SHA256 8788d530d9405a3afd3cd96e1b5029b221a4f99f4128dc656cd5be5b096a47d2
MD5 f66ad2af4f5e3d7aadcd044819263619
BLAKE2b-256 b80f1adc73075a4b32ffb418013d480899cb650bf43e3bd4795577492a1ce13b

See more details on using hashes here.

Provenance

The following attestation bundles were made for ballistic_solver-0.5.0.tar.gz:

Publisher: release.yml on ujinf74/ballistic-solver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ballistic_solver-0.5.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for ballistic_solver-0.5.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 d72584dd3d6d4183e55b0d71563da7b0892808c7006bdd4f69c04014ed9b99e6
MD5 29d0fe3d894e5b886d7ed170009a0b89
BLAKE2b-256 6fdc2572816e3d3f2c3b625fc097294110275a03d95cf9b445f19fe7a4470624

See more details on using hashes here.

Provenance

The following attestation bundles were made for ballistic_solver-0.5.0-cp312-cp312-win_amd64.whl:

Publisher: release.yml on ujinf74/ballistic-solver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ballistic_solver-0.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ballistic_solver-0.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7943f844fd472fe92a2950c32ec8f8b7595c1ca8bcbd2776f833b2123e33faa9
MD5 99b010fc6be3011e31db76c8cb3fe044
BLAKE2b-256 7c6ae551c7b23086e03093c285f0e97070c80286ef337482a4b17cf9a8af9937

See more details on using hashes here.

Provenance

The following attestation bundles were made for ballistic_solver-0.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on ujinf74/ballistic-solver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ballistic_solver-0.5.0-cp312-cp312-macosx_10_13_universal2.whl.

File metadata

File hashes

Hashes for ballistic_solver-0.5.0-cp312-cp312-macosx_10_13_universal2.whl
Algorithm Hash digest
SHA256 2c31c506621062c874e3cc0b0363658d0117b320fa4b069cbd0bde0163efbe90
MD5 92738f69dbff64b99f18da1b9dcefd47
BLAKE2b-256 0a11719511f1fee9d6911a481e3b8ff205c852d6a3ab07436af75a6cba377809

See more details on using hashes here.

Provenance

The following attestation bundles were made for ballistic_solver-0.5.0-cp312-cp312-macosx_10_13_universal2.whl:

Publisher: release.yml on ujinf74/ballistic-solver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ballistic_solver-0.5.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for ballistic_solver-0.5.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 56c33b0546c361454dec05a0e4b95609209b4017cfa9d5bb093b999162b98106
MD5 9c0d8074ddc9fe43c3b4a4cd1b4a66f1
BLAKE2b-256 62b105b16652ad603f0c584e1bb940e72081702f394850eb2cfb85b1b044365d

See more details on using hashes here.

Provenance

The following attestation bundles were made for ballistic_solver-0.5.0-cp311-cp311-win_amd64.whl:

Publisher: release.yml on ujinf74/ballistic-solver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ballistic_solver-0.5.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ballistic_solver-0.5.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e10e5dcdc8ffdf5e2351daabde6b845b82fcf7c0eb7492fd0cea66f73cebbc67
MD5 3f22e0e48b2397ee3f1e2748ea786410
BLAKE2b-256 da3b24b8e1cb0fa6465225e14b2bffe2b268a63eee30a600a22c2188d96f2a54

See more details on using hashes here.

Provenance

The following attestation bundles were made for ballistic_solver-0.5.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on ujinf74/ballistic-solver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ballistic_solver-0.5.0-cp311-cp311-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for ballistic_solver-0.5.0-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 32374c668836aaa2c08e33811d46714cd95348c48928feab15b45156f7a2c066
MD5 1d9051059ee531c54d68e8e1beea774f
BLAKE2b-256 baf8b8d0245db1afdf9da23cd540db8d8fe3d3567afe005c6fc0fd6d56609b10

See more details on using hashes here.

Provenance

The following attestation bundles were made for ballistic_solver-0.5.0-cp311-cp311-macosx_10_9_universal2.whl:

Publisher: release.yml on ujinf74/ballistic-solver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ballistic_solver-0.5.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for ballistic_solver-0.5.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 8c9610e81bf5f1bf182b4b8a7088fd273a66bf3ed6cafa652cd54ea654c89595
MD5 fbe21c42d77b2c9c971ef83cb87591f5
BLAKE2b-256 1fd9dfeaa9728d2e7bebad20246a1f0469beb504ccd6d2c861c552bcdbdda074

See more details on using hashes here.

Provenance

The following attestation bundles were made for ballistic_solver-0.5.0-cp310-cp310-win_amd64.whl:

Publisher: release.yml on ujinf74/ballistic-solver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ballistic_solver-0.5.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ballistic_solver-0.5.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 22115b10e439bc1bb31b80a48e185008cf201d8a372f83b5be48292cf5fd833e
MD5 7252970d1374e8b1617d7083395f80ec
BLAKE2b-256 5881d6e159be6665b8c8ce0b45c739ec9030c931ce8d66c733b67025b5026d02

See more details on using hashes here.

Provenance

The following attestation bundles were made for ballistic_solver-0.5.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on ujinf74/ballistic-solver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ballistic_solver-0.5.0-cp310-cp310-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for ballistic_solver-0.5.0-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 6e3312ae696b4d7c5883a1cb908c321f447a56f43c36b6aac79490cae9fccabf
MD5 e60ec80c2d28ee4a70089c8903a517b3
BLAKE2b-256 209409e909c3cf681e87b47bfb2790dfb5cc335c62e274ae4ffb1d8e86e56060

See more details on using hashes here.

Provenance

The following attestation bundles were made for ballistic_solver-0.5.0-cp310-cp310-macosx_10_9_universal2.whl:

Publisher: release.yml on ujinf74/ballistic-solver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page