pattapatta 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +98 -0
  4. package/dist/circle-BDbKfrdR.d.ts +12 -0
  5. package/dist/circlePacking/index.d.ts +78 -0
  6. package/dist/circlePacking/index.js +381 -0
  7. package/dist/circlePacking/index.js.map +1 -0
  8. package/dist/cli.js +365 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/construction/index.d.ts +26 -0
  11. package/dist/construction/index.js +102 -0
  12. package/dist/construction/index.js.map +1 -0
  13. package/dist/contour/index.d.ts +20 -0
  14. package/dist/contour/index.js +118 -0
  15. package/dist/contour/index.js.map +1 -0
  16. package/dist/conversion/index.d.ts +31 -0
  17. package/dist/conversion/index.js +99 -0
  18. package/dist/conversion/index.js.map +1 -0
  19. package/dist/group-BNjVVYSQ.d.ts +13 -0
  20. package/dist/hatch/index.d.ts +41 -0
  21. package/dist/hatch/index.js +253 -0
  22. package/dist/hatch/index.js.map +1 -0
  23. package/dist/hull/index.d.ts +16 -0
  24. package/dist/hull/index.js +97 -0
  25. package/dist/hull/index.js.map +1 -0
  26. package/dist/index.d.ts +67 -0
  27. package/dist/index.js +3933 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/meshing/index.d.ts +125 -0
  30. package/dist/meshing/index.js +1333 -0
  31. package/dist/meshing/index.js.map +1 -0
  32. package/dist/morphology/index.d.ts +58 -0
  33. package/dist/morphology/index.js +268 -0
  34. package/dist/morphology/index.js.map +1 -0
  35. package/dist/optimisation/index.d.ts +43 -0
  36. package/dist/optimisation/index.js +400 -0
  37. package/dist/optimisation/index.js.map +1 -0
  38. package/dist/path-0RjhYjJs.d.ts +21 -0
  39. package/dist/pointSet/index.d.ts +24 -0
  40. package/dist/pointSet/index.js +139 -0
  41. package/dist/pointSet/index.js.map +1 -0
  42. package/dist/polygonisation/index.d.ts +44 -0
  43. package/dist/polygonisation/index.js +310 -0
  44. package/dist/polygonisation/index.js.map +1 -0
  45. package/dist/predicates/index.d.ts +35 -0
  46. package/dist/predicates/index.js +159 -0
  47. package/dist/predicates/index.js.map +1 -0
  48. package/dist/processing/index.d.ts +54 -0
  49. package/dist/processing/index.js +457 -0
  50. package/dist/processing/index.js.map +1 -0
  51. package/dist/segment-BKuIFMKD.d.ts +10 -0
  52. package/dist/segmentSet/index.d.ts +25 -0
  53. package/dist/segmentSet/index.js +109 -0
  54. package/dist/segmentSet/index.js.map +1 -0
  55. package/dist/shapeBoolean/index.d.ts +41 -0
  56. package/dist/shapeBoolean/index.js +211 -0
  57. package/dist/shapeBoolean/index.js.map +1 -0
  58. package/dist/svg/index.d.ts +38 -0
  59. package/dist/svg/index.js +317 -0
  60. package/dist/svg/index.js.map +1 -0
  61. package/dist/tiling/index.d.ts +32 -0
  62. package/dist/tiling/index.js +344 -0
  63. package/dist/tiling/index.js.map +1 -0
  64. package/dist/transformation/index.d.ts +37 -0
  65. package/dist/transformation/index.js +184 -0
  66. package/dist/transformation/index.js.map +1 -0
  67. package/dist/triangulation/index.d.ts +48 -0
  68. package/dist/triangulation/index.js +334 -0
  69. package/dist/triangulation/index.js.map +1 -0
  70. package/dist/vec2-CWyXN1Wj.d.ts +10 -0
  71. package/dist/voronoi/index.d.ts +31 -0
  72. package/dist/voronoi/index.js +211 -0
  73. package/dist/voronoi/index.js.map +1 -0
  74. package/package.json +165 -0
