Step 05 — Sweeping in 1D (entry & exit time)
This is the seed of the whole engine. Get this one in your bones and the scary
2D sweptAABB becomes "do this twice and combine."
Concept
Forget 2D. Forget boxes. We have:
- a point sitting at position
pon a number line, - moving with velocity
v— meaning over this one frame it travels a total ofvunits (so at fractiontof the frame, it's atp + v*t, fortfrom 0 to 1), - and a static interval
[min, max]on that same line.
Question: during this frame, for which t is the point inside [min, max]?
The slab math
The point reaches min when p + v*t = min, i.e. t = (min - p) / v. Likewise
it reaches max at t = (max - p) / v.
t1 = (min - p) / v
t2 = (max - p) / v
If v is negative (moving left), the point hits max before min, so
t1 > t2. We always want entry to be the smaller and exit the larger, so
swap them if they're out of order. Then:
entry= the time the point enters the interval,exit= the time it leaves.
These can be negative or greater than 1 — that just means the crossing happens before this frame started or after it ends. Don't clamp here; the caller (step 06/08) decides whether
entryfalls within[0, 1]. Keeping the raw numbers is what lets us combine axes later.
The v == 0 edge case
If the point isn't moving (v == 0), it never crosses an edge — dividing by
zero is meaningless. Instead: it's either already inside the interval for the
whole frame, or never. So:
- if
min <= p <= max: it's inside the entire time →entry = -Infinity,exit = +Infinity. - otherwise: it never overlaps → return
null.
(Those infinities are deliberate: in 2D they let a non-moving axis say "I'm not
the axis that limits the collision," without breaking the max/min combine
step. You'll see why in step 06.)
Task
Implement sweepInterval(p, v, min, max) in sweep1d.ts. Return
{ entry, exit }, or null only in the not-moving-and-outside case.
bun test workshop/steps/05-sweep-1d