scripts/mascot-bodies/sdf.test.mjs
Rama main · réplica de lectura del repositorio original.
import { describe, expect, it } from "vitest";
import { maskFromPolylines } from "./raster.ts";
import { fieldFromMask, largestInscribedCircle, sampleSdf } from "./sdf.ts";
const FACE_BOX = 228.541;
const SIZE = 256;
const circle = (r, steps = 512) => {
const c = FACE_BOX / 2;
const points = [];
for (let i = 0; i < steps; i++) {
const a = (i / steps) * Math.PI * 2;
points.push([c + Math.cos(a) * r, c + Math.sin(a) * r]);
}
return [points];
};
const fieldFor = (r) => fieldFromMask(maskFromPolylines(circle(r), SIZE), SIZE);
describe("sdf", () => {
it("is positive inside, negative outside, and zero on the edge", () => {
const sdf = fieldFor(80);
const c = FACE_BOX / 2;
expect(sampleSdf(sdf, c, c)).toBeGreaterThan(70);
expect(sampleSdf(sdf, c + 100, c)).toBeLessThan(0);
expect(Math.abs(sampleSdf(sdf, c + 80, c))).toBeLessThan(3);
});
it("finds the centre of a circle as its largest inscribed circle", () => {
const found = largestInscribedCircle(fieldFor(80));
expect(found.x).toBeCloseTo(FACE_BOX / 2, 0);
expect(found.y).toBeCloseTo(FACE_BOX / 2, 0);
// A pixel-sampled field cannot resolve the radius exactly: FACE_BOX/2 lands on a
// pixel corner at SIZE=256, so the best-placed pixel centre sits ~0.7px off the
// true centre, and the EDT measures to outside pixel CENTRES rather than to the
// true edge. The shortfall is ~0.6px (~0.55 units) at every radius tested.
expect(found.radius).toBeGreaterThan(79);
// Over-estimating would report clearance the shape lacks and let a face clip;
// under-estimating only costs a slightly smaller face.
expect(found.radius).toBeLessThanOrEqual(80);
});
});