time for a snapshot

This commit is contained in:
Schluffe
2026-07-11 17:48:28 +02:00
parent 135b7c3042
commit 7262752e16
47 changed files with 1712 additions and 61 deletions
@@ -0,0 +1,59 @@
import {
type AABB,
add,
EPSILON,
type Hit,
scale,
slide,
sweptAABB,
type Vec,
} from "./given.ts";
/**
* Move `box` by the full-frame displacement `v`, sliding along any `walls` it
* hits, up to 4 iterations. Returns the final corner position.
*
* See the README for the algorithm. You already have everything you need in
* given.ts: sweptAABB, slide, add, scale, EPSILON.
*/
export function moveAndSlide(box: AABB, v: Vec, walls: AABB[]): Vec {
let pos: Vec = { x: box.x, y: box.y };
let vel: Vec = { x: v.x, y: v.y };
let timeLeft = 1;
let i = 0;
while (i++ < 4 && timeLeft > 0) {
const move = scale(vel, timeLeft);
let nearest: Hit = {
normal: { x: 0, y: 0 },
time: 2,
};
for (const wall of walls) {
const hit = sweptAABB(
{
x: pos.x,
y: pos.y,
w: box.w,
h: box.h,
},
move,
wall,
);
if (hit !== null) {
nearest = hit.time < nearest.time ? hit : nearest;
}
}
if (nearest.time === 2) {
pos = add(pos, move);
break;
} else {
pos = add(pos, scale(move, Math.max(0, nearest.time - EPSILON)));
vel = slide(vel, nearest.normal);
timeLeft = timeLeft * (1 - nearest.time);
}
}
return pos;
}