Skip to main content
banner

CI Release Native + PyPI PyPI License

ballistic-solver computes the launch angles to hit moving targets under gravity, quadratic air drag, and optional wind — for games, simulation, robotics, and targeting.

Unlike vacuum / closed-form solvers, it simulates the projectile and solves the intercept numerically, so it stays accurate on strongly curved trajectories. Native C/C++ core with a stable C ABI and a modern C++ API (bs::solve), plus Python (pip install ballistic-solver), C#/Unity, and Godot bindings.

https://github.com/user-attachments/assets/7de04137-61d9-4cf0-be5e-9804d6a9c67b

Real-time 3D showcase — the built-in tracker leading a noisy, diving target with range rings, tracer trails, and a live hit-rate HUD (examples/godot/).

Applications. The solver only sees relative kinematics, so the same code drops into many domains — most visibly games and simulation (turret lead-targeting, projectile interception; see the demo above), and equally robotics (interception / capture), tracking, and other aiming / targeting problems. An optional position-only tracker (bs.TargetTracker) adds lead-fire from a noisy track. See benchmarks/intercept_eval.py and examples/viz/ for cross-domain examples and accuracy comparisons.


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 either assume a vacuum (no drag) or linearize the dynamics. Each common approach trades away something:

Approach Moving target Drag Wind No per-shot tuning Real-time speed Robust
Vacuum / closed-form ○ ✗ ✗ ◎ ◎ ○
Brute-force angle grid ◎ ◎ ◎ ○ ✗ ◎
Generic optimizer (e.g. least-squares) ◎ ◎ ◎ △ △ ○
ballistic-solver ◎ ◎ ◎ ◎ ◎ ◎

◎ strong · ○ workable · △ limited · ✗ not supported

Vacuum solvers are the fastest but ignore drag and wind. Brute-force grids handle everything but are too slow for real-time use. Generic optimizers work on the same residual but need a good initial guess and per-problem tuning, and are more prone to local minima. ballistic-solver is purpose-built for the moving-target + drag + real-time corner: a closed-form vacuum warm start, an analytic Jacobian preconditioner, and a multistart fallback for the hard cases. See docs/numerical_method.md for the full method.


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)
  • Quartic vacuum-lead initialization for moving targets (since v0.6)
  • High-arc moving-target auxiliary multi-start fallback (since v0.6.1)
  • Coordinate-residual Gauss–Newton core with vacuum-seeded Jacobian (default since v1.0; ~15–25% faster, auxiliary-residual method kept as solve_aux)
  • 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
  • Modern C++ API (bs::solve / bs::solve_aux)
  • Easy install via PyPI: pip install ballistic-solver

Python API

solve(...)

solve(relPos0, relVel, v0, kDrag, arcMode=None, params=None, relAcc=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); None keeps the params value
  • params: optional BallisticParams for advanced tuning (gravity, wind, integrator and solver knobs)
  • relAcc: optional constant target relative acceleration (x,y,z); same as solve_accel

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)

solve uses the coordinate-residual core (Gauss–Newton on the 3D closest-approach miss, vacuum-seeded Jacobian, multistart fallback). It is the same signature as before and a drop-in replacement, typically ~15–25% faster at equal robustness.

solve_aux(...)

solve_aux(relPos0, relVel, v0, kDrag, arcMode=None, params=None, relAcc=None) -> dict

The previous default: the auxiliary-residual method (re-aim through the vacuum inverse, solved by damped least squares with a multistart fallback). Same return dict as solve. Kept for compatibility and for reproducing the auxiliary-residual results.

solve_predicted(...)

solve_predicted(predictor, v0, kDrag, arcMode=None, params=None) -> dict

Lead-fire against a position-only trajectory predictor instead of explicit relVel/relAcc. predictor(t) returns the predicted relative position (x, y, z) at time t >= 0 (e.g. from a Kalman/IMM track). Internally a local constant-acceleration model is fitted at the intercept time and iterated to a fixed point — exact for constant-velocity / constant-acceleration predictors and second-order accurate at the intercept for smoothly curving tracks. Returns the same dict as solve.

TargetTracker

tracker = bs.TargetTracker(processNoise=1.0, measNoise=0.25)
for t, pos in measurements:        # (timestamp, relative position)
    tracker.update(t, pos)
lead = tracker.predict(1.5)        # predicted relative position 1.5 s ahead
result = tracker.solve(v0=95.0, kDrag=0.0015)   # lead-fire via the predictor seam

A position-only constant-acceleration Kalman tracker (per-axis, white-noise-jerk model). It denoises the track and recovers velocity/acceleration without finite-difference noise, then feeds the predictor seam — so callers never supply relVel/relAcc. See benchmarks/predictor_eval.py for a lead-prediction accuracy comparison against a constant-velocity baseline.

