@flighthq/path-boolean 0.1.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.
- package/dist/booleanPaths.d.ts +7 -0
- package/dist/booleanPaths.d.ts.map +1 -0
- package/dist/booleanPaths.js +47 -0
- package/dist/booleanPaths.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/martinezKernel.d.ts +3 -0
- package/dist/martinezKernel.d.ts.map +1 -0
- package/dist/martinezKernel.js +625 -0
- package/dist/martinezKernel.js.map +1 -0
- package/dist/offsetPath.d.ts +3 -0
- package/dist/offsetPath.d.ts.map +1 -0
- package/dist/offsetPath.js +318 -0
- package/dist/offsetPath.js.map +1 -0
- package/dist/pathBooleanBackend.d.ts +5 -0
- package/dist/pathBooleanBackend.d.ts.map +1 -0
- package/dist/pathBooleanBackend.js +24 -0
- package/dist/pathBooleanBackend.js.map +1 -0
- package/dist/resolvePathRegions.d.ts +3 -0
- package/dist/resolvePathRegions.d.ts.map +1 -0
- package/dist/resolvePathRegions.js +28 -0
- package/dist/resolvePathRegions.js.map +1 -0
- package/dist/simplifyPath.d.ts +3 -0
- package/dist/simplifyPath.d.ts.map +1 -0
- package/dist/simplifyPath.js +16 -0
- package/dist/simplifyPath.js.map +1 -0
- package/dist/unionAllPaths.d.ts +3 -0
- package/dist/unionAllPaths.d.ts.map +1 -0
- package/dist/unionAllPaths.js +35 -0
- package/dist/unionAllPaths.js.map +1 -0
- package/package.json +38 -0
- package/src/booleanPaths.test.ts +163 -0
- package/src/fuzzInvariants.test.ts +203 -0
- package/src/martinezKernel.test.ts +376 -0
- package/src/offsetPath.test.ts +223 -0
- package/src/pathBooleanBackend.test.ts +50 -0
- package/src/resolvePathRegions.test.ts +48 -0
- package/src/simplifyPath.test.ts +146 -0
- package/src/unionAllPaths.test.ts +92 -0
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
// Builds the default boolean kernel: a from-scratch, floating-point Martinez–Rueda–Feito sweep-line.
|
|
2
|
+
//
|
|
3
|
+
// The pipeline runs in two stages, deliberately separated so the correctness-critical classification
|
|
4
|
+
// never races the arrangement construction:
|
|
5
|
+
//
|
|
6
|
+
// 1. Arrangement (the sweep). An event priority queue holds the left/right endpoint events of every
|
|
7
|
+
// input edge. Sweeping left-to-right maintains a status of the active segments ordered by their y
|
|
8
|
+
// at the sweep; each segment is only ever tested for intersection against its immediate status
|
|
9
|
+
// neighbors. A proper crossing splits both segments at the crossing point; a collinear overlap
|
|
10
|
+
// splits each at the other's interior endpoints so the shared span becomes geometrically identical
|
|
11
|
+
// sub-segments. When a segment's right endpoint is reached it is final and recorded.
|
|
12
|
+
// 2. Classification + assembly (a static pass over the final segments). Coincident sub-segments are
|
|
13
|
+
// merged by geometry, summing each operand's winding contribution. Every unique segment is then
|
|
14
|
+
// classified by the winding number just below vs just above it (a downward ray from its midpoint),
|
|
15
|
+
// under the fill rule, for the operation — the boundary test. In-result segments are oriented so
|
|
16
|
+
// the kept region lies on their left and traced into closed rings.
|
|
17
|
+
//
|
|
18
|
+
// Handling coincidence in the static pass rather than mid-sweep is the key robustness decision: winding
|
|
19
|
+
// deltas are all final before any membership is computed, so both fill rules and both same/opposite
|
|
20
|
+
// edge orientations fall out of the same arithmetic with no field-staleness. It trades the classic
|
|
21
|
+
// algorithm's O(n log n) inline classification for an O(n²) post-pass, which is the right call for a
|
|
22
|
+
// correctness-first kernel on the modest polygon sizes booleans see.
|
|
23
|
+
export function createMartinezPathBooleanBackend() {
|
|
24
|
+
return {
|
|
25
|
+
computePathBoolean(subject, clip, operation, fillRule) {
|
|
26
|
+
return computeMartinezBoolean(subject, clip, operation, fillRule);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
// Relative factor for the vertex-merge grid: two vertices collapse to one when they fall in the same
|
|
31
|
+
// cell of a grid this fraction of the input's coordinate extent. Large enough to catch the last-bit
|
|
32
|
+
// numerical twins a crossing computation produces (a few ulps of the extent), far below any real
|
|
33
|
+
// feature separation, so it only ever fuses points that were meant to be identical. Made relative to
|
|
34
|
+
// the coordinate magnitude (rather than a fixed absolute) so the same topology resolves whether the
|
|
35
|
+
// polygon is expressed in pixels, metres, or micrometres.
|
|
36
|
+
const VERTEX_SNAP_RELATIVE = 1e-9;
|
|
37
|
+
// Fallback absolute snap for degenerate all-coincident input where the extent is zero; no segments
|
|
38
|
+
// survive such input, so the exact value only guards the division in `snap`.
|
|
39
|
+
const VERTEX_SNAP_FALLBACK = 1e-9;
|
|
40
|
+
// Relative tolerance for the intersection orientation tests, scaled by squared edge lengths in each
|
|
41
|
+
// comparison so it already behaves consistently across coordinate magnitudes.
|
|
42
|
+
const INTERSECTION_EPS = 1e-12;
|
|
43
|
+
let nextEventId = 0;
|
|
44
|
+
// The active vertex-merge grid cell size for the boolean currently being computed, derived from the
|
|
45
|
+
// input's coordinate extent at the top of `computeMartinezBoolean`. Module-scoped rather than threaded
|
|
46
|
+
// through every `approxEqual`/`snap` call (the computation is synchronous and single-entrant, like
|
|
47
|
+
// `nextEventId`); it is never read at import time, so importing the package stays side-effect-free.
|
|
48
|
+
let vertexSnap = VERTEX_SNAP_FALLBACK;
|
|
49
|
+
function computeMartinezBoolean(subject, clip, operation, fillRule) {
|
|
50
|
+
nextEventId = 0;
|
|
51
|
+
vertexSnap = computeVertexSnap(subject, clip);
|
|
52
|
+
const segments = buildArrangement(subject, clip);
|
|
53
|
+
if (segments.length === 0)
|
|
54
|
+
return [];
|
|
55
|
+
const unique = mergeCoincidentSegments(segments);
|
|
56
|
+
const kept = classifySegments(unique, operation, fillRule);
|
|
57
|
+
if (kept.length === 0)
|
|
58
|
+
return [];
|
|
59
|
+
return traceRings(kept);
|
|
60
|
+
}
|
|
61
|
+
// Stage 1: the sweep. Returns every final (non-crossing, non-overlapping) segment of the combined
|
|
62
|
+
// subject+clip arrangement.
|
|
63
|
+
function buildArrangement(subject, clip) {
|
|
64
|
+
const heap = new EventHeap();
|
|
65
|
+
fillQueue(subject, true, heap);
|
|
66
|
+
fillQueue(clip, false, heap);
|
|
67
|
+
const status = [];
|
|
68
|
+
const segments = [];
|
|
69
|
+
while (!heap.isEmpty()) {
|
|
70
|
+
const event = heap.pop();
|
|
71
|
+
if (event.left) {
|
|
72
|
+
const index = insertStatus(status, event);
|
|
73
|
+
const prev = index > 0 ? status[index - 1] : null;
|
|
74
|
+
const next = index < status.length - 1 ? status[index + 1] : null;
|
|
75
|
+
if (next !== null)
|
|
76
|
+
possibleIntersection(event, next, heap);
|
|
77
|
+
if (prev !== null)
|
|
78
|
+
possibleIntersection(prev, event, heap);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const leftEvent = event.otherEvent;
|
|
82
|
+
const index = findStatus(status, leftEvent);
|
|
83
|
+
if (index !== -1) {
|
|
84
|
+
const prev = index > 0 ? status[index - 1] : null;
|
|
85
|
+
const next = index < status.length - 1 ? status[index + 1] : null;
|
|
86
|
+
status.splice(index, 1);
|
|
87
|
+
if (prev !== null && next !== null)
|
|
88
|
+
possibleIntersection(prev, next, heap);
|
|
89
|
+
}
|
|
90
|
+
recordSegment(leftEvent, event, segments);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return segments;
|
|
94
|
+
}
|
|
95
|
+
function recordSegment(leftEvent, rightEvent, segments) {
|
|
96
|
+
if (!leftEvent.left)
|
|
97
|
+
return;
|
|
98
|
+
if (approxEqual(leftEvent.x, rightEvent.x) && approxEqual(leftEvent.y, rightEvent.y))
|
|
99
|
+
return;
|
|
100
|
+
segments.push({
|
|
101
|
+
ax: leftEvent.x,
|
|
102
|
+
ay: leftEvent.y,
|
|
103
|
+
bx: rightEvent.x,
|
|
104
|
+
by: rightEvent.y,
|
|
105
|
+
isSubject: leftEvent.isSubject,
|
|
106
|
+
windingDelta: leftEvent.windingDelta,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
// Appends every edge of every contour as a left/right event pair. A trailing vertex repeating the first
|
|
110
|
+
// (flattenPath appends one on CLOSE) is dropped; zero-length edges are skipped.
|
|
111
|
+
function fillQueue(contours, isSubject, heap) {
|
|
112
|
+
for (const contour of contours) {
|
|
113
|
+
let count = contour.length >> 1;
|
|
114
|
+
if (count < 2)
|
|
115
|
+
continue;
|
|
116
|
+
if (approxEqual(contour[0], contour[(count - 1) * 2]) && approxEqual(contour[1], contour[(count - 1) * 2 + 1])) {
|
|
117
|
+
count -= 1;
|
|
118
|
+
}
|
|
119
|
+
if (count < 3)
|
|
120
|
+
continue;
|
|
121
|
+
for (let i = 0; i < count; i++) {
|
|
122
|
+
const ax = contour[i * 2];
|
|
123
|
+
const ay = contour[i * 2 + 1];
|
|
124
|
+
const j = (i + 1) % count;
|
|
125
|
+
const bx = contour[j * 2];
|
|
126
|
+
const by = contour[j * 2 + 1];
|
|
127
|
+
if (approxEqual(ax, bx) && approxEqual(ay, by))
|
|
128
|
+
continue;
|
|
129
|
+
addEdge(ax, ay, bx, by, isSubject, heap);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function addEdge(ax, ay, bx, by, isSubject, heap) {
|
|
134
|
+
const a = createEvent(ax, ay, isSubject);
|
|
135
|
+
const b = createEvent(bx, by, isSubject);
|
|
136
|
+
a.otherEvent = b;
|
|
137
|
+
b.otherEvent = a;
|
|
138
|
+
if (pointOrder(ax, ay, bx, by) < 0) {
|
|
139
|
+
a.left = true;
|
|
140
|
+
a.windingDelta = 1;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
b.left = true;
|
|
144
|
+
b.windingDelta = -1;
|
|
145
|
+
}
|
|
146
|
+
heap.push(a);
|
|
147
|
+
heap.push(b);
|
|
148
|
+
}
|
|
149
|
+
function createEvent(x, y, isSubject) {
|
|
150
|
+
return {
|
|
151
|
+
x,
|
|
152
|
+
y,
|
|
153
|
+
left: false,
|
|
154
|
+
otherEvent: null,
|
|
155
|
+
isSubject,
|
|
156
|
+
id: nextEventId++,
|
|
157
|
+
windingDelta: 0,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
// Reshapes the arrangement so two status-neighbor segments only ever meet at shared endpoints.
|
|
161
|
+
function possibleIntersection(le1, le2, heap) {
|
|
162
|
+
const inter = segmentIntersection(le1.x, le1.y, le1.otherEvent.x, le1.otherEvent.y, le2.x, le2.y, le2.otherEvent.x, le2.otherEvent.y);
|
|
163
|
+
if (inter === null)
|
|
164
|
+
return;
|
|
165
|
+
if (inter.length === 1) {
|
|
166
|
+
const ix = inter[0][0];
|
|
167
|
+
const iy = inter[0][1];
|
|
168
|
+
if (!pointOnEndpoint(le1, ix, iy))
|
|
169
|
+
divideSegment(le1, ix, iy, heap);
|
|
170
|
+
if (!pointOnEndpoint(le2, ix, iy))
|
|
171
|
+
divideSegment(le2, ix, iy, heap);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
// Collinear overlap: split each segment at the other's strictly-interior endpoints. Remaining overlap
|
|
175
|
+
// on the freshly-created halves is resolved when those halves become status neighbors and are tested.
|
|
176
|
+
divideIfInterior(le1, le2.x, le2.y, heap);
|
|
177
|
+
divideIfInterior(le1, le2.otherEvent.x, le2.otherEvent.y, heap);
|
|
178
|
+
divideIfInterior(le2, le1.x, le1.y, heap);
|
|
179
|
+
divideIfInterior(le2, le1.otherEvent.x, le1.otherEvent.y, heap);
|
|
180
|
+
}
|
|
181
|
+
function divideIfInterior(le, x, y, heap) {
|
|
182
|
+
if (pointStrictlyInside(le.x, le.y, le.otherEvent.x, le.otherEvent.y, x, y))
|
|
183
|
+
divideSegment(le, x, y, heap);
|
|
184
|
+
}
|
|
185
|
+
// Splits `le` at interior point (x, y): the left half keeps `le` as its left endpoint; a fresh left
|
|
186
|
+
// event opens the right half. Both halves inherit the ring orientation, so their winding deltas match.
|
|
187
|
+
function divideSegment(le, x, y, heap) {
|
|
188
|
+
const right = le.otherEvent;
|
|
189
|
+
const newRight = createEvent(x, y, le.isSubject);
|
|
190
|
+
const newLeft = createEvent(x, y, le.isSubject);
|
|
191
|
+
newRight.left = false;
|
|
192
|
+
newRight.otherEvent = le;
|
|
193
|
+
newLeft.left = true;
|
|
194
|
+
newLeft.otherEvent = right;
|
|
195
|
+
newLeft.windingDelta = le.windingDelta;
|
|
196
|
+
le.otherEvent = newRight;
|
|
197
|
+
right.otherEvent = newLeft;
|
|
198
|
+
heap.push(newLeft);
|
|
199
|
+
heap.push(newRight);
|
|
200
|
+
}
|
|
201
|
+
function pointOnEndpoint(le, x, y) {
|
|
202
|
+
return ((approxEqual(le.x, x) && approxEqual(le.y, y)) ||
|
|
203
|
+
(approxEqual(le.otherEvent.x, x) && approxEqual(le.otherEvent.y, y)));
|
|
204
|
+
}
|
|
205
|
+
function pointStrictlyInside(lx, ly, rx, ry, x, y) {
|
|
206
|
+
if ((approxEqual(lx, x) && approxEqual(ly, y)) || (approxEqual(rx, x) && approxEqual(ry, y)))
|
|
207
|
+
return false;
|
|
208
|
+
const cross = (rx - lx) * (y - ly) - (ry - ly) * (x - lx);
|
|
209
|
+
const lenSq = (rx - lx) * (rx - lx) + (ry - ly) * (ry - ly);
|
|
210
|
+
if (cross * cross > INTERSECTION_EPS * lenSq * lenSq)
|
|
211
|
+
return false;
|
|
212
|
+
const dot = (x - lx) * (rx - lx) + (y - ly) * (ry - ly);
|
|
213
|
+
return dot > 0 && dot < lenSq;
|
|
214
|
+
}
|
|
215
|
+
// Sweep-line status: a sorted array. Because segments are subdivided at every crossing they never swap
|
|
216
|
+
// order once inserted, so a plain insertion order stays valid.
|
|
217
|
+
function insertStatus(status, event) {
|
|
218
|
+
let lo = 0;
|
|
219
|
+
let hi = status.length;
|
|
220
|
+
while (lo < hi) {
|
|
221
|
+
const mid = (lo + hi) >> 1;
|
|
222
|
+
if (compareSegments(status[mid], event) < 0)
|
|
223
|
+
lo = mid + 1;
|
|
224
|
+
else
|
|
225
|
+
hi = mid;
|
|
226
|
+
}
|
|
227
|
+
status.splice(lo, 0, event);
|
|
228
|
+
return lo;
|
|
229
|
+
}
|
|
230
|
+
function findStatus(status, event) {
|
|
231
|
+
for (let i = 0; i < status.length; i++)
|
|
232
|
+
if (status[i] === event)
|
|
233
|
+
return i;
|
|
234
|
+
return -1;
|
|
235
|
+
}
|
|
236
|
+
// Orders two active segments by vertical position at the sweep (Martinez segment comparator). Uses
|
|
237
|
+
// exact comparisons throughout so the order is a consistent total order — a non-transitive tolerant
|
|
238
|
+
// comparator would corrupt the sorted status.
|
|
239
|
+
function compareSegments(le1, le2) {
|
|
240
|
+
if (le1 === le2)
|
|
241
|
+
return 0;
|
|
242
|
+
const a1x = le1.x;
|
|
243
|
+
const a1y = le1.y;
|
|
244
|
+
const a2x = le1.otherEvent.x;
|
|
245
|
+
const a2y = le1.otherEvent.y;
|
|
246
|
+
const s1 = signedArea(a1x, a1y, a2x, a2y, le2.x, le2.y);
|
|
247
|
+
const s2 = signedArea(a1x, a1y, a2x, a2y, le2.otherEvent.x, le2.otherEvent.y);
|
|
248
|
+
if (s1 !== 0 || s2 !== 0) {
|
|
249
|
+
if (a1x === le2.x && a1y === le2.y)
|
|
250
|
+
return isBelow(le1, le2.otherEvent.x, le2.otherEvent.y) ? -1 : 1;
|
|
251
|
+
if (a1x === le2.x)
|
|
252
|
+
return a1y < le2.y ? -1 : 1;
|
|
253
|
+
if (compareEvents(le1, le2) === 1)
|
|
254
|
+
return isBelow(le2, a1x, a1y) ? 1 : -1;
|
|
255
|
+
return isBelow(le1, le2.x, le2.y) ? -1 : 1;
|
|
256
|
+
}
|
|
257
|
+
if (le1.isSubject !== le2.isSubject)
|
|
258
|
+
return le1.isSubject ? -1 : 1;
|
|
259
|
+
if (a1x === le2.x && a1y === le2.y)
|
|
260
|
+
return le1.id < le2.id ? -1 : 1;
|
|
261
|
+
return compareEvents(le1, le2) === 1 ? 1 : -1;
|
|
262
|
+
}
|
|
263
|
+
// True when segment `le` passes strictly below point (x, y).
|
|
264
|
+
function isBelow(le, x, y) {
|
|
265
|
+
return le.left
|
|
266
|
+
? signedArea(le.x, le.y, le.otherEvent.x, le.otherEvent.y, x, y) > 0
|
|
267
|
+
: signedArea(le.otherEvent.x, le.otherEvent.y, le.x, le.y, x, y) > 0;
|
|
268
|
+
}
|
|
269
|
+
// Priority order of two events: by x, then y, then right-endpoint-before-left, then by slope, then a
|
|
270
|
+
// stable operand/id tiebreak. Returns -1 when e1 is processed first. Exact comparisons only.
|
|
271
|
+
function compareEvents(e1, e2) {
|
|
272
|
+
if (e1.x !== e2.x)
|
|
273
|
+
return e1.x < e2.x ? -1 : 1;
|
|
274
|
+
if (e1.y !== e2.y)
|
|
275
|
+
return e1.y < e2.y ? -1 : 1;
|
|
276
|
+
if (e1 === e2)
|
|
277
|
+
return 0;
|
|
278
|
+
if (e1.left !== e2.left)
|
|
279
|
+
return e1.left ? 1 : -1;
|
|
280
|
+
const area = signedArea(e1.x, e1.y, e1.otherEvent.x, e1.otherEvent.y, e2.otherEvent.x, e2.otherEvent.y);
|
|
281
|
+
if (area !== 0)
|
|
282
|
+
return isBelow(e1, e2.otherEvent.x, e2.otherEvent.y) ? -1 : 1;
|
|
283
|
+
if (e1.isSubject !== e2.isSubject)
|
|
284
|
+
return e1.isSubject ? -1 : 1;
|
|
285
|
+
return e1.id < e2.id ? -1 : 1;
|
|
286
|
+
}
|
|
287
|
+
function pointOrder(ax, ay, bx, by) {
|
|
288
|
+
if (ax < bx)
|
|
289
|
+
return -1;
|
|
290
|
+
if (ax > bx)
|
|
291
|
+
return 1;
|
|
292
|
+
if (ay < by)
|
|
293
|
+
return -1;
|
|
294
|
+
if (ay > by)
|
|
295
|
+
return 1;
|
|
296
|
+
return 0;
|
|
297
|
+
}
|
|
298
|
+
// > 0 when (p0, p1, p2) turn counterclockwise in math (y-up) orientation.
|
|
299
|
+
function signedArea(p0x, p0y, p1x, p1y, p2x, p2y) {
|
|
300
|
+
return (p0x - p2x) * (p1y - p2y) - (p1x - p2x) * (p0y - p2y);
|
|
301
|
+
}
|
|
302
|
+
// Returns null, a single intersection point, or the two endpoints of a collinear overlap.
|
|
303
|
+
function segmentIntersection(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) {
|
|
304
|
+
const vax = a2x - a1x;
|
|
305
|
+
const vay = a2y - a1y;
|
|
306
|
+
const vbx = b2x - b1x;
|
|
307
|
+
const vby = b2y - b1y;
|
|
308
|
+
const ex = b1x - a1x;
|
|
309
|
+
const ey = b1y - a1y;
|
|
310
|
+
const kross = vax * vby - vay * vbx;
|
|
311
|
+
const sqrKross = kross * kross;
|
|
312
|
+
const sqrLenA = vax * vax + vay * vay;
|
|
313
|
+
const sqrLenB = vbx * vbx + vby * vby;
|
|
314
|
+
if (sqrKross > INTERSECTION_EPS * sqrLenA * sqrLenB) {
|
|
315
|
+
const s = (ex * vby - ey * vbx) / kross;
|
|
316
|
+
if (s < 0 || s > 1)
|
|
317
|
+
return null;
|
|
318
|
+
const t = (ex * vay - ey * vax) / kross;
|
|
319
|
+
if (t < 0 || t > 1)
|
|
320
|
+
return null;
|
|
321
|
+
return [[a1x + s * vax, a1y + s * vay]];
|
|
322
|
+
}
|
|
323
|
+
const krossE = ex * vay - ey * vax;
|
|
324
|
+
if (krossE * krossE > INTERSECTION_EPS * sqrLenA * (ex * ex + ey * ey))
|
|
325
|
+
return null;
|
|
326
|
+
const sa = (ex * vax + ey * vay) / sqrLenA;
|
|
327
|
+
const sb = sa + (vbx * vax + vby * vay) / sqrLenA;
|
|
328
|
+
const lo = Math.max(0, Math.min(sa, sb));
|
|
329
|
+
const hi = Math.min(1, Math.max(sa, sb));
|
|
330
|
+
if (lo > hi + 1e-12)
|
|
331
|
+
return null;
|
|
332
|
+
if (Math.abs(lo - hi) <= 1e-12)
|
|
333
|
+
return [[a1x + lo * vax, a1y + lo * vay]];
|
|
334
|
+
return [
|
|
335
|
+
[a1x + lo * vax, a1y + lo * vay],
|
|
336
|
+
[a1x + hi * vax, a1y + hi * vay],
|
|
337
|
+
];
|
|
338
|
+
}
|
|
339
|
+
// Stage 2a: fold coincident final segments into one, summing each operand's winding contribution. The
|
|
340
|
+
// key normalizes endpoints to lexicographic order, matching the way `addEdge` measures windingDelta, so
|
|
341
|
+
// deltas from opposite-direction coincident edges cancel.
|
|
342
|
+
function mergeCoincidentSegments(segments) {
|
|
343
|
+
const map = new Map();
|
|
344
|
+
for (const seg of segments) {
|
|
345
|
+
let ax = seg.ax;
|
|
346
|
+
let ay = seg.ay;
|
|
347
|
+
let bx = seg.bx;
|
|
348
|
+
let by = seg.by;
|
|
349
|
+
if (pointOrder(ax, ay, bx, by) > 0) {
|
|
350
|
+
ax = seg.bx;
|
|
351
|
+
ay = seg.by;
|
|
352
|
+
bx = seg.ax;
|
|
353
|
+
by = seg.ay;
|
|
354
|
+
}
|
|
355
|
+
const key = `${snap(ax)},${snap(ay)},${snap(bx)},${snap(by)}`;
|
|
356
|
+
let unique = map.get(key);
|
|
357
|
+
if (unique === undefined) {
|
|
358
|
+
unique = { ax, ay, bx, by, subjectDelta: 0, clipDelta: 0 };
|
|
359
|
+
map.set(key, unique);
|
|
360
|
+
}
|
|
361
|
+
if (seg.isSubject)
|
|
362
|
+
unique.subjectDelta += seg.windingDelta;
|
|
363
|
+
else
|
|
364
|
+
unique.clipDelta += seg.windingDelta;
|
|
365
|
+
}
|
|
366
|
+
return [...map.values()];
|
|
367
|
+
}
|
|
368
|
+
// Stage 2b: classify each unique segment by the boundary test, orienting kept segments so the retained
|
|
369
|
+
// region sits on the segment's left. Returns directed edges [fromX, fromY, toX, toY].
|
|
370
|
+
//
|
|
371
|
+
// Membership is sampled at two points a hair off each side of the segment's midpoint, perpendicular to
|
|
372
|
+
// it, and the winding of each operand at those points is found by a downward ray. Sampling
|
|
373
|
+
// perpendicular to the edge (rather than straight up/down) is what makes vertical and horizontal edges
|
|
374
|
+
// classify correctly — a purely y-based below/above test is degenerate for vertical edges.
|
|
375
|
+
function classifySegments(unique, operation, fillRule) {
|
|
376
|
+
const kept = [];
|
|
377
|
+
for (const seg of unique) {
|
|
378
|
+
const mx = (seg.ax + seg.bx) / 2;
|
|
379
|
+
const my = (seg.ay + seg.by) / 2;
|
|
380
|
+
const dx = seg.bx - seg.ax;
|
|
381
|
+
const dy = seg.by - seg.ay;
|
|
382
|
+
const len = Math.hypot(dx, dy);
|
|
383
|
+
if (len === 0)
|
|
384
|
+
continue;
|
|
385
|
+
// Left normal of the lex-ordered direction A→B (math y-up: rotate +90°). Offset well inside the
|
|
386
|
+
// segment's own clear zone — other segments only meet it at its endpoints.
|
|
387
|
+
const eps = len * 1e-4;
|
|
388
|
+
const nlx = (-dy / len) * eps;
|
|
389
|
+
const nly = (dx / len) * eps;
|
|
390
|
+
const leftInSubject = isInside(windingAt(unique, mx + nlx, my + nly, true), fillRule);
|
|
391
|
+
const leftInClip = isInside(windingAt(unique, mx + nlx, my + nly, false), fillRule);
|
|
392
|
+
const rightInSubject = isInside(windingAt(unique, mx - nlx, my - nly, true), fillRule);
|
|
393
|
+
const rightInClip = isInside(windingAt(unique, mx - nlx, my - nly, false), fillRule);
|
|
394
|
+
const filledLeft = combine(operation, leftInSubject, leftInClip);
|
|
395
|
+
const filledRight = combine(operation, rightInSubject, rightInClip);
|
|
396
|
+
if (filledLeft === filledRight)
|
|
397
|
+
continue;
|
|
398
|
+
// Direct the edge so the kept region is on its left.
|
|
399
|
+
if (filledLeft)
|
|
400
|
+
kept.push([seg.ax, seg.ay, seg.bx, seg.by]);
|
|
401
|
+
else
|
|
402
|
+
kept.push([seg.bx, seg.by, seg.ax, seg.ay]);
|
|
403
|
+
}
|
|
404
|
+
return kept;
|
|
405
|
+
}
|
|
406
|
+
// Winding number of one operand at (px, py): the signed sum of the winding deltas of every segment that
|
|
407
|
+
// the downward vertical ray from the point crosses (a segment strictly spanning px whose y at px lies
|
|
408
|
+
// below py).
|
|
409
|
+
function windingAt(unique, px, py, subject) {
|
|
410
|
+
let winding = 0;
|
|
411
|
+
for (const v of unique) {
|
|
412
|
+
const lox = Math.min(v.ax, v.bx);
|
|
413
|
+
const hix = Math.max(v.ax, v.bx);
|
|
414
|
+
// Half-open x-interval so a ray passing exactly through a shared vertex counts exactly one of the
|
|
415
|
+
// two edges meeting there (the one that starts at px, not the one that ends at it).
|
|
416
|
+
if (px < lox || px >= hix)
|
|
417
|
+
continue;
|
|
418
|
+
const t = (px - v.ax) / (v.bx - v.ax);
|
|
419
|
+
const yAt = v.ay + t * (v.by - v.ay);
|
|
420
|
+
if (yAt < py)
|
|
421
|
+
winding += subject ? v.subjectDelta : v.clipDelta;
|
|
422
|
+
}
|
|
423
|
+
return winding;
|
|
424
|
+
}
|
|
425
|
+
function combine(operation, inSubject, inClip) {
|
|
426
|
+
switch (operation) {
|
|
427
|
+
case 'union':
|
|
428
|
+
return inSubject || inClip;
|
|
429
|
+
case 'intersection':
|
|
430
|
+
return inSubject && inClip;
|
|
431
|
+
case 'difference':
|
|
432
|
+
return inSubject && !inClip;
|
|
433
|
+
case 'xor':
|
|
434
|
+
return inSubject !== inClip;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function isInside(winding, fillRule) {
|
|
438
|
+
switch (fillRule) {
|
|
439
|
+
case 'evenOdd':
|
|
440
|
+
return (Math.abs(winding) & 1) === 1;
|
|
441
|
+
case 'positive':
|
|
442
|
+
return winding > 0;
|
|
443
|
+
case 'negative':
|
|
444
|
+
return winding < 0;
|
|
445
|
+
default:
|
|
446
|
+
return winding !== 0;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
// Stage 2c: chain the directed, fill-on-left edges into closed rings. At a vertex shared by several
|
|
450
|
+
// rings, the next edge is the one turning most clockwise from the reversed incoming direction, which
|
|
451
|
+
// keeps the retained region continuously on the left.
|
|
452
|
+
function traceRings(edges) {
|
|
453
|
+
const graph = new DirectedGraph();
|
|
454
|
+
for (const e of edges)
|
|
455
|
+
graph.addEdge(e[0], e[1], e[2], e[3]);
|
|
456
|
+
return graph.traceRings();
|
|
457
|
+
}
|
|
458
|
+
function approxEqual(a, b) {
|
|
459
|
+
return Math.abs(a - b) <= vertexSnap;
|
|
460
|
+
}
|
|
461
|
+
// Derives the vertex-merge grid size from the largest coordinate span across both operands, so the
|
|
462
|
+
// snap tolerance tracks the input's magnitude. Zero/degenerate extent falls back to a fixed absolute.
|
|
463
|
+
function computeVertexSnap(subject, clip) {
|
|
464
|
+
let minX = Infinity;
|
|
465
|
+
let minY = Infinity;
|
|
466
|
+
let maxX = -Infinity;
|
|
467
|
+
let maxY = -Infinity;
|
|
468
|
+
for (const contours of [subject, clip]) {
|
|
469
|
+
for (const contour of contours) {
|
|
470
|
+
for (let i = 0; i < contour.length; i += 2) {
|
|
471
|
+
const x = contour[i];
|
|
472
|
+
const y = contour[i + 1];
|
|
473
|
+
if (x < minX)
|
|
474
|
+
minX = x;
|
|
475
|
+
if (x > maxX)
|
|
476
|
+
maxX = x;
|
|
477
|
+
if (y < minY)
|
|
478
|
+
minY = y;
|
|
479
|
+
if (y > maxY)
|
|
480
|
+
maxY = y;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
const extent = Math.max(maxX - minX, maxY - minY);
|
|
485
|
+
return extent > 0 ? extent * VERTEX_SNAP_RELATIVE : VERTEX_SNAP_FALLBACK;
|
|
486
|
+
}
|
|
487
|
+
function snap(v) {
|
|
488
|
+
return Math.round(v / vertexSnap);
|
|
489
|
+
}
|
|
490
|
+
// Directed graph of the kept boundary edges. Each directed edge is consumed once; ring closure and
|
|
491
|
+
// vertex sharing are handled by angular next-edge selection.
|
|
492
|
+
class DirectedGraph {
|
|
493
|
+
keys = new Map();
|
|
494
|
+
xs = [];
|
|
495
|
+
ys = [];
|
|
496
|
+
outgoing = [];
|
|
497
|
+
edgeTo = [];
|
|
498
|
+
edgeFrom = [];
|
|
499
|
+
used = [];
|
|
500
|
+
addEdge(fromX, fromY, toX, toY) {
|
|
501
|
+
const from = this.vertex(fromX, fromY);
|
|
502
|
+
const to = this.vertex(toX, toY);
|
|
503
|
+
if (from === to)
|
|
504
|
+
return;
|
|
505
|
+
const edge = this.edgeFrom.length;
|
|
506
|
+
this.edgeFrom.push(from);
|
|
507
|
+
this.edgeTo.push(to);
|
|
508
|
+
this.used.push(false);
|
|
509
|
+
this.outgoing[from].push(edge);
|
|
510
|
+
}
|
|
511
|
+
traceRings() {
|
|
512
|
+
const rings = [];
|
|
513
|
+
for (let start = 0; start < this.edgeFrom.length; start++) {
|
|
514
|
+
if (this.used[start])
|
|
515
|
+
continue;
|
|
516
|
+
const ring = this.walk(start);
|
|
517
|
+
if (ring !== null && ring.length >= 6)
|
|
518
|
+
rings.push(ring);
|
|
519
|
+
}
|
|
520
|
+
return rings;
|
|
521
|
+
}
|
|
522
|
+
walk(startEdge) {
|
|
523
|
+
const ring = [];
|
|
524
|
+
let edge = startEdge;
|
|
525
|
+
let guard = 0;
|
|
526
|
+
const limit = this.edgeFrom.length + 2;
|
|
527
|
+
while (guard++ < limit) {
|
|
528
|
+
this.used[edge] = true;
|
|
529
|
+
const from = this.edgeFrom[edge];
|
|
530
|
+
ring.push(this.xs[from], this.ys[from]);
|
|
531
|
+
const to = this.edgeTo[edge];
|
|
532
|
+
const next = this.nextEdge(to, from);
|
|
533
|
+
if (next === -1 || next === startEdge || this.used[next])
|
|
534
|
+
break;
|
|
535
|
+
edge = next;
|
|
536
|
+
}
|
|
537
|
+
return ring;
|
|
538
|
+
}
|
|
539
|
+
// At vertex `at`, arriving from `cameFrom`, pick the unused outgoing edge that turns most clockwise
|
|
540
|
+
// from the reversed incoming direction — the walk that keeps the retained region on the left.
|
|
541
|
+
nextEdge(at, cameFrom) {
|
|
542
|
+
const incomingAngle = Math.atan2(this.ys[cameFrom] - this.ys[at], this.xs[cameFrom] - this.xs[at]);
|
|
543
|
+
let best = -1;
|
|
544
|
+
let bestGap = Infinity;
|
|
545
|
+
for (const edge of this.outgoing[at]) {
|
|
546
|
+
if (this.used[edge])
|
|
547
|
+
continue;
|
|
548
|
+
const to = this.edgeTo[edge];
|
|
549
|
+
const angle = Math.atan2(this.ys[to] - this.ys[at], this.xs[to] - this.xs[at]);
|
|
550
|
+
let gap = incomingAngle - angle;
|
|
551
|
+
while (gap <= 0)
|
|
552
|
+
gap += Math.PI * 2;
|
|
553
|
+
while (gap > Math.PI * 2)
|
|
554
|
+
gap -= Math.PI * 2;
|
|
555
|
+
if (gap < bestGap) {
|
|
556
|
+
bestGap = gap;
|
|
557
|
+
best = edge;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return best;
|
|
561
|
+
}
|
|
562
|
+
vertex(x, y) {
|
|
563
|
+
const key = `${snap(x)},${snap(y)}`;
|
|
564
|
+
const existing = this.keys.get(key);
|
|
565
|
+
if (existing !== undefined)
|
|
566
|
+
return existing;
|
|
567
|
+
const index = this.xs.length;
|
|
568
|
+
this.keys.set(key, index);
|
|
569
|
+
this.xs.push(x);
|
|
570
|
+
this.ys.push(y);
|
|
571
|
+
this.outgoing.push([]);
|
|
572
|
+
return index;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
// Binary min-heap over sweep events ordered by compareEvents.
|
|
576
|
+
class EventHeap {
|
|
577
|
+
data = [];
|
|
578
|
+
isEmpty() {
|
|
579
|
+
return this.data.length === 0;
|
|
580
|
+
}
|
|
581
|
+
push(event) {
|
|
582
|
+
const data = this.data;
|
|
583
|
+
data.push(event);
|
|
584
|
+
let i = data.length - 1;
|
|
585
|
+
while (i > 0) {
|
|
586
|
+
const parent = (i - 1) >> 1;
|
|
587
|
+
if (compareEvents(data[i], data[parent]) < 0) {
|
|
588
|
+
swap(data, i, parent);
|
|
589
|
+
i = parent;
|
|
590
|
+
}
|
|
591
|
+
else
|
|
592
|
+
break;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
pop() {
|
|
596
|
+
const data = this.data;
|
|
597
|
+
const top = data[0];
|
|
598
|
+
const last = data.pop();
|
|
599
|
+
if (data.length > 0) {
|
|
600
|
+
data[0] = last;
|
|
601
|
+
let i = 0;
|
|
602
|
+
const n = data.length;
|
|
603
|
+
for (;;) {
|
|
604
|
+
const left = i * 2 + 1;
|
|
605
|
+
const right = left + 1;
|
|
606
|
+
let smallest = i;
|
|
607
|
+
if (left < n && compareEvents(data[left], data[smallest]) < 0)
|
|
608
|
+
smallest = left;
|
|
609
|
+
if (right < n && compareEvents(data[right], data[smallest]) < 0)
|
|
610
|
+
smallest = right;
|
|
611
|
+
if (smallest === i)
|
|
612
|
+
break;
|
|
613
|
+
swap(data, i, smallest);
|
|
614
|
+
i = smallest;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
return top;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
function swap(data, i, j) {
|
|
621
|
+
const tmp = data[i];
|
|
622
|
+
data[i] = data[j];
|
|
623
|
+
data[j] = tmp;
|
|
624
|
+
}
|
|
625
|
+
//# sourceMappingURL=martinezKernel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"martinezKernel.js","sourceRoot":"","sources":["../src/martinezKernel.ts"],"names":[],"mappings":"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"}
|