diff --git a/debug/tick.ts b/debug/tick.ts index d0ddd09..3e0c44b 100644 --- a/debug/tick.ts +++ b/debug/tick.ts @@ -43,6 +43,8 @@ export function OrbitDemo() { cx.scale(1 / 2, 1 / 2); cx.translate(512, 512); + const G = 8000; + const PHYSICS_TICKS = 30; const masses: { x: number; y: number; @@ -51,22 +53,47 @@ export function OrbitDemo() { r: number; m: number; c: string; - }[] = [ - { x: 0, y: 0, vx: 0, vy: 0, r: 10, m: 10000, c: "yellow" }, - { x: -200, y: 200, vx: 100, vy: 100, r: 4, m: 4, c: "red" }, - { x: -450, y: 0, vx: 0, vy: 100, r: 5, m: 5, c: "blue" }, - ]; + }[] = []; - const tickSource = tick(16); + const tickSource = tick(PHYSICS_TICKS); let cancel: Cancel; const begin = () => { // reset / init cancel?.(); + masses.length = 0; + masses.push( + { x: 0, y: 0, vx: -1, vy: -2, r: 10, m: 1000, c: "yellow" }, + { x: -150, y: 150, vx: 130, vy: 130, r: 9, m: 10, c: "red" }, + { x: -450, y: 0, vx: 0, vy: 120, r: 4, m: 5, c: "#0f8" } + ); // subscribe to source, stash cancellation func cancel = tickSource((tick) => { switch (tick[0]) { case "physics": + // apply velocities + masses.forEach((mass) => { + mass.x += mass.vx * (1 / PHYSICS_TICKS); + mass.y += mass.vy * (1 / PHYSICS_TICKS); + }); + // apply accelerations + masses.forEach((mass) => { + masses.forEach((other) => { + if (mass != other) { + const dx = other.x - mass.x; + const dy = other.y - mass.y; + + const rSquared = dx ** 2 + dy ** 2; + const f = (G * other.m) / rSquared; + const d = Math.sqrt(rSquared); + const fx = (f * dx) / d; + const fy = (f * dy) / d; + + mass.vx += fx / PHYSICS_TICKS; + mass.vy += fy / PHYSICS_TICKS; + } + }); + }); break; case "render": const [, dt] = tick;