pub fn apply_dsf(result: &mut TrajectoryResult, table: &DsfTable)Expand description
Apply a DSF table to an already-solved trajectory, IN PLACE, scaling only each
point’s drop below the line of sight — in BOTH result.points and, when present,
result.sampled_points.
For each point in result.points:
- Per-point Mach is
point.velocity_magnitude / result.station_speed_of_sound_mps— the same frozen “station” speed of sound the solver itself divides intovelocity_magnitudefor its own per-point Mach diagnostics (Mach-transition tracking, pitch-damping, precession/nutation; see the “MBA-1136 (rank 30)” comments next toresolved_atmosphere()incli_api.rs’s integration loops). The engine does NOT store a re-derived per-altitude local speed of sound onTrajectoryPointitself, so this is “the way the solver does it”, not a sea-level constant and not a new per-point atmosphere recompute. It is also the same divisor the truing observation path uses to derive an observation’s Mach (trajectory_observation.rs), so a DSF point keyed at derivation time lands back on the identical Mach at application time — a per-point local recompute here would skew the two apart. drop = result.line_of_sight_height_m - point.position.y(drop below the horizontal line of sight, in the solver’s ground-referenced frame — the samedrop_offset - yconventioncli_api::fit_value_atuses for BC-fit drop curves).point.position.yis rewritten so that the (possibly rescaled) drop isdrop * table.factor_at(mach).
result.sampled_points (populated when --sample-trajectory is requested; read by
the Table’s “Sampled Trajectory” section, CSV --full, and the PDF dope card — the
PDF dope card always requires sampling) is a SEPARATE Vec<TrajectorySample> from
points and was, until MBA-1357 Task 2’s review (Critical #2), left untouched by this
function — those outputs silently rendered untrued drops even with an active DSF
table. Each TrajectorySample already stores its drop directly as drop_m (the same
LOS - actual sign convention derived from points above — see
trajectory_sampling.rs’s sample_trajectory doc comment), so no position
reconstruction is needed: sample.drop_m is simply multiplied by
table.factor_at(mach), with mach computed from sample.velocity_mps via the
identical frozen station_speed_of_sound_mps divisor used for points above. This
mirrors run_sampled_trajectory‘s (come-ups’ own sampled-trajectory path, main.rs)
hand-rolled version of the same transform, so both paths now agree. None stays
None — nothing to scale.
Nothing else is touched: position.x (downrange), position.z (windage/lateral),
velocity_magnitude, kinetic_energy, and time are byte-identical to their
pre-call values on points; distance_m, wind_drift_m, velocity_mps,
energy_j, time_s, and flags are byte-identical on sampled_points; every
top-level scalar on result itself (time_of_flight, impact_velocity,
impact_energy, max_range, max_height, …) is untouched too.