The real-time 3D showcase at the top of this README is built on this tracker — the full project is in examples/godot/ (default scene demo/intercept_demo.tscn).

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: a = (0, 0, -g) - kDrag * |v - wind| * (v - wind)
  • 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);

Return value policy:

  • 0: API call completed and out was filled.
  • <0: API-level failure, such as null pointers or an internal exception.
  • Numerical solve success is reported separately by out->success and out->status.
  • ABI v3 adds convergence diagnostics to BallisticOutputs: iterations, acceptedSteps, lastLambda, and lastAlpha.
  • ABI v4 adds a preset field to BallisticInputs (0=Fast, 1=Balanced, 2=Precise). ballistic_inputs_apply_preset records it so that the full preset tuning (line-search, lambda tries, finite-difference step, golden-section) is carried into ballistic_solve, not only dt/tMax/tolMiss/maxIter.

Callers should check both:

int32_t rc = ballistic_solve(&in, &out);
if (rc != 0) {
    /* API call failed */
}
if (!out.success) {
    /* Solver ran but did not satisfy the requested tolerance. */
}

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)
  • Godot 4 (GDExtension addon-style example)
  • 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


Use as a CMake dependency (C/C++)

Pull the library straight into your CMake build with FetchContent:

include(FetchContent)
FetchContent_Declare(
    ballistic_solver
    GIT_REPOSITORY https://github.com/ujinf74/ballistic-solver.git
    GIT_TAG v1.0.0
)
set(BUILD_TESTING OFF)  # don't build the library's own tests in your tree
FetchContent_MakeAvailable(ballistic_solver)

target_link_libraries(your_app PRIVATE ballistic_solver)

C++

#include <ballistic_solver.hpp>

bs::Problem problem;
problem.rel_pos0 = {120, 30, 5};
problem.rel_vel  = {2, -1, 0};
problem.v0       = 90;
problem.k_drag   = 0.002;

bs::Options options;
options.preset = bs::Preset::Precise;

bs::Intercept r = bs::solve(problem, options);
if (r)                       // explicit operator bool() == success
    aim(r.theta, r.phi);     // elevation, azimuth in radians

With C++20 designated initializers the same call is more compact:

auto r = bs::solve({.rel_pos0 = {120, 30, 5},
                    .rel_vel  = {2, -1, 0},
                    .v0       = 90,
                    .k_drag   = 0.002},
                   {.preset = bs::Preset::Precise});

The bs:: API is source-level (build it with the same toolchain as the library; none of the internal headers leak into your code). For a stable ABI or FFI from other languages, use the C API instead.

C (stable ABI)

#include "ballistic_solver_c_api.h"

BallisticInputs in; BallisticOutputs out = {0};
ballistic_inputs_init(&in);
in.relPos0[0] = 120; in.relPos0[1] = 30; in.relPos0[2] = 5;
in.relVel[0]  = 2;   in.relVel[1]  = -1; in.relVel[2]  = 0;
in.v0 = 90; in.kDrag = 0.002;

if (ballistic_solve(&in, &out) == 0 && out.success)
    printf("theta=%.4f phi=%.4f miss=%.4f\n", out.theta, out.phi, out.miss);

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.


Godot

The GDExtension addon in examples/godot/ exposes the solver to GDScript:

var solver := BallisticSolver.new()
var r := solver.solve(rel_pos0, rel_vel, v0, k_drag, 0)  # arc_mode: 0 low, 1 high
if r.success:
    aim_at(r.theta, r.phi)  # elevation, azimuth in radians

A position-only BallisticTracker (Kalman) with the same solve(v0, k_drag, arc_mode) seam is also provided — it powers the real-time demo at the top of this README.


How it works (high level)

  1. Build a vacuum-lead initial guess from the moving-target quartic.
  2. Seed the inverse Jacobian analytically from the vacuum-arc map (no trajectory integration), as a cheap preconditioner.
  3. Simulate projectile motion using RK4 integration with drag (+ wind) and track the closest approach between projectile and target.
  4. Use the 3D closest-approach miss vector itself as the residual (it is well-conditioned), and solve the launch angles by Gauss-Newton on it.
  5. Refine the Jacobian with Broyden-style rank-1 updates; take full steps (no Levenberg–Marquardt damping, no line search).
  6. If the warm start does not reach tolerance, retry from a small arc-appropriate theta-grid multistart.
  7. Return the best solution found.

solve uses this coordinate-residual core. The earlier auxiliary-residual method (re-aim through the vacuum inverse, with damped least squares) remains available as solve_aux for compatibility and reproducibility.

