Triangles of a panel outline
32-bit, display onlyCuts a panel's outline into triangles for drawing.
ear when (b − a) × (c − a) > 1e-9 and no other point is inside the triangle
Ear clipping with fixed limits of 1e-9 on cross products in the job's unit squared. It returns index triples only; no coordinate is changed.
/** Ear clipping of a simple polygon, counter-clockwise. */
export function triangulate(pts) {
const n = pts.length, idx = pts.map((_, i) => i), out = [];
const cross = (a, b, c) => (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
const inTri = (p, a, b, c) => cross(a, b, p) >= -1e-9 && cross(b, c, p) >= -1e-9 && cross(c, a, p) >= -1e-9;
let guard = n * n + 10;
while (idx.length > 3 && guard-- > 0) {
let cut = false;
for (let k = 0; k < idx.length; k++) {
const i0 = idx[(k + idx.length - 1) % idx.length], i1 = idx[k], i2 = idx[(k + 1) % idx.length];
const a = pts[i0], b = pts[i1], c = pts[i2];
if (cross(a, b, c) <= 1e-9) continue;
if (idx.some((j) => j !== i0 && j !== i1 && j !== i2 && inTri(pts[j], a, b, c))) continue;
out.push([i0, i1, i2]); idx.splice(k, 1); cut = true; break;
}
if (!cut) break;
}
if (idx.length === 3) out.push([idx[0], idx[1], idx[2]]);
void n;
return out;
}