WIP
This commit is contained in:
@@ -7,8 +7,8 @@ entry/exit time of one sweep") finally fuse. A **moving point vs a static box**.
|
||||
|
||||
A point at `p` moves by `v` over the frame. A static box has a left/right edge
|
||||
(its x-interval) and a top/bottom edge (its y-interval). The point is inside the
|
||||
**box** only while it's inside the x-interval **and** the y-interval *at the same
|
||||
time*.
|
||||
**box** only while it's inside the x-interval **and** the y-interval _at the
|
||||
same time_.
|
||||
|
||||
So run `sweepInterval` twice:
|
||||
|
||||
@@ -18,7 +18,7 @@ spanY = sweepInterval(p.y, v.y, box.y, box.y + box.h) // the y-edges
|
||||
```
|
||||
|
||||
Each gives you a time-window `[entry, exit]` during which the point is inside
|
||||
*that one axis's* strip. You're inside the box during the **overlap of the two
|
||||
_that one axis's_ strip. You're inside the box during the **overlap of the two
|
||||
windows**:
|
||||
|
||||
```
|
||||
@@ -28,7 +28,7 @@ exit = min(spanX.exit, spanY.exit) // out of the box once you leave the FIR
|
||||
|
||||
Read those two lines until they feel obvious — they're the whole algorithm:
|
||||
|
||||
- You're only truly *inside the box* once you've entered **both** strips, so the
|
||||
- You're only truly _inside the box_ once you've entered **both** strips, so the
|
||||
real entry is the **later** of the two entries → `max`.
|
||||
- You **leave** the box the instant you exit **either** strip → the **earlier**
|
||||
exit → `min`.
|
||||
@@ -36,28 +36,29 @@ Read those two lines until they feel obvious — they're the whole algorithm:
|
||||
### When is there NO hit?
|
||||
|
||||
1. **A span is `null`** — on some axis the point isn't moving and is already
|
||||
outside that strip. It can never be inside the box. Return `null` immediately.
|
||||
outside that strip. It can never be inside the box. Return `null`
|
||||
immediately.
|
||||
2. **`entry > exit`** — the two windows never overlap. The point is inside one
|
||||
strip, then the other, but never both at once. That's the classic "flies past
|
||||
the corner" miss.
|
||||
3. **`entry >= 1` or `exit <= 0`** — the windows overlap, but not *during this
|
||||
frame* (it's entirely in the future, or entirely in the past). Not our problem
|
||||
this frame.
|
||||
3. **`entry >= 1` or `exit <= 0`** — the windows overlap, but not _during this
|
||||
frame_ (it's entirely in the future, or entirely in the past). Not our
|
||||
problem this frame.
|
||||
|
||||
### The normal (which wall did we hit?)
|
||||
|
||||
When you do collide, you also want to know **which face** you hit, so the response
|
||||
later can push you back the right way. That's the `normal` — a unit vector
|
||||
pointing out of the surface you struck.
|
||||
When you do collide, you also want to know **which face** you hit, so the
|
||||
response later can push you back the right way. That's the `normal` — a unit
|
||||
vector pointing out of the surface you struck.
|
||||
|
||||
The trick: **the axis you entered *last* is the axis you actually hit.** Compare
|
||||
The trick: **the axis you entered _last_ is the axis you actually hit.** Compare
|
||||
the two entry times — whichever is larger is the blocking axis:
|
||||
|
||||
- if `spanX.entry > spanY.entry` → you hit a **vertical** wall (left/right face).
|
||||
The normal is horizontal, pointing back against your x-motion:
|
||||
- if `spanX.entry > spanY.entry` → you hit a **vertical** wall (left/right
|
||||
face). The normal is horizontal, pointing back against your x-motion:
|
||||
`normal = { x: v.x > 0 ? -1 : 1, y: 0 }`.
|
||||
- otherwise → you hit a **horizontal** wall (top/bottom). The normal is vertical:
|
||||
`normal = { x: 0, y: v.y > 0 ? -1 : 1 }`.
|
||||
- otherwise → you hit a **horizontal** wall (top/bottom). The normal is
|
||||
vertical: `normal = { x: 0, y: v.y > 0 ? -1 : 1 }`.
|
||||
|
||||
(Moving right and hitting something → the surface pushes you left → normal `-1`.
|
||||
That sign rule is all there is to it.)
|
||||
|
||||
Reference in New Issue
Block a user