|
lob 0.11.0
Exterior ballistics library — API + technical reference
|
Given a desired range R, find the sight adjustment that makes the trajectory hit:
where θ*(R) solves f(θ)=0 as in Zero-Angle Solver. The difficulty is doing this for many R without repeating the full trajectory integration more than necessary and handling unreachable or zero ranges correctly.
lob exposes two APIs over the same core (source/lob_solve.cpp, include/lob/lob.h):
LobSolveInverse / lob::SolveInverse — iterative, authoritative.
Seeding with FastInverseAngle applied to the forward residual gives a starting angle usually within 0.1 MOA of the solution (test/source/solve_angle_test.cpp), so the inner iteration typically converges in 1–2 steps.
LobFastInverse / lob::FastInverse — one-step, in-place.
No integration is performed; the call just warps the stored forward height via the geometric formula. Hence the doc warning: only convert outputs whose forward solve reached R — fall-short residuals are meaningless (source/lob_solve.cpp).
Both the builder's zero finding (FastSolveAngle) and inverse solving (FastSolveAngle or SolveAngle per-range gated on drop>100ft) route through SolveAngle/FastSolveAngle/FastInverseAngle in source/solve_angle.hpp:
Zero-angle uses a vacuum parabola seed; inverse uses the forward residual seed. They converge with the same tolerance 0.01 MOA, bounds ±45°, and iteration cap 10. Sharing the mechanism avoids divergence between “how we zero” and “how we compute adjustments” (Shared Angle Solver).
range==0 entries: LobSolveInverse counts them with 0 MOA; LobFastInverse skips them and does not count them (source/lob_solve.cpp LobFastInverse).LobSolveInverse stops at the first unreachable range (where SolveAngle returns NaN) and reports only the reachable prefix; LobFastInverse does not stop — it would silently give a wrong number for a fall-short, hence the asymmetry is intentional. Note: a fall-short LobSolve still produces an output at the tumble/max-time point; LobSolveInverse only discards it if the angle solve for that achieved range fails.LobSolveInverse requires strictly increasing pranges; otherwise 0 is returned (same guard as LobSolve). LobFastInverse operates in-place and does not check pranges.FastInverse and not counted.Validation in test/source/lob_inverse_test.cpp:
std::array overloads,FastInverse and iterative inverse within 0.1 MOA when jump is non-zero (cross-checks the jump addition inside both paths),SolveAngle tight-tolerance and unreachable tests.SolveInverse for published adjustment tables.FastInverse when you already have forward outputs and know they are reachable and want to avoid a second integration. Spot-check a few ranges against SolveInverse to confirm FastInverse error is acceptable for your trajectory.