UNPKG

@thi.ng/geom-tessellate

Version:

2D/3D convex polygon tessellators

49 lines (48 loc) 1.24 kB
import { pointInTriangle2 } from "@thi.ng/geom-isec/point"; import { polyArea2 } from "@thi.ng/geom-poly-utils/area"; import { range } from "@thi.ng/transducers/range"; import { signedArea2 } from "@thi.ng/vectors/signed-area"; const earCut = (tess, faces, pids) => { let n = pids.length; const points = tess.pointsForIDs(pids); const order = [ ...polyArea2(points) > 0 ? range(n) : range(n - 1, -1, -1) ]; let count = 2 * n - 1; let v = n - 1, u, w; while (count > 0 && n > 2) { u = n <= v ? 0 : v; v = u + 1; v = n <= v ? 0 : v; w = v + 1; w = n <= w ? 0 : w; if (__snip(points, u, v, w, n, order)) { faces.push([pids[order[u]], pids[order[v]], pids[order[w]]]); order.splice(v, 1); n--; count = 2 * n; } else { count--; } } return faces; }; const __snip = (points, u, v, w, n, ids) => { const a = points[ids[u]]; const b = points[ids[v]]; const c = points[ids[w]]; if (signedArea2(a, b, c) > 0) { for (let i = 0; i < n; i++) { if (i !== u && i !== v && i !== w) { if (pointInTriangle2(points[ids[i]], a, b, c)) { return false; } } } return true; } return false; }; export { earCut };