@@ -0,0 +1,24 @@
1
+ import { V as Vec2 } from '../vec2-CWyXN1Wj.js';
2
+
3
+ /** Seeded uniform random points in an axis-aligned box. */
4
+ declare function random(count: number, minX: number, minY: number, maxX: number, maxY: number, seed?: number): Vec2[];
5
+ /** Square lattice points covering [minX,maxX] × [minY,maxY]. */
6
+ declare function squareGrid(spacing: number, minX: number, minY: number, maxX: number, maxY: number): Vec2[];
7
+ /** Hexagonal lattice points covering the box. */
8
+ declare function hexGrid(spacing: number, minX: number, minY: number, maxX: number, maxY: number): Vec2[];
9
+ /** Ring of `count` points around `center` with `radius`. */
10
+ declare function ring(count: number, center: Vec2, radius: number): Vec2[];
11
+ /** Bridson-ish Poisson disk sample in a box (seeded). */
12
+ declare function poisson(minDistance: number, minX: number, minY: number, maxX: number, maxY: number, seed?: number, maxAttempts?: number): Vec2[];
13
+ /** Drop points closer than `minDistance` (greedy keep-first). */
14
+ declare function prunePointsWithinDistance(points: Vec2[], minDistance: number): Vec2[];
15
+ declare const pointSet: {
16
+ random: typeof random;
17
+ squareGrid: typeof squareGrid;
18
+ hexGrid: typeof hexGrid;
19
+ ring: typeof ring;
20
+ poisson: typeof poisson;
21
+ prunePointsWithinDistance: typeof prunePointsWithinDistance;
22
+ };
23
+
24
+ export { hexGrid, pointSet, poisson, prunePointsWithinDistance, random, ring, squareGrid };
@@ -0,0 +1,139 @@
1
+ // src/pointSet/index.ts
2
+ function random(count, minX, minY, maxX, maxY, seed = 1) {
3
+ const rng = mulberry32(seed >>> 0);
4
+ const out = [];
5
+ for (let i = 0; i < count; i++) {
6
+ out.push({
7
+ x: minX + rng() * (maxX - minX),
8
+ y: minY + rng() * (maxY - minY)
9
+ });
10
+ }
11
+ return out;
12
+ }
13
+ function squareGrid(spacing, minX, minY, maxX, maxY) {
14
+ const s = Math.max(spacing, 1e-9);
15
+ const out = [];
16
+ for (let x = minX; x <= maxX + 1e-12; x += s) {
17
+ for (let y = minY; y <= maxY + 1e-12; y += s) {
18
+ out.push({ x, y });
19
+ }
20
+ }
21
+ return out;
22
+ }
23
+ function hexGrid(spacing, minX, minY, maxX, maxY) {
24
+ const s = Math.max(spacing, 1e-9);
25
+ const dx = s;
26
+ const dy = s * Math.sqrt(3) * 0.5;
27
+ const out = [];
28
+ let row = 0;
29
+ for (let y = minY; y <= maxY + 1e-12; y += dy, row++) {
30
+ const x0 = minX + (row % 2 === 0 ? 0 : s * 0.5);
31
+ for (let x = x0; x <= maxX + 1e-12; x += dx) {
32
+ out.push({ x, y });
33
+ }
34
+ }
35
+ return out;
36
+ }
37
+ function ring(count, center, radius) {
38
+ const out = [];
39
+ for (let i = 0; i < count; i++) {
40
+ const t = i / count * Math.PI * 2;
41
+ out.push({
42
+ x: center.x + Math.cos(t) * radius,
43
+ y: center.y + Math.sin(t) * radius
44
+ });
45
+ }
46
+ return out;
47
+ }
48
+ function mulberry32(a) {
49
+ return function() {
50
+ let t = a += 1831565813;
51
+ t = Math.imul(t ^ t >>> 15, t | 1);
52
+ t ^= t + Math.imul(t ^ t >>> 7, t | 61);
53
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
54
+ };
55
+ }
56
+ function poisson(minDistance, minX, minY, maxX, maxY, seed = 1, maxAttempts = 30) {
57
+ const rng = mulberry32(seed >>> 0);
58
+ const r = Math.max(minDistance, 1e-9);
59
+ const cell = r / Math.SQRT2;
60
+ const w = maxX - minX;
61
+ const h = maxY - minY;
62
+ const gw = Math.max(1, Math.ceil(w / cell));
63
+ const gh = Math.max(1, Math.ceil(h / cell));
64
+ const grid = Array(gw * gh).fill(null);
65
+ const points = [];
66
+ const active = [];
67
+ const gx = (p) => Math.min(gw - 1, Math.floor((p.x - minX) / cell));
68
+ const gy = (p) => Math.min(gh - 1, Math.floor((p.y - minY) / cell));
69
+ const emit = (p) => {
70
+ const i = points.length;
71
+ points.push(p);
72
+ active.push(i);
73
+ grid[gy(p) * gw + gx(p)] = i;
74
+ };
75
+ emit({
76
+ x: minX + rng() * w,
77
+ y: minY + rng() * h
78
+ });
79
+ while (active.length > 0) {
80
+ const ai = Math.floor(rng() * active.length);
81
+ const i = active[ai];
82
+ const src = points[i];
83
+ let found = false;
84
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
85
+ const ang = rng() * Math.PI * 2;
86
+ const rad = r * (1 + rng());
87
+ const cand = {
88
+ x: src.x + Math.cos(ang) * rad,
89
+ y: src.y + Math.sin(ang) * rad
90
+ };
91
+ if (cand.x < minX || cand.x > maxX || cand.y < minY || cand.y > maxY) {
92
+ continue;
93
+ }
94
+ const cx = gx(cand);
95
+ const cy = gy(cand);
96
+ let ok = true;
97
+ for (let yy = Math.max(0, cy - 2); yy <= Math.min(gh - 1, cy + 2) && ok; yy++) {
98
+ for (let xx = Math.max(0, cx - 2); xx <= Math.min(gw - 1, cx + 2); xx++) {
99
+ const j = grid[yy * gw + xx];
100
+ if (j == null) continue;
101
+ const q = points[j];
102
+ if (Math.hypot(cand.x - q.x, cand.y - q.y) < r) {
103
+ ok = false;
104
+ break;
105
+ }
106
+ }
107
+ }
108
+ if (ok) {
109
+ emit(cand);
110
+ found = true;
111
+ break;
112
+ }
113
+ }
114
+ if (!found) active.splice(ai, 1);
115
+ }
116
+ return points;
117
+ }
118
+ function prunePointsWithinDistance(points, minDistance) {
119
+ const r = Math.max(minDistance, 0);
120
+ const out = [];
121
+ for (const p of points) {
122
+ if (out.every((q) => Math.hypot(p.x - q.x, p.y - q.y) >= r)) {
123
+ out.push(p);
124
+ }
125
+ }
126
+ return out;
127
+ }
128
+ var pointSet = {
129
+ random,
130
+ squareGrid,
131
+ hexGrid,
132
+ ring,
133
+ poisson,
134
+ prunePointsWithinDistance
135
+ };
136
+
137
+ export { hexGrid, pointSet, poisson, prunePointsWithinDistance, random, ring, squareGrid };
138
+ //# sourceMappingURL=index.js.map
139
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/pointSet/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Vec2 } from '../types/index.js'\n\n/** Seeded uniform random points in an axis-aligned box. */\nexport function random(\n count: number,\n minX: number,\n minY: number,\n maxX: number,\n maxY: number,\n seed = 1,\n): Vec2[] {\n const rng = mulberry32(seed >>> 0)\n const out: Vec2[] = []\n for (let i = 0; i < count; i++) {\n out.push({\n x: minX + rng() * (maxX - minX),\n y: minY + rng() * (maxY - minY),\n })\n }\n return out\n}\n\n/** Square lattice points covering [minX,maxX] × [minY,maxY]. */\nexport function squareGrid(\n spacing: number,\n minX: number,\n minY: number,\n maxX: number,\n maxY: number,\n): Vec2[] {\n const s = Math.max(spacing, 1e-9)\n const out: Vec2[] = []\n for (let x = minX; x <= maxX + 1e-12; x += s) {\n for (let y = minY; y <= maxY + 1e-12; y += s) {\n out.push({ x, y })\n }\n }\n return out\n}\n\n/** Hexagonal lattice points covering the box. */\nexport function hexGrid(\n spacing: number,\n minX: number,\n minY: number,\n maxX: number,\n maxY: number,\n): Vec2[] {\n const s = Math.max(spacing, 1e-9)\n const dx = s\n const dy = s * Math.sqrt(3) * 0.5\n const out: Vec2[] = []\n let row = 0\n for (let y = minY; y <= maxY + 1e-12; y += dy, row++) {\n const x0 = minX + (row % 2 === 0 ? 0 : s * 0.5)\n for (let x = x0; x <= maxX + 1e-12; x += dx) {\n out.push({ x, y })\n }\n }\n return out\n}\n\n/** Ring of `count` points around `center` with `radius`. */\nexport function ring(\n count: number,\n center: Vec2,\n radius: number,\n): Vec2[] {\n const out: Vec2[] = []\n for (let i = 0; i < count; i++) {\n const t = (i / count) * Math.PI * 2\n out.push({\n x: center.x + Math.cos(t) * radius,\n y: center.y + Math.sin(t) * radius,\n })\n }\n return out\n}\n\nfunction mulberry32(a: number): () => number {\n return function () {\n let t = (a += 0x6d2b79f5)\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/** Bridson-ish Poisson disk sample in a box (seeded). */\nexport function poisson(\n minDistance: number,\n minX: number,\n minY: number,\n maxX: number,\n maxY: number,\n seed = 1,\n maxAttempts = 30,\n): Vec2[] {\n const rng = mulberry32(seed >>> 0)\n const r = Math.max(minDistance, 1e-9)\n const cell = r / Math.SQRT2\n const w = maxX - minX\n const h = maxY - minY\n const gw = Math.max(1, Math.ceil(w / cell))\n const gh = Math.max(1, Math.ceil(h / cell))\n const grid: (number | null)[] = Array(gw * gh).fill(null)\n const points: Vec2[] = []\n const active: number[] = []\n\n const gx = (p: Vec2) => Math.min(gw - 1, Math.floor((p.x - minX) / cell))\n const gy = (p: Vec2) => Math.min(gh - 1, Math.floor((p.y - minY) / cell))\n\n const emit = (p: Vec2) => {\n const i = points.length\n points.push(p)\n active.push(i)\n grid[gy(p) * gw + gx(p)] = i\n }\n\n emit({\n x: minX + rng() * w,\n y: minY + rng() * h,\n })\n\n while (active.length > 0) {\n const ai = Math.floor(rng() * active.length)\n const i = active[ai]!\n const src = points[i]!\n let found = false\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const ang = rng() * Math.PI * 2\n const rad = r * (1 + rng())\n const cand = {\n x: src.x + Math.cos(ang) * rad,\n y: src.y + Math.sin(ang) * rad,\n }\n if (\n cand.x < minX ||\n cand.x > maxX ||\n cand.y < minY ||\n cand.y > maxY\n ) {\n continue\n }\n const cx = gx(cand)\n const cy = gy(cand)\n let ok = true\n for (let yy = Math.max(0, cy - 2); yy <= Math.min(gh - 1, cy + 2) && ok; yy++) {\n for (let xx = Math.max(0, cx - 2); xx <= Math.min(gw - 1, cx + 2); xx++) {\n const j = grid[yy * gw + xx]\n if (j == null) continue\n const q = points[j]!\n if (Math.hypot(cand.x - q.x, cand.y - q.y) < r) {\n ok = false\n break\n }\n }\n }\n if (ok) {\n emit(cand)\n found = true\n break\n }\n }\n if (!found) active.splice(ai, 1)\n }\n return points\n}\n\n/** Drop points closer than `minDistance` (greedy keep-first). */\nexport function prunePointsWithinDistance(\n points: Vec2[],\n minDistance: number,\n): Vec2[] {\n const r = Math.max(minDistance, 0)\n const out: Vec2[] = []\n for (const p of points) {\n if (out.every((q) => Math.hypot(p.x - q.x, p.y - q.y) >= r)) {\n out.push(p)\n }\n }\n return out\n}\n\nexport const pointSet = {\n random,\n squareGrid,\n hexGrid,\n ring,\n poisson,\n prunePointsWithinDistance,\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import { V as Vec2 } from '../vec2-CWyXN1Wj.js';
2
+ import { P as Path } from '../path-0RjhYjJs.js';
3
+
4
+ /** Convex hull (largest-area simple polygonisation for a point cloud). */
5
+ declare function maxArea(points: Vec2[]): Path;
6
+ /**
7
+ * Minimum-area triangle covering the points among hull edges
8
+ * (O(h²) rotating-calipers style brute force on hull).
9
+ * Falls back to hull if fewer than 3 hull vertices.
10
+ */
11
+ declare function minArea(points: Vec2[]): Path;
12
+ /** Closed polygon connecting points in order of minimum spanning path heuristic (NN tour). */
13
+ declare function minPerimeter(points: Vec2[]): Path;
14
+ /** Connect points sorted by x then y. */
15
+ declare function horizontal(points: Vec2[]): Path;
16
+ /** Connect points sorted by y then x. */
17
+ declare function vertical(points: Vec2[]): Path;
18
+ /** Connect by polar angle around centroid. */
19
+ declare function angular(points: Vec2[]): Path;
20
+ /** Alias of angular. */
21
+ declare function circular(points: Vec2[]): Path;
22
+ /**
23
+ * Onion layers: successive convex hulls. Returns the outermost hull polygon;
24
+ * use `onionLayers` for all peels.
25
+ */
26
+ declare function onion(points: Vec2[]): Path;
27
+ /** Convex onion peels from outside in. */
28
+ declare function onionLayers(points: Vec2[]): Path[];
29
+ /** Connect points ordered by 2D Hilbert curve index. */
30
+ declare function hilbert(points: Vec2[]): Path;
31
+ declare const polygonisation: {
32
+ maxArea: typeof maxArea;
33
+ minArea: typeof minArea;
34
+ minPerimeter: typeof minPerimeter;
35
+ horizontal: typeof horizontal;
36
+ vertical: typeof vertical;
37
+ angular: typeof angular;
38
+ circular: typeof circular;
39
+ onion: typeof onion;
40
+ onionLayers: typeof onionLayers;
41
+ hilbert: typeof hilbert;
42
+ };
43
+
44
+ export { angular, circular, hilbert, horizontal, maxArea, minArea, minPerimeter, onion, onionLayers, polygonisation, vertical };
@@ -0,0 +1,310 @@
1
+ import { FillRule, areaD } from 'clipper2-ts';
2
+
3
+ // src/types/vec2.ts
4
+ function cloneVec2(v) {
5
+ return { x: v.x, y: v.y };
6
+ }
7
+ function equalsVec2(a, b, eps = 1e-9) {
8
+ return Math.abs(a.x - b.x) <= eps && Math.abs(a.y - b.y) <= eps;
9
+ }
10
+
11
+ // src/types/path.ts
12
+ function path(rings, closed = true) {
13
+ return {
14
+ rings: rings.map((ring) => ring.map(cloneVec2)),
15
+ closed
16
+ };
17
+ }
18
+ function polygon(exterior, holes = []) {
19
+ return path([exterior, ...holes], true);
20
+ }
21
+ function normalizeRing(ring, eps = 1e-9) {
22
+ if (ring.length < 2) return ring.map(cloneVec2);
23
+ const first = ring[0];
24
+ const last = ring[ring.length - 1];
25
+ if (first && last && equalsVec2(first, last, eps)) {
26
+ return ring.slice(0, -1).map(cloneVec2);
27
+ }
28
+ return ring.map(cloneVec2);
29
+ }
30
+ FillRule.NonZero;
31
+ function ringToPathD(ring) {
32
+ const pts = [];
33
+ for (const v of normalizeRing(ring)) {
34
+ pts.push({ x: v.x, y: v.y, z: 0 });
35
+ }
36
+ return pts;
37
+ }
38
+ function pathToPathsD(p) {
39
+ if (!p.closed || p.rings.length === 0) {
40
+ throw new Error("Boolean ops require a closed path with at least one ring");
41
+ }
42
+ return p.rings.map((ring) => ringToPathD(ring));
43
+ }
44
+ function pathsArea(paths) {
45
+ let sum = 0;
46
+ for (const p of paths) {
47
+ sum += Math.abs(areaD(p));
48
+ }
49
+ return sum;
50
+ }
51
+
52
+ // src/predicates/index.ts
53
+ function ringArea(ring) {
54
+ if (ring.length < 3) return 0;
55
+ let sum = 0;
56
+ for (let i = 0; i < ring.length; i++) {
57
+ const a = ring[i];
58
+ const b = ring[(i + 1) % ring.length];
59
+ sum += a.x * b.y - b.x * a.y;
60
+ }
61
+ return sum / 2;
62
+ }
63
+ function area(p) {
64
+ if (!p.closed || p.rings.length === 0) return 0;
65
+ try {
66
+ return pathsArea(pathToPathsD(p));
67
+ } catch {
68
+ let total = 0;
69
+ for (let i = 0; i < p.rings.length; i++) {
70
+ const a = Math.abs(ringArea(p.rings[i]));
71
+ total += i === 0 ? a : -a;
72
+ }
73
+ return Math.max(0, total);
74
+ }
75
+ }
76
+
77
+ // src/hull/index.ts
78
+ function convexHull(points) {
79
+ const pts = uniquePoints(points);
80
+ if (pts.length < 3) return polygon(pts);
81
+ pts.sort((a, b) => a.x === b.x ? a.y - b.y : a.x - b.x);
82
+ const lower = [];
83
+ for (const p of pts) {
84
+ while (lower.length >= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], p) <= 0) {
85
+ lower.pop();
86
+ }
87
+ lower.push(p);
88
+ }
89
+ const upper = [];
90
+ for (let i = pts.length - 1; i >= 0; i--) {
91
+ const p = pts[i];
92
+ while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], p) <= 0) {
93
+ upper.pop();
94
+ }
95
+ upper.push(p);
96
+ }
97
+ lower.pop();
98
+ upper.pop();
99
+ return polygon([...lower, ...upper]);
100
+ }
101
+ function cross(o, a, b) {
102
+ return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
103
+ }
104
+ function uniquePoints(points) {
105
+ const seen = /* @__PURE__ */ new Set();
106
+ const out = [];
107
+ for (const p of points) {
108
+ const key = `${p.x},${p.y}`;
109
+ if (seen.has(key)) continue;
110
+ seen.add(key);
111
+ out.push({ x: p.x, y: p.y });
112
+ }
113
+ return out;
114
+ }
115
+
116
+ // src/polygonisation/index.ts
117
+ function maxArea(points) {
118
+ return convexHull(points);
119
+ }
120
+ function minArea(points) {
121
+ const hull = convexHull(points).rings[0] ?? [];
122
+ if (hull.length < 3) return convexHull(points);
123
+ if (hull.length === 3) return polygon(hull);
124
+ let best = null;
125
+ let bestA = Infinity;
126
+ const h = hull;
127
+ const n = h.length;
128
+ for (let i = 0; i < n; i++) {
129
+ for (let j = i + 1; j < n; j++) {
130
+ for (let k = j + 1; k < n; k++) {
131
+ const tri = polygon([h[i], h[j], h[k]]);
132
+ if (!coversPoints(tri, points)) continue;
133
+ const a = area(tri);
134
+ if (a < bestA) {
135
+ bestA = a;
136
+ best = tri;
137
+ }
138
+ }
139
+ }
140
+ }
141
+ return best ?? convexHull(points);
142
+ }
143
+ function minPerimeter(points) {
144
+ if (points.length === 0) return polygon([]);
145
+ if (points.length < 3) return polygon(points);
146
+ const remaining = points.map((p) => ({ ...p }));
147
+ const ordered = [remaining.shift()];
148
+ while (remaining.length) {
149
+ const last = ordered[ordered.length - 1];
150
+ let bestI = 0;
151
+ let bestD = Infinity;
152
+ for (let i = 0; i < remaining.length; i++) {
153
+ const d = Math.hypot(
154
+ remaining[i].x - last.x,
155
+ remaining[i].y - last.y
156
+ );
157
+ if (d < bestD) {
158
+ bestD = d;
159
+ bestI = i;
160
+ }
161
+ }
162
+ ordered.push(remaining.splice(bestI, 1)[0]);
163
+ }
164
+ return polygon(ordered);
165
+ }
166
+ function horizontal(points) {
167
+ const pts = [...points].sort(
168
+ (a, b) => a.y === b.y ? a.x - b.x : a.y - b.y
169
+ );
170
+ return polygon(pts);
171
+ }
172
+ function vertical(points) {
173
+ const pts = [...points].sort(
174
+ (a, b) => a.x === b.x ? a.y - b.y : a.x - b.x
175
+ );
176
+ return polygon(pts);
177
+ }
178
+ function angular(points) {
179
+ if (points.length === 0) return polygon([]);
180
+ const c = centroidOf(points);
181
+ const pts = [...points].sort(
182
+ (a, b) => Math.atan2(a.y - c.y, a.x - c.x) - Math.atan2(b.y - c.y, b.x - c.x)
183
+ );
184
+ return polygon(pts);
185
+ }
186
+ function circular(points) {
187
+ return angular(points);
188
+ }
189
+ function onion(points) {
190
+ const layers = onionLayers(points);
191
+ return layers[0] ?? polygon([]);
192
+ }
193
+ function onionLayers(points) {
194
+ let remaining = points.map((p) => ({ ...p }));
195
+ const layers = [];
196
+ while (remaining.length >= 3) {
197
+ const hull = convexHull(remaining);
198
+ const ring = hull.rings[0] ?? [];
199
+ if (ring.length < 3) break;
200
+ layers.push(hull);
201
+ const onHull = new Set(ring.map((v) => `${v.x},${v.y}`));
202
+ remaining = remaining.filter((p) => !onHull.has(`${p.x},${p.y}`));
203
+ }
204
+ return layers;
205
+ }
206
+ function hilbert(points) {
207
+ if (points.length === 0) return polygon([]);
208
+ let minX = Infinity;
209
+ let minY = Infinity;
210
+ let maxX = -Infinity;
211
+ let maxY = -Infinity;
212
+ for (const p of points) {
213
+ minX = Math.min(minX, p.x);
214
+ minY = Math.min(minY, p.y);
215
+ maxX = Math.max(maxX, p.x);
216
+ maxY = Math.max(maxY, p.y);
217
+ }
218
+ const span = Math.max(maxX - minX, maxY - minY, 1e-9);
219
+ const order = 10;
220
+ const n = 1 << order;
221
+ const scored = points.map((p) => {
222
+ const x = Math.min(
223
+ n - 1,
224
+ Math.max(0, Math.floor((p.x - minX) / span * (n - 1)))
225
+ );
226
+ const y = Math.min(
227
+ n - 1,
228
+ Math.max(0, Math.floor((p.y - minY) / span * (n - 1)))
229
+ );
230
+ return { p, h: xy2d(order, x, y) };
231
+ });
232
+ scored.sort((a, b) => a.h - b.h);
233
+ return polygon(scored.map((s) => s.p));
234
+ }
235
+ function coversPoints(poly, points) {
236
+ const r = poly.rings[0];
237
+ if (!r || r.length < 3) return false;
238
+ const a = r[0];
239
+ const b = r[1];
240
+ const c = r[2];
241
+ for (const p of points) {
242
+ if (!pointInTriangle(p, a, b, c)) return false;
243
+ }
244
+ return true;
245
+ }
246
+ function pointInTriangle(p, a, b, c) {
247
+ const v0x = c.x - a.x;
248
+ const v0y = c.y - a.y;
249
+ const v1x = b.x - a.x;
250
+ const v1y = b.y - a.y;
251
+ const v2x = p.x - a.x;
252
+ const v2y = p.y - a.y;
253
+ const dot00 = v0x * v0x + v0y * v0y;
254
+ const dot01 = v0x * v1x + v0y * v1y;
255
+ const dot02 = v0x * v2x + v0y * v2y;
256
+ const dot11 = v1x * v1x + v1y * v1y;
257
+ const dot12 = v1x * v2x + v1y * v2y;
258
+ const inv = 1 / (dot00 * dot11 - dot01 * dot01 || 1e-18);
259
+ const u = (dot11 * dot02 - dot01 * dot12) * inv;
260
+ const v = (dot00 * dot12 - dot01 * dot02) * inv;
261
+ return u >= -1e-9 && v >= -1e-9 && u + v <= 1 + 1e-9;
262
+ }
263
+ function centroidOf(points) {
264
+ let sx = 0;
265
+ let sy = 0;
266
+ for (const p of points) {
267
+ sx += p.x;
268
+ sy += p.y;
269
+ }
270
+ return { x: sx / points.length, y: sy / points.length };
271
+ }
272
+ function xy2d(order, x, y) {
273
+ let rx;
274
+ let ry;
275
+ let s;
276
+ let d = 0;
277
+ for (s = 1 << order - 1; s > 0; s >>= 1) {
278
+ rx = (x & s) > 0 ? 1 : 0;
279
+ ry = (y & s) > 0 ? 1 : 0;
280
+ d += s * s * (3 * rx ^ ry);
281
+ ({ x, y } = rot(s, x, y, rx, ry));
282
+ }
283
+ return d;
284
+ }
285
+ function rot(n, x, y, rx, ry) {
286
+ if (ry === 0) {
287
+ if (rx === 1) {
288
+ x = n - 1 - x;
289
+ y = n - 1 - y;
290
+ }
291
+ return { x: y, y: x };
292
+ }
293
+ return { x, y };
294
+ }
295
+ var polygonisation = {
296
+ maxArea,
297
+ minArea,
298
+ minPerimeter,
299
+ horizontal,
300
+ vertical,
301
+ angular,
302
+ circular,
303
+ onion,
304
+ onionLayers,
305
+ hilbert
306
+ };
307
+
308
+ export { angular, circular, hilbert, horizontal, maxArea, minArea, minPerimeter, onion, onionLayers, polygonisation, vertical };
309
+ //# sourceMappingURL=index.js.map
310
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/vec2.ts","../../src/types/path.ts","../../src/clipper/convert.ts","../../src/predicates/index.ts","../../src/hull/index.ts","../../src/polygonisation/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/** 2D point / vector. */\nexport type Vec2 = {\n x: number\n y: number\n}\n\nexport function vec2(x: number, y: number): Vec2 {\n return { x, y }\n}\n\nexport function cloneVec2(v: Vec2): Vec2 {\n return { x: v.x, y: v.y }\n}\n\nexport function equalsVec2(a: Vec2, b: Vec2, eps = 1e-9): boolean {\n return Math.abs(a.x - b.x) <= eps && Math.abs(a.y - b.y) <= eps\n}\n","import type { Vec2 } from './vec2.js'\nimport { cloneVec2, equalsVec2 } from './vec2.js'\n\n/** Ordered ring of vertices (typically without repeating the closing vertex). */\nexport type Ring = Vec2[]\n\n/**\n * A path: one exterior ring plus optional holes, or an open polyline.\n * `rings[0]` is the exterior (or the open polyline when `closed` is false).\n * Additional rings are holes (only meaningful when `closed` is true).\n */\nexport type Path = {\n rings: Ring[]\n closed: boolean\n}\n\nexport function path(rings: Ring[], closed = true): Path {\n return {\n rings: rings.map((ring) => ring.map(cloneVec2)),\n closed,\n }\n}\n\nexport function polyline(points: Ring): Path {\n return path([points], false)\n}\n\nexport function polygon(exterior: Ring, holes: Ring[] = []): Path {\n return path([exterior, ...holes], true)\n}\n\n/** Drop a trailing vertex that duplicates the first (SVG often closes this way). */\nexport function normalizeRing(ring: Ring, eps = 1e-9): Ring {\n if (ring.length < 2) return ring.map(cloneVec2)\n const first = ring[0]\n const last = ring[ring.length - 1]\n if (first && last && equalsVec2(first, last, eps)) {\n return ring.slice(0, -1).map(cloneVec2)\n }\n return ring.map(cloneVec2)\n}\n\nexport function clonePath(p: Path): Path {\n return {\n closed: p.closed,\n rings: p.rings.map((ring) => ring.map(cloneVec2)),\n }\n}\n","import {\n FillRule,\n areaD,\n differenceD,\n intersectD,\n isPositiveD,\n pointInPolygonD,\n PointInPolygonResult,\n unionD,\n xorD,\n type PathD,\n type PathsD,\n type PointD,\n} from 'clipper2-ts'\nimport type { Group, Path, Ring, Vec2 } from '../types/index.js'\nimport { group, normalizeRing, path, vec2 } from '../types/index.js'\n\nexport const DEFAULT_FILL_RULE = FillRule.NonZero\n\nexport function ringToPathD(ring: Ring): PathD {\n const pts: PointD[] = []\n for (const v of normalizeRing(ring)) {\n pts.push({ x: v.x, y: v.y, z: 0 })\n }\n return pts\n}\n\n/** Closed path → Clipper subject/clip paths (exterior + holes). */\nexport function pathToPathsD(p: Path): PathsD {\n if (!p.closed || p.rings.length === 0) {\n throw new Error('Boolean ops require a closed path with at least one ring')\n }\n return p.rings.map((ring) => ringToPathD(ring))\n}\n\nexport function pathsDToGroup(paths: PathsD): Group {\n if (paths.length === 0) return group([])\n\n const outers: { ring: Ring; holes: Ring[] }[] = []\n const holes: Ring[] = []\n\n for (const pd of paths) {\n const ring = pathDToRing(pd)\n if (ring.length < 3) continue\n if (isPositiveD(pd)) {\n outers.push({ ring, holes: [] })\n } else {\n holes.push(ring)\n }\n }\n\n for (const hole of holes) {\n const sample = hole[0]\n if (!sample) continue\n let assigned = false\n for (const outer of outers) {\n if (pointInRing(sample, outer.ring)) {\n outer.holes.push(hole)\n assigned = true\n break\n }\n }\n if (!assigned) {\n // Treat unmatched negative rings as their own outers (orientation flip).\n outers.push({ ring: [...hole].reverse(), holes: [] })\n }\n }\n\n return group(outers.map((o) => path([o.ring, ...o.holes], true)))\n}\n\nexport function pathDToRing(pd: PathD): Ring {\n return normalizeRing(pd.map((p) => vec2(p.x, p.y)))\n}\n\nexport function pointInRing(point: Vec2, ring: Ring): boolean {\n const result = pointInPolygonD(\n { x: point.x, y: point.y, z: 0 },\n ringToPathD(ring),\n )\n return (\n result === PointInPolygonResult.IsInside ||\n result === PointInPolygonResult.IsOn\n )\n}\n\nexport function clipUnion(a: PathsD, b: PathsD): PathsD {\n return unionD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipIntersect(a: PathsD, b: PathsD): PathsD {\n return intersectD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipDifference(a: PathsD, b: PathsD): PathsD {\n return differenceD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipXor(a: PathsD, b: PathsD): PathsD {\n return xorD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function pathsArea(paths: PathsD): number {\n let sum = 0\n for (const p of paths) {\n sum += Math.abs(areaD(p))\n }\n return sum\n}\n","import type { Group, Path, Vec2 } from '../types/index.js'\nimport { vec2 } from '../types/index.js'\nimport {\n pathToPathsD,\n pathsArea,\n pointInRing,\n} from '../clipper/convert.js'\n\n/** Signed area of a closed ring (shoelace). */\nexport function ringArea(ring: Vec2[]): number {\n if (ring.length < 3) return 0\n let sum = 0\n for (let i = 0; i < ring.length; i++) {\n const a = ring[i]!\n const b = ring[(i + 1) % ring.length]!\n sum += a.x * b.y - b.x * a.y\n }\n return sum / 2\n}\n\n/** Absolute area of a closed path (exterior minus holes). */\nexport function area(p: Path): number {\n if (!p.closed || p.rings.length === 0) return 0\n try {\n return pathsArea(pathToPathsD(p))\n } catch {\n let total = 0\n for (let i = 0; i < p.rings.length; i++) {\n const a = Math.abs(ringArea(p.rings[i]!))\n total += i === 0 ? a : -a\n }\n return Math.max(0, total)\n }\n}\n\nexport function areaGroup(g: Group): number {\n return g.paths.reduce((sum, p) => sum + area(p), 0)\n}\n\n/** Centroid of a closed exterior ring (ignores holes for Phase 2). */\nexport function centroid(p: Path): Vec2 {\n const ring = p.rings[0]\n if (!ring || ring.length === 0) return vec2(0, 0)\n const a = ringArea(ring)\n if (Math.abs(a) < 1e-12) {\n let sx = 0\n let sy = 0\n for (const v of ring) {\n sx += v.x\n sy += v.y\n }\n return vec2(sx / ring.length, sy / ring.length)\n }\n let cx = 0\n let cy = 0\n for (let i = 0; i < ring.length; i++) {\n const p0 = ring[i]!\n const p1 = ring[(i + 1) % ring.length]!\n const cross = p0.x * p1.y - p1.x * p0.y\n cx += (p0.x + p1.x) * cross\n cy += (p0.y + p1.y) * cross\n }\n return vec2(cx / (6 * a), cy / (6 * a))\n}\n\nexport function containsPoint(p: Path, point: Vec2): boolean {\n if (!p.closed || !p.rings[0]) return false\n if (!pointInRing(point, p.rings[0])) return false\n for (let i = 1; i < p.rings.length; i++) {\n const hole = p.rings[i]\n if (hole && pointInRing(point, hole)) return false\n }\n return true\n}\n\nexport function bounds(p: Path): {\n minX: number\n minY: number\n maxX: number\n maxY: number\n} {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const ring of p.rings) {\n for (const v of ring) {\n minX = Math.min(minX, v.x)\n minY = Math.min(minY, v.y)\n maxX = Math.max(maxX, v.x)\n maxY = Math.max(maxY, v.y)\n }\n }\n if (!Number.isFinite(minX)) {\n return { minX: 0, minY: 0, maxX: 0, maxY: 0 }\n }\n return { minX, minY, maxX, maxY }\n}\n\nexport function width(p: Path): number {\n const b = bounds(p)\n return b.maxX - b.minX\n}\n\nexport function height(p: Path): number {\n const b = bounds(p)\n return b.maxY - b.minY\n}\n\n/** Rough polygon similarity via absolute area difference relative to max area. */\nexport function areaSimilarity(a: Path, b: Path): number {\n const aa = area(a)\n const bb = area(b)\n const denom = Math.max(aa, bb, 1e-12)\n return 1 - Math.abs(aa - bb) / denom\n}\n\nexport const predicates = {\n area,\n areaGroup,\n ringArea,\n centroid,\n containsPoint,\n bounds,\n width,\n height,\n areaSimilarity,\n}\n","import type { Path, Vec2 } from '../types/index.js'\nimport { polygon } from '../types/index.js'\nimport { bounds } from '../predicates/index.js'\n\n/** Andrew's monotone-chain convex hull of a point set. */\nexport function convexHull(points: Vec2[]): Path {\n const pts = uniquePoints(points)\n if (pts.length < 3) return polygon(pts)\n\n pts.sort((a, b) => (a.x === b.x ? a.y - b.y : a.x - b.x))\n\n const lower: Vec2[] = []\n for (const p of pts) {\n while (\n lower.length >= 2 &&\n cross(lower[lower.length - 2]!, lower[lower.length - 1]!, p) <= 0\n ) {\n lower.pop()\n }\n lower.push(p)\n }\n\n const upper: Vec2[] = []\n for (let i = pts.length - 1; i >= 0; i--) {\n const p = pts[i]!\n while (\n upper.length >= 2 &&\n cross(upper[upper.length - 2]!, upper[upper.length - 1]!, p) <= 0\n ) {\n upper.pop()\n }\n upper.push(p)\n }\n\n lower.pop()\n upper.pop()\n return polygon([...lower, ...upper])\n}\n\n/** Convex hull of all vertices in a path (exterior + holes). */\nexport function convexHullPath(p: Path): Path {\n const pts: Vec2[] = []\n for (const ring of p.rings) pts.push(...ring)\n return convexHull(pts)\n}\n\n/** Axis-aligned bounding box of a path as a closed rectangle. */\nexport function boundingBox(p: Path): Path {\n const b = bounds(p)\n return polygon([\n { x: b.minX, y: b.minY },\n { x: b.maxX, y: b.minY },\n { x: b.maxX, y: b.maxY },\n { x: b.minX, y: b.maxY },\n ])\n}\n\nfunction cross(o: Vec2, a: Vec2, b: Vec2): number {\n return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x)\n}\n\nfunction uniquePoints(points: Vec2[]): Vec2[] {\n const seen = new Set<string>()\n const out: Vec2[] = []\n for (const p of points) {\n const key = `${p.x},${p.y}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push({ x: p.x, y: p.y })\n }\n return out\n}\n\nexport const hull = {\n convexHull,\n convexHullPath,\n boundingBox,\n}\n","import type { Path, Vec2 } from '../types/index.js'\nimport { polygon } from '../types/index.js'\nimport { convexHull } from '../hull/index.js'\nimport { area } from '../predicates/index.js'\n\n/** Convex hull (largest-area simple polygonisation for a point cloud). */\nexport function maxArea(points: Vec2[]): Path {\n return convexHull(points)\n}\n\n/**\n * Minimum-area triangle covering the points among hull edges\n * (O(h²) rotating-calipers style brute force on hull).\n * Falls back to hull if fewer than 3 hull vertices.\n */\nexport function minArea(points: Vec2[]): Path {\n const hull = convexHull(points).rings[0] ?? []\n if (hull.length < 3) return convexHull(points)\n if (hull.length === 3) return polygon(hull)\n\n let best: Path | null = null\n let bestA = Infinity\n const h = hull\n const n = h.length\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n for (let k = j + 1; k < n; k++) {\n const tri = polygon([h[i]!, h[j]!, h[k]!])\n if (!coversPoints(tri, points)) continue\n const a = area(tri)\n if (a < bestA) {\n bestA = a\n best = tri\n }\n }\n }\n }\n return best ?? convexHull(points)\n}\n\n/** Closed polygon connecting points in order of minimum spanning path heuristic (NN tour). */\nexport function minPerimeter(points: Vec2[]): Path {\n if (points.length === 0) return polygon([])\n if (points.length < 3) return polygon(points)\n const remaining = points.map((p) => ({ ...p }))\n const ordered: Vec2[] = [remaining.shift()!]\n while (remaining.length) {\n const last = ordered[ordered.length - 1]!\n let bestI = 0\n let bestD = Infinity\n for (let i = 0; i < remaining.length; i++) {\n const d = Math.hypot(\n remaining[i]!.x - last.x,\n remaining[i]!.y - last.y,\n )\n if (d < bestD) {\n bestD = d\n bestI = i\n }\n }\n ordered.push(remaining.splice(bestI, 1)[0]!)\n }\n return polygon(ordered)\n}\n\n/** Connect points sorted by x then y. */\nexport function horizontal(points: Vec2[]): Path {\n const pts = [...points].sort((a, b) =>\n a.y === b.y ? a.x - b.x : a.y - b.y,\n )\n return polygon(pts)\n}\n\n/** Connect points sorted by y then x. */\nexport function vertical(points: Vec2[]): Path {\n const pts = [...points].sort((a, b) =>\n a.x === b.x ? a.y - b.y : a.x - b.x,\n )\n return polygon(pts)\n}\n\n/** Connect by polar angle around centroid. */\nexport function angular(points: Vec2[]): Path {\n if (points.length === 0) return polygon([])\n const c = centroidOf(points)\n const pts = [...points].sort(\n (a, b) =>\n Math.atan2(a.y - c.y, a.x - c.x) - Math.atan2(b.y - c.y, b.x - c.x),\n )\n return polygon(pts)\n}\n\n/** Alias of angular. */\nexport function circular(points: Vec2[]): Path {\n return angular(points)\n}\n\n/**\n * Onion layers: successive convex hulls. Returns the outermost hull polygon;\n * use `onionLayers` for all peels.\n */\nexport function onion(points: Vec2[]): Path {\n const layers = onionLayers(points)\n return layers[0] ?? polygon([])\n}\n\n/** Convex onion peels from outside in. */\nexport function onionLayers(points: Vec2[]): Path[] {\n let remaining = points.map((p) => ({ ...p }))\n const layers: Path[] = []\n while (remaining.length >= 3) {\n const hull = convexHull(remaining)\n const ring = hull.rings[0] ?? []\n if (ring.length < 3) break\n layers.push(hull)\n const onHull = new Set(ring.map((v) => `${v.x},${v.y}`))\n remaining = remaining.filter((p) => !onHull.has(`${p.x},${p.y}`))\n }\n return layers\n}\n\n/** Connect points ordered by 2D Hilbert curve index. */\nexport function hilbert(points: Vec2[]): Path {\n if (points.length === 0) return polygon([])\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const p of points) {\n minX = Math.min(minX, p.x)\n minY = Math.min(minY, p.y)\n maxX = Math.max(maxX, p.x)\n maxY = Math.max(maxY, p.y)\n }\n const span = Math.max(maxX - minX, maxY - minY, 1e-9)\n const order = 10\n const n = 1 << order\n const scored = points.map((p) => {\n const x = Math.min(\n n - 1,\n Math.max(0, Math.floor(((p.x - minX) / span) * (n - 1))),\n )\n const y = Math.min(\n n - 1,\n Math.max(0, Math.floor(((p.y - minY) / span) * (n - 1))),\n )\n return { p, h: xy2d(order, x, y) }\n })\n scored.sort((a, b) => a.h - b.h)\n return polygon(scored.map((s) => s.p))\n}\n\nfunction coversPoints(poly: Path, points: Vec2[]): boolean {\n // triangle cover check via barycentric\n const r = poly.rings[0]\n if (!r || r.length < 3) return false\n const a = r[0]!\n const b = r[1]!\n const c = r[2]!\n for (const p of points) {\n if (!pointInTriangle(p, a, b, c)) return false\n }\n return true\n}\n\nfunction pointInTriangle(p: Vec2, a: Vec2, b: Vec2, c: Vec2): boolean {\n const v0x = c.x - a.x\n const v0y = c.y - a.y\n const v1x = b.x - a.x\n const v1y = b.y - a.y\n const v2x = p.x - a.x\n const v2y = p.y - a.y\n const dot00 = v0x * v0x + v0y * v0y\n const dot01 = v0x * v1x + v0y * v1y\n const dot02 = v0x * v2x + v0y * v2y\n const dot11 = v1x * v1x + v1y * v1y\n const dot12 = v1x * v2x + v1y * v2y\n const inv = 1 / (dot00 * dot11 - dot01 * dot01 || 1e-18)\n const u = (dot11 * dot02 - dot01 * dot12) * inv\n const v = (dot00 * dot12 - dot01 * dot02) * inv\n return u >= -1e-9 && v >= -1e-9 && u + v <= 1 + 1e-9\n}\n\nfunction centroidOf(points: Vec2[]): Vec2 {\n let sx = 0\n let sy = 0\n for (const p of points) {\n sx += p.x\n sy += p.y\n }\n return { x: sx / points.length, y: sy / points.length }\n}\n\n/** Hilbert index for (x,y) in [0, 2^order). */\nfunction xy2d(order: number, x: number, y: number): number {\n let rx\n let ry\n let s\n let d = 0\n for (s = 1 << (order - 1); s > 0; s >>= 1) {\n rx = (x & s) > 0 ? 1 : 0\n ry = (y & s) > 0 ? 1 : 0\n d += s * s * ((3 * rx) ^ ry)\n ;({ x, y } = rot(s, x, y, rx, ry))\n }\n return d\n}\n\nfunction rot(\n n: number,\n x: number,\n y: number,\n rx: number,\n ry: number,\n): { x: number; y: number } {\n if (ry === 0) {\n if (rx === 1) {\n x = n - 1 - x\n y = n - 1 - y\n }\n return { x: y, y: x }\n }\n return { x, y }\n}\n\nexport const polygonisation = {\n maxArea,\n minArea,\n minPerimeter,\n horizontal,\n vertical,\n angular,\n circular,\n onion,\n onionLayers,\n hilbert,\n}\n"]}
@@ -0,0 +1,35 @@
1
+ import { V as Vec2 } from '../vec2-CWyXN1Wj.js';
2
+ import { P as Path } from '../path-0RjhYjJs.js';
3
+ import { G as Group } from '../group-BNjVVYSQ.js';
4
+
5
+ /** Signed area of a closed ring (shoelace). */
6
+ declare function ringArea(ring: Vec2[]): number;
7
+ /** Absolute area of a closed path (exterior minus holes). */
8
+ declare function area(p: Path): number;
9
+ declare function areaGroup(g: Group): number;
10
+ /** Centroid of a closed exterior ring (ignores holes for Phase 2). */
11
+ declare function centroid(p: Path): Vec2;
12
+ declare function containsPoint(p: Path, point: Vec2): boolean;
13
+ declare function bounds(p: Path): {
14
+ minX: number;
15
+ minY: number;
16
+ maxX: number;
17
+ maxY: number;
18
+ };
19
+ declare function width(p: Path): number;
20
+ declare function height(p: Path): number;
21
+ /** Rough polygon similarity via absolute area difference relative to max area. */
22
+ declare function areaSimilarity(a: Path, b: Path): number;
23
+ declare const predicates: {
24
+ area: typeof area;
25
+ areaGroup: typeof areaGroup;
26
+ ringArea: typeof ringArea;
27
+ centroid: typeof centroid;
28
+ containsPoint: typeof containsPoint;
29
+ bounds: typeof bounds;
30
+ width: typeof width;
31
+ height: typeof height;
32
+ areaSimilarity: typeof areaSimilarity;
33
+ };
34
+
35
+ export { area, areaGroup, areaSimilarity, bounds, centroid, containsPoint, height, predicates, ringArea, width };