Earliest time t > 0 at which a projectile launched from position with
velocity under gravity crosses the horizontal plane y = planeY, or NaN
when it never does again — the flight time to that plane. The bound is strict
so that a shot fired from the plane reports its landing rather than 0; see
the root choice below.
Only the Y components matter — the plane is horizontal and the world is Y-up
(§7a) — so this is the quadratic
A parabola crosses a horizontal plane twice: once rising, once falling. This
returns the smaller of the two roots that is strictly greater than zero —
the first crossing still ahead:
both roots in the past → NaN (nothing ahead to report);
one root at or before 0, one after → the later one. This is why the bound
is strict: a projectile launched from the plane has a root at t = 0,
and the useful answer is its landing, not the launch. That answer is the
familiar 2·velocity.y / |gravity.y|, i.e. twice
ballisticTimeToApex.
both roots ahead → the earlier one. For a shot fired upward at a plane above
it, that is the crossing on the way up; the other crossing (coming back
down) is 2·timeToApex − t when gravity is vertical.
negative discriminant (the apex never reaches the plane) → NaN.
Degenerate cases, all consistent with "earliest t > 0 that satisfies the
equation": with gravity.y = 0 the equation is linear (level flight crosses
once or never); with velocity.y = 0 as well, the path never leaves its
height, so the answer is NaN unless that height is the plane — a path
lying in the plane at every time reports 0.
The roots are computed with the numerically stable form (multiply by the
conjugate rather than differencing two nearly equal numbers), so a nearly
grazing shot does not lose precision.
Earliest time
t > 0at which a projectile launched frompositionwithvelocityundergravitycrosses the horizontal planey = planeY, orNaNwhen it never does again — the flight time to that plane. The bound is strict so that a shot fired from the plane reports its landing rather than0; see the root choice below.Only the Y components matter — the plane is horizontal and the world is Y-up (§7a) — so this is the quadratic
Root choice (decision, WP-8.3)
A parabola crosses a horizontal plane twice: once rising, once falling. This returns the smaller of the two roots that is strictly greater than zero — the first crossing still ahead:
NaN(nothing ahead to report);0, one after → the later one. This is why the bound is strict: a projectile launched from the plane has a root att = 0, and the useful answer is its landing, not the launch. That answer is the familiar2·velocity.y / |gravity.y|, i.e. twice ballisticTimeToApex.2·timeToApex − twhen gravity is vertical.NaN.Degenerate cases, all consistent with "earliest
t > 0that satisfies the equation": withgravity.y = 0the equation is linear (level flight crosses once or never); withvelocity.y = 0as well, the path never leaves its height, so the answer isNaNunless that height is the plane — a path lying in the plane at every time reports0.The roots are computed with the numerically stable form (multiply by the conjugate rather than differencing two nearly equal numbers), so a nearly grazing shot does not lose precision.