Expand description
MBA-1361: reticle schema, parametric generators, and the hold-point-in-reticle API.
Shooters who HOLD rather than dial need the answer expressed where they actually read
it: a point in their own reticle. This module is the engine slice of that — one shared
model (serde-serializable) that the CLI, the browser terminal, the FFI consumers and
the front ends can all speak, plus the coordinate transform from an angular firing
solution to a reticle coordinate. It is a transform plus a schema, not new physics: the
raw material (angular drop and drift in milliradians) is already a first-class output
everywhere in this crate.
§Intellectual-property exclusions (deliberate, do not “fill in”)
Horus grid reticles and Time-of-Flight Wind Dots are actively patented, and Horus monetizes app integration through its own licensed app. Therefore this module has, and must keep having:
- no TREMOR-family / Horus grid layouts —
ReticleDescription::mil_gridbuilds a plain mil-hash CROSS (marks along the two stadia), never a filled two-dimensional grid, andReticleDescription::treeis a generic parametric widening tree with no vendor geometry in it; - no wind-dot calibration — nothing here maps a time of flight, a wind speed or a “wind hold number” onto a dot. Wind enters only as an angular deflection the caller already solved, in milliradians, exactly like elevation;
- no vendor reticle catalog. Manufacturer subtension sheets are published facts and are a legally viable catalog source, but curating one is a separate, per-vendor IP-reviewed data project (a tracked follow-up), not this module.
§Angular conventions (the whole set, in one place)
Every angle here is a milliradian (mil), and every reticle coordinate is measured from the optical center:
down_mil— POSITIVE is BELOW center. A holdover point is at positivedown_mil.right_mil— POSITIVE is to the shooter’s RIGHT of center.
The hold point follows straight from that. If the bullet falls d mil below the line
of sight at some range, the shooter must place a reticle point d mil BELOW center on
the target — so down_mil == drop_mil. If the wind pushes the bullet w mil to the
RIGHT, the shooter must aim left by placing a point w mil to the RIGHT of center on
the target — so right_mil == wind_mil. hold_point_in_reticle therefore carries
the firing solution through unchanged and does the real work in the mark search; the
value of stating it here is that every surface now agrees on which way is which.
§Focal plane
Published optics-manual math, no more:
- FFP (first focal plane): the reticle is magnified with the image, so a mark subtends the same angle at every magnification. Marks are used as authored.
- SFP (second focal plane): the reticle is a fixed angular size at the eyepiece
while the target image scales, so a mark’s TRUE subtension is
nominal * reference_magnification / magnification. A 2 mil mark on a reticle calibrated at 10x covers 4 mil of target at 5x, and 1 mil at 20x.
The hold point is a property of the trajectory, not of the optic, so it is always TRUE angular. The mark search therefore scales the MARKS into true angular space and compares there — never the other way round.
Structs§
- Reticle
Description - A complete reticle: its focal plane, its calibration magnification, and its marks.
- Reticle
Hold - Where a firing solution lands in a reticle (MBA-1361).
- Reticle
Mark - One aiming mark, positioned in NOMINAL angular units from the optical center.
- Scaled
Mark - The true-angular position of a mark after focal-plane scaling.
Enums§
- Focal
Plane - Which focal plane the reticle is etched in.
- Mark
Kind - What a mark looks like. Purely descriptive — the hold math treats every kind identically, and renderers use it to draw.
- Reticle
Error - Why a reticle operation was rejected. Typed rather than stringly, so front ends can render their own wording and the FFI can map to a code.
- Reticle
Format - Rendering shape for the
reticlecommand family.
Constants§
- MAX_
RETICLE_ MARKS - Largest mark count any generator will produce, and the most
ReticleDescription::validatewill accept. - OFF_
RETICLE_ MARGIN_ FRACTION - Fraction of each axis’s mark span added as slack before a hold counts as
ReticleHold::off_reticle. See that field for the exact rule.
Functions§
- format_
reticle_ description - Render a reticle description, identically on every surface (MBA-1361).
- format_
reticle_ hold - Render a hold point, identically on every surface (MBA-1361).
- hold_
point_ in_ reticle - Place a firing solution in a reticle (MBA-1361).