/** Runnable self-check for the cut geometry — the honest core, and the part
 *  that hid a degenerate-vertex bug (a cut line through two verts made lopsided
 *  halves). Run: `node src/sim/geom.check.ts` (Node strips the types). */
import { polyArea, pieceCV, cvWord, splitConvexByLine, type V } from './geom.ts';
import assert from 'node:assert/strict';

const circle = (r: number, n: number): V[] =>
  Array.from({ length: n }, (_, i) => ({ x: Math.cos((i / n) * 2 * Math.PI) * r, y: Math.sin((i / n) * 2 * Math.PI) * r }));

// 1. centred vertical cut of a symmetric polygon → equal halves
{
  const c = circle(34, 12);
  const [L, R] = splitConvexByLine(c, { x: 0, y: -50 }, { x: 0, y: 50 })!;
  assert(Math.abs(polyArea(L) - polyArea(R)) < 1e-6, 'off-vertex split should be symmetric');
}

// 2. THE REGRESSION: cut line passing exactly through two vertices (top+bottom
//    of a 12-gon at (0,±r)) must still give equal halves, not lopsided ones.
{
  const c = circle(34, 12);
  const [L, R] = splitConvexByLine(c, { x: 0, y: -34 }, { x: 0, y: 34 })!;
  assert(Math.abs(polyArea(L) - polyArea(R)) < 1e-6, 'through-vertex split must be symmetric');
}

// 3. a line that misses the polygon returns null
{
  assert(splitConvexByLine(circle(10, 8), { x: 100, y: -10 }, { x: 100, y: 10 }) === null, 'miss → null');
}

// 4. pieceCV: equal pieces → 0; the ladder words line up
assert(pieceCV([100, 100]) === 0, 'equal areas → CV 0');
assert(pieceCV([50, 150]) > 0.4, 'lopsided pieces → high CV');
assert(cvWord(0) === 'even' && cvWord(0.5) === 'a lottery', 'cvWord ladder');

console.log('geom.check: all assertions passed');