Failure cases are explicitly detected and reported. See docs/numerical_method.md for a step-by-step description and docs/limitations.md for the modelling assumptions.


When solving can fail

The solver returns a best-effort result even when it cannot satisfy tolMiss. Common causes include:

  • invalid inputs (v0 <= 0, non-positive g, dt, tMax, or maxIter)
  • geometrically unreachable vacuum targets
  • targets that require an intercept beyond tMax
  • strong drag or high-arc cases where the selected arc branch cannot be maintained
  • iteration limits that are too tight for the requested tolerance

Use success, status, message, and miss together when deciding whether to accept a solution.


Limitations

ballistic-solver is a point-mass solver with a deliberately scoped physics model:

  • point mass — no spin drift / Magnus effect
  • quadratic drag with a single coefficient — no Mach-dependent drag table
  • constant gravity and uniform, constant wind
  • solves launch angles only (muzzle speed and arc branch are inputs)
  • no terrain / obstacle collision
  • best-effort (not guaranteed) on unreachable or near-limit targets
  • a numerical library for games, simulation, robotics, and research — not a certified fire-control system

See docs/limitations.md for the full list and the reasoning behind each.


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

The default coordinate-residual solve emits Ok, InvalidInput, JacobianFailed, or MaxIterReached. The Levenberg–Marquardt codes (4–7) are specific to the auxiliary-residual solve_aux path.

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

Distributed regression and benchmark scripts are available:

python tests/random_regression.py
python benchmarks/linear_cases.py

The CI workflow runs CTest smoke coverage plus the Python regression script. The regression script includes analytic vacuum checks, constructed moving-target vacuum cases, unreachable-target checks, randomized linear cases, and constant-acceleration API smoke coverage.

Benchmark numbers depend on CPU, OS, compiler, build type, Python version, and whether native or Python entrypoints are measured. The local reference below was measured on Windows NT 10.0.26200.0, AMD Ryzen 9 6900HS, Python 3.12.8, MSVC 14.44.35207, x64 Release build, through the Python native extension.

Reference preset result from the same local Release build:

fast:     500/500, median 0.031 ms, p95 0.131 ms, p95 miss 2.810e-02 m
balanced: 500/500, median 0.057 ms, p95 0.261 ms, p95 miss 7.053e-03 m
precise:  500/500, median 0.087 ms, p95 0.356 ms, p95 miss 5.596e-06 m

Current default solver (coordinate-residual core) results from 10,000 generated cases with seed 20260503. The last row is the high-arc moving-target stress case:

Case set Success Median runtime P95 runtime P95 miss
Low arc, moving target 10000/10000 (100.00%) 0.089 ms 0.266 ms 6.450e-03 m
High arc, stationary target 10000/10000 (100.00%) 0.408 ms 0.846 ms 8.018e-03 m
High arc, moving target 10000/10000 (100.00%) 0.607 ms 1.264 ms 8.341e-03 m

For a difficulty-bucketed breakdown (low / high arc × drag strength, with P99 and the hard-corner tail) and the full methodology, see docs/benchmarks.md.


ABI notes

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

Official repository

The only official repository is https://github.com/ujinf74/ballistic-solver. Install from PyPI (pip install ballistic-solver) or this repository's Releases page — not from third-party copies, mirrors, or reuploads.


License

MIT License

Metadata

Release files for ballistic-solver 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ballistic-solver 1.1.0
File Size Uploaded Provenance
ballistic_solver-1.1.0.tar.gz 81.9 kB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for ballistic-solver 1.1.0
File
ballistic_solver-1.1.0-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
ballistic_solver-1.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
ballistic_solver-1.1.0-cp312-cp312-macosx_10_13_universal2.whl CPython 3.12 CPython 3.12 macOS 10.13+ universal2 (ARM64, x86-64) Details
ballistic_solver-1.1.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
ballistic_solver-1.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
ballistic_solver-1.1.0-cp311-cp311-macosx_10_9_universal2.whl CPython 3.11 CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64) Details
ballistic_solver-1.1.0-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details
ballistic_solver-1.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
ballistic_solver-1.1.0-cp310-cp310-macosx_10_9_universal2.whl CPython 3.10 CPython 3.10 macOS 10.9+ universal2 (ARM64, x86-64) Details

Total release size: 2.0 MB

Release files / ballistic_solver-1.1.0.tar.gz

Download URL ballistic_solver-1.1.0.tar.gz
Size 81.9 kB
Tags Source
SHA-256 checksum
How to use checksums
fe9ec44a496a17854d47a1491123a4533118d049a25a247457f4cc14dbedeea8
BLAKE2b-256 checksum
How to use checksums
8d673ba9d8be338af5c3dc6eddb61fe1d8ed634776cac548f9d8543b7886beb7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / ballistic_solver-1.1.0-cp312-cp312-win_amd64.whl

Download URL ballistic_solver-1.1.0-cp312-cp312-win_amd64.whl
Size 169.2 kB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
393766132a7359c766f1744a51ad77d5d5479c9286823b712b38674df5a22736
BLAKE2b-256 checksum
How to use checksums
ae2d1ee556dbf98625796646637f80da08d689b16f1438b1cd03a266b1b8a265
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / ballistic_solver-1.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL ballistic_solver-1.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 188.5 kB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
4049394932f5e9db8be73b07527bafe2dccb3452c41204b41aa577db1813a543
BLAKE2b-256 checksum
How to use checksums
4ddbc9c9fd77a1bab14bc14930201e91d85e308ab5a1b83fbabc9edb53634b3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / ballistic_solver-1.1.0-cp312-cp312-macosx_10_13_universal2.whl

Download URL ballistic_solver-1.1.0-cp312-cp312-macosx_10_13_universal2.whl
Size 300.2 kB
Tags CPython 3.12 macOS 10.13+ universal2 (ARM64, x86-64)
SHA-256 checksum
How to use checksums
5dde6bf39777f4a758acbe0ba12f35fe7b77df6955c081b932ccea85ce79732d
BLAKE2b-256 checksum
How to use checksums
fd45eef04fb086609394475e59342be1e5a6ecb3191b5c86a24d7257bb688e84
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / ballistic_solver-1.1.0-cp311-cp311-win_amd64.whl

Download URL ballistic_solver-1.1.0-cp311-cp311-win_amd64.whl
Size 166.5 kB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
07800dee66aa226fed5a398c37d0dcb306e9df73f259706115b4a7e127b8b26a
BLAKE2b-256 checksum
How to use checksums
810383015d500b957a03c6543dfab519ece8de7c5527ffe2b5f2b60380f6ebe4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / ballistic_solver-1.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL ballistic_solver-1.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 185.8 kB
Tags CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
f4090fa2166a1c44a6c0bc9b013b58605a8d8acd5cec6a483e5c641ecd947c91
BLAKE2b-256 checksum
How to use checksums
b3737484c7d228093c8cb59b72538cd08d0d967ce3fce5ecb7b12cd23a93f697
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / ballistic_solver-1.1.0-cp311-cp311-macosx_10_9_universal2.whl

Download URL ballistic_solver-1.1.0-cp311-cp311-macosx_10_9_universal2.whl
Size 299.4 kB
Tags CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64)
SHA-256 checksum
How to use checksums
6bc772dba9668803fbad189c2d6ae402f0a92a493c147b0ccd712ad2c7f90a30
BLAKE2b-256 checksum
How to use checksums
5f77de83f072b18d1acc97b0bb78ecc9d92f0605a563a7099a9884c094204f9f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / ballistic_solver-1.1.0-cp310-cp310-win_amd64.whl

Download URL ballistic_solver-1.1.0-cp310-cp310-win_amd64.whl
Size 165.3 kB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
78006d5ab2c21a24f5f3fb5c3b816bc9e780f2bdcfb44805faddf8698a64761f
BLAKE2b-256 checksum
How to use checksums
8a9c8b4516a8131fe88f90125b7e42871ac36c408aa45d56ccb5bb3437da93a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / ballistic_solver-1.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL ballistic_solver-1.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 184.5 kB
Tags CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
7a3073e47ef92d627c3442f2908aab41ed2fb1b4d8fbcaedbb6e973845921978
BLAKE2b-256 checksum
How to use checksums
a5ee9a5990e0c108276a38f5fd35528e0a51644d88b9ff609d0981eb669017cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / ballistic_solver-1.1.0-cp310-cp310-macosx_10_9_universal2.whl

Download URL ballistic_solver-1.1.0-cp310-cp310-macosx_10_9_universal2.whl
Size 296.9 kB
Tags CPython 3.10 macOS 10.9+ universal2 (ARM64, x86-64)
SHA-256 checksum
How to use checksums
13d2557c7b21af477108867415238a1425ca648312b6dbf75c5e85e48577feb3
BLAKE2b-256 checksum
How to use checksums
509e056836329954cad0aaeb05f986fccd494bc778d9fb789d69361dc91e6f9f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Security for ballistic-solver 1.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 10 files in this release have been uploaded with provenance metadata.

Select from 10 files

Attestation for ballistic_solver-1.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page