Files
mikael-lovqvists-claude-agent 9600a2bc2a Add Goldberg Polyhedron Paint experiment
Interactive WebGL Goldberg polyhedron viewer and painter with PBR
shading, adjustable environment lighting, paint tools (pen, brush,
circle, fill, line, pick), undo/redo, colour palettes, and mesh
relaxation. Added to the standalone experiments index.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 16:00:19 +00:00

46 lines
1.4 KiB
JavaScript

import { quat_from_axis_angle, quat_mul } from './math.mjs';
export class Spin_State {
constructor() {
this.active = false;
this.axis = [0, 1, 0];
this.target = [0, 1, 0];
this.speed = 0.00035; // radians per millisecond
this.last_t = null;
}
_random_unit() {
let x, y, z, r;
do {
x = Math.random()*2-1; y = Math.random()*2-1; z = Math.random()*2-1;
r = Math.sqrt(x*x+y*y+z*z);
} while (r < 0.001 || r > 1);
return [x/r, y/r, z/r];
}
_new_target() { this.target = this._random_unit(); }
// Advance spin by dt ms. Returns updated rot_quat (unchanged if not active).
tick(dt, rot_quat) {
if (!this.active) { return rot_quat; }
if (this.last_t === null) { this._new_target(); return rot_quat; }
const drift = Math.min(1, dt * 0.0003);
const [ax,ay,az] = this.axis;
const [tx,ty,tz] = this.target;
let mx = ax + (tx-ax)*drift, my = ay + (ty-ay)*drift, mz = az + (tz-az)*drift;
const mr = Math.sqrt(mx*mx+my*my+mz*mz);
this.axis = [mx/mr, my/mr, mz/mr];
const dot = this.axis[0]*this.target[0] + this.axis[1]*this.target[1] + this.axis[2]*this.target[2];
if (dot > 0.999) { this._new_target(); }
const angle = this.speed * dt;
const [rx,ry,rz] = this.axis;
return quat_mul(quat_from_axis_angle(rx, ry, rz, angle), rot_quat);
}
start() { this.active = true; this.last_t = null; }
stop() { this.active = false; this.last_t = null; }
}