@weasel-js/geom 1.10.1 → 1.11.1

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 (55) hide show
  1. package/README.md +9 -1
  2. package/dist/3d/index.d.ts +29 -2
  3. package/dist/3d/index.js +49 -1
  4. package/dist/3d/index.js.map +1 -1
  5. package/dist/booleans/index.d.ts +18 -11
  6. package/dist/booleans/index.js +432 -352
  7. package/dist/booleans/index.js.map +1 -1
  8. package/dist/chunk-4Y67BZL5.js +573 -0
  9. package/dist/chunk-4Y67BZL5.js.map +1 -0
  10. package/dist/chunk-6FGQML7D.js +152 -0
  11. package/dist/chunk-6FGQML7D.js.map +1 -0
  12. package/dist/{chunk-7WFFCHRL.js → chunk-7F66PQCJ.js} +6 -37
  13. package/dist/chunk-7F66PQCJ.js.map +1 -0
  14. package/dist/chunk-B53BERKG.js +386 -0
  15. package/dist/chunk-B53BERKG.js.map +1 -0
  16. package/dist/chunk-CE7IY7TB.js +104 -0
  17. package/dist/chunk-CE7IY7TB.js.map +1 -0
  18. package/dist/chunk-EAKE3N7W.js +804 -0
  19. package/dist/chunk-EAKE3N7W.js.map +1 -0
  20. package/dist/chunk-LRVPK7HI.js +491 -0
  21. package/dist/chunk-LRVPK7HI.js.map +1 -0
  22. package/dist/chunk-Q66NA2FU.js +174 -0
  23. package/dist/chunk-Q66NA2FU.js.map +1 -0
  24. package/dist/chunk-UI3FUWXM.js +533 -0
  25. package/dist/chunk-UI3FUWXM.js.map +1 -0
  26. package/dist/curvature-PkoLduGc.d.ts +454 -0
  27. package/dist/curves/index.d.ts +14 -5
  28. package/dist/curves/index.js +33 -111
  29. package/dist/curves/index.js.map +1 -1
  30. package/dist/index.d.ts +1511 -283
  31. package/dist/index.js +5755 -2674
  32. package/dist/index.js.map +1 -1
  33. package/dist/nd/index.d.ts +92 -27
  34. package/dist/nd/index.js +297 -0
  35. package/dist/nd/index.js.map +1 -1
  36. package/dist/path-BW8d_2RY.d.ts +157 -0
  37. package/dist/portCurve-C5HDWuuV.d.ts +30 -0
  38. package/dist/tessellate/index.d.ts +15 -4
  39. package/dist/tessellate/index.js +21 -277
  40. package/dist/tessellate/index.js.map +1 -1
  41. package/dist/warp/index.d.ts +254 -0
  42. package/dist/warp/index.js +1448 -0
  43. package/dist/warp/index.js.map +1 -0
  44. package/package.json +5 -1
  45. package/dist/chunk-7WFFCHRL.js.map +0 -1
  46. package/dist/chunk-IDXY2NCA.js +0 -177
  47. package/dist/chunk-IDXY2NCA.js.map +0 -1
  48. package/dist/chunk-NJ3IGAKR.js +0 -16
  49. package/dist/chunk-NJ3IGAKR.js.map +0 -1
  50. package/dist/chunk-OXH3NOXC.js +0 -62
  51. package/dist/chunk-OXH3NOXC.js.map +0 -1
  52. package/dist/chunk-URQMDR6Q.js +0 -80
  53. package/dist/chunk-URQMDR6Q.js.map +0 -1
  54. package/dist/cubicMath-BW-HJrCE.d.ts +0 -16
  55. package/dist/path-ljHxobyu.d.ts +0 -44
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The cubic control points that make a curve leave a port along its normal and
3
+ * arrive at the next against that port's normal — what makes a routed edge read
4
+ * as plugged into a box rather than aimed at it.
5
+ *
6
+ * The rule is stated once, over loose components, and published as is from
7
+ * `./nd`; the 2D barrel and `./3d` each wrap it in their own currency. Every
8
+ * operation here is closed on the plane z = 0, so a planar problem answered
9
+ * through the 3D wrapper returns the same numbers as through the 2D one, not an
10
+ * approximation of them.
11
+ */
12
+ /** How far a control point reaches toward the other end, as a fraction of the
13
+ * straight-line distance between the two. */
14
+ declare const PORT_REACH = 0.4;
15
+ /**
16
+ * `[c1, c2]` for the cubic from `a` to `b`.
17
+ *
18
+ * A null normal falls back to a plain lerp along the chord, which is what makes
19
+ * an unported waypoint curve smoothly instead of kinking. The two ends are not
20
+ * symmetric: `outNormal` points the way the curve departs, while `inNormal`
21
+ * points out of the receiving port, so `c2` is pushed *along* it to arrive
22
+ * against it.
23
+ */
24
+ declare function portControls(a: readonly number[], b: readonly number[], outNormal: readonly number[] | null | undefined, inNormal: readonly number[] | null | undefined, reach?: number): [number[], number[]];
25
+ /** A port curve sampled into `samples` points, excluding its start. */
26
+ declare function portCurvePoints(a: readonly number[], b: readonly number[], outNormal: readonly number[] | null | undefined, inNormal: readonly number[] | null | undefined, samples: number, reach?: number): number[][];
27
+ /** A cubic evaluated at `t`, component-wise, in whatever dimension it was given. */
28
+ declare function cubicAt(p0: readonly number[], p1: readonly number[], p2: readonly number[], p3: readonly number[], t: number): number[];
29
+
30
+ export { PORT_REACH as P, portCurvePoints as a, cubicAt as c, portControls as p };
@@ -1,4 +1,4 @@
1
- import { P as Path } from '../path-ljHxobyu.js';
1
+ import { a as Path } from '../path-BW8d_2RY.js';
2
2
 
3
3
  /**
4
4
  * A tessellated representation of a Path, ready to upload to GL.
@@ -51,6 +51,11 @@ interface Polyline {
51
51
  /** Per-point stroke width, populated by the tessellator when the Stroke
52
52
  * carries `vertexWidths`. Undefined means uniform `Stroke.width`. */
53
53
  widths?: Float32Array;
54
+ /** Per-point distance the ribbon's middle sits off the path toward the
55
+ * normal `(−dy, dx)` of the direction of travel: half the right edge's
56
+ * distance less the left's. Set alongside `widths` only when the two sides
57
+ * differ somewhere; undefined means centered. */
58
+ offsets?: Float32Array;
54
59
  }
55
60
  /** Options for `extractPolylines`. */
56
61
  interface ExtractOptions {
@@ -69,8 +74,7 @@ declare function extractPolylines(path: Path, opts?: ExtractOptions): Polyline[]
69
74
  * stroke — so this is the one place our rendering deliberately differs.
70
75
  *
71
76
  * Runs before dash splitting, so a dash pattern fits the visible line rather
72
- * than running off under the head. The anchor-param interpolation matches
73
- * `splitForDash`'s rule for a boundary landing mid-segment.
77
+ * than running off under the head.
74
78
  */
75
79
 
76
80
  /**
@@ -83,4 +87,11 @@ declare function extractPolylines(path: Path, opts?: ExtractOptions): Polyline[]
83
87
  */
84
88
  declare function trimPolyline(pl: Polyline, startInset: number, endInset: number): Polyline | null;
85
89
 
86
- export { type ExtractOptions, type Mesh, type Polyline, type TessellateOptions, extractPolylines, tessellate, trimPolyline };
90
+ /**
91
+ * The anchor parameters `(A, B, t)` of a point a fraction `frac` of the way
92
+ * from one polyline point to the next: `t` interpolated when both lie between
93
+ * the same two anchors, otherwise the nearer point's own.
94
+ */
95
+ declare function anchorParamsBetween(a0: number, b0: number, t0: number, a1: number, b1: number, t1: number, frac: number): [number, number, number];
96
+
97
+ export { type ExtractOptions, type Mesh, type Polyline, type TessellateOptions, anchorParamsBetween, extractPolylines, tessellate, trimPolyline };
@@ -1,267 +1,18 @@
1
- import { rectToContour } from '../chunk-7WFFCHRL.js';
2
- export { extractPolylines } from '../chunk-7WFFCHRL.js';
3
- import { DEFAULT_FLATTEN_TOLERANCE, pointInPolygon, fillsOpenSubpaths, flattenCubicWithArcLen, flattenQuadraticWithArcLen } from '../chunk-IDXY2NCA.js';
1
+ export { extractPolylines } from '../chunk-7F66PQCJ.js';
2
+ export { tessellate } from '../chunk-LRVPK7HI.js';
3
+ import '../chunk-EAKE3N7W.js';
4
4
  import '../chunk-755Y4YZS.js';
5
- import { forEachSegment, PATH_Z, PATH_C, PATH_Q, PATH_L, PATH_M } from '../chunk-OXH3NOXC.js';
6
- import earcut from 'earcut';
5
+ import '../chunk-B53BERKG.js';
7
6
 
8
- function tessellate(path, opts = {}) {
9
- if (path.kind === "rect") return tessellateRect(path);
10
- return tessellatePolygon(path, opts);
11
- }
12
- function tessellateRect(p) {
13
- const { x, y, width: w, height: h } = p;
14
- return {
15
- vertices: Float32Array.from(rectToContour(x, y, w, h)),
16
- indices: new Uint32Array([0, 1, 2, 0, 2, 3]),
17
- anchorA: new Uint32Array([0, 1, 2, 3]),
18
- anchorB: new Uint32Array([0, 1, 2, 3]),
19
- anchorT: new Float32Array([0, 0, 0, 0])
20
- };
21
- }
22
- function flattenPolygon(p, tolerance) {
23
- const closed = /* @__PURE__ */ new Set();
24
- const all = flattenContours(p, tolerance, closed);
25
- if (fillsOpenSubpaths(p)) return all;
26
- const kept = { coords: [], contourStarts: [], anchorA: [], anchorB: [], anchorT: [] };
27
- all.contourStarts.forEach((start, c) => {
28
- if (!closed.has(c)) return;
29
- const end = c + 1 < all.contourStarts.length ? all.contourStarts[c + 1] : all.coords.length / 2;
30
- kept.contourStarts.push(kept.coords.length / 2);
31
- kept.coords.push(...all.coords.slice(start * 2, end * 2));
32
- kept.anchorA.push(...all.anchorA.slice(start, end));
33
- kept.anchorB.push(...all.anchorB.slice(start, end));
34
- kept.anchorT.push(...all.anchorT.slice(start, end));
35
- });
36
- return kept;
37
- }
38
- function flattenContours(p, tolerance, closed) {
39
- const { commands, coords } = p;
40
- const out = [];
41
- const anchorA = [];
42
- const anchorB = [];
43
- const anchorT = [];
44
- const contourStarts = [];
45
- let startAnchor = -1;
46
- let prevAnchor = -1;
47
- let anchorCounter = 0;
48
- const pushCurveAnchors = (anchorStart, arcAccum, total, target) => {
49
- for (let k = 0; k < arcAccum.length; k++) {
50
- anchorA.push(prevAnchor);
51
- anchorB.push(target);
52
- anchorT.push(total > 0 ? arcAccum[k] / total : 0);
53
- }
54
- const lastIdx = anchorStart + arcAccum.length - 1;
55
- anchorA[lastIdx] = target;
56
- anchorB[lastIdx] = target;
57
- anchorT[lastIdx] = 0;
58
- };
59
- forEachSegment(commands, coords, (cmd, coordIdx, prevX, prevY, _i, opensSubpath) => {
60
- if (opensSubpath) {
61
- const anchor = Math.max(startAnchor, 0);
62
- contourStarts.push(out.length / 2);
63
- out.push(prevX, prevY);
64
- anchorA.push(anchor);
65
- anchorB.push(anchor);
66
- anchorT.push(0);
67
- prevAnchor = anchor;
68
- }
69
- switch (cmd) {
70
- case PATH_M:
71
- case PATH_L: {
72
- if (cmd === PATH_M) {
73
- contourStarts.push(out.length / 2);
74
- startAnchor = anchorCounter;
75
- }
76
- out.push(coords[coordIdx], coords[coordIdx + 1]);
77
- anchorA.push(anchorCounter);
78
- anchorB.push(anchorCounter);
79
- anchorT.push(0);
80
- prevAnchor = anchorCounter;
81
- anchorCounter++;
82
- break;
83
- }
84
- case PATH_Q: {
85
- const target = anchorCounter;
86
- const arcAccum = [];
87
- const anchorStart = anchorA.length;
88
- const total = flattenQuadraticWithArcLen(
89
- prevX,
90
- prevY,
91
- coords[coordIdx],
92
- coords[coordIdx + 1],
93
- coords[coordIdx + 2],
94
- coords[coordIdx + 3],
95
- tolerance,
96
- out,
97
- arcAccum
98
- );
99
- pushCurveAnchors(anchorStart, arcAccum, total, target);
100
- prevAnchor = target;
101
- anchorCounter++;
102
- break;
103
- }
104
- case PATH_C: {
105
- const target = anchorCounter;
106
- const arcAccum = [];
107
- const anchorStart = anchorA.length;
108
- const total = flattenCubicWithArcLen(
109
- prevX,
110
- prevY,
111
- coords[coordIdx],
112
- coords[coordIdx + 1],
113
- coords[coordIdx + 2],
114
- coords[coordIdx + 3],
115
- coords[coordIdx + 4],
116
- coords[coordIdx + 5],
117
- tolerance,
118
- out,
119
- arcAccum
120
- );
121
- pushCurveAnchors(anchorStart, arcAccum, total, target);
122
- prevAnchor = target;
123
- anchorCounter++;
124
- break;
125
- }
126
- case PATH_Z:
127
- closed.add(contourStarts.length - 1);
128
- prevAnchor = startAnchor;
129
- break;
130
- default:
131
- throw new Error(`tessellate: unknown command code ${cmd}`);
132
- }
133
- });
134
- return { coords: out, contourStarts, anchorA, anchorB, anchorT };
135
- }
136
- function tessellatePolygon(p, opts) {
137
- const tolerance = opts.flattenTolerance ?? DEFAULT_FLATTEN_TOLERANCE;
138
- const { coords, contourStarts, anchorA, anchorB, anchorT } = flattenPolygon(p, tolerance);
139
- if (p.fillRule === "evenodd") {
140
- return tessellateEvenoddWithAnchors(coords, contourStarts, anchorA, anchorB, anchorT);
141
- }
142
- const totalVerts = coords.length / 2;
143
- const contourEnd = (i) => i + 1 < contourStarts.length ? contourStarts[i + 1] : totalVerts;
144
- if (contourStarts.length <= 1) {
145
- const tri = earcut(coords);
146
- return {
147
- vertices: new Float32Array(coords),
148
- indices: new Uint32Array(tri),
149
- anchorA: new Uint32Array(anchorA),
150
- anchorB: new Uint32Array(anchorB),
151
- anchorT: new Float32Array(anchorT)
152
- };
153
- }
154
- const areas = contourStarts.map((s, i) => signedArea(coords, s, contourEnd(i)));
155
- const refSign = Math.sign(areas[0]) || 1;
156
- const positives = [];
157
- const negatives = [];
158
- for (let i = 0; i < contourStarts.length; i++) {
159
- if (areas[i] === 0) continue;
160
- if (Math.sign(areas[i]) === refSign) positives.push(i);
161
- else negatives.push(i);
162
- }
163
- if (positives.length === 1 && negatives.length > 0) {
164
- const holeIndices = contourStarts.slice(1);
165
- const tri = earcut(coords, holeIndices);
166
- return {
167
- vertices: new Float32Array(coords),
168
- indices: new Uint32Array(tri),
169
- anchorA: new Uint32Array(anchorA),
170
- anchorB: new Uint32Array(anchorB),
171
- anchorT: new Float32Array(anchorT)
172
- };
173
- }
174
- const holesByPositive = /* @__PURE__ */ new Map();
175
- const orphanPositives = [];
176
- for (const n of negatives) {
177
- const px = coords[contourStarts[n] * 2];
178
- const py = coords[contourStarts[n] * 2 + 1];
179
- let bestPos = -1;
180
- let bestAbsArea = Infinity;
181
- for (const pos of positives) {
182
- const absArea = Math.abs(areas[pos]);
183
- if (absArea < bestAbsArea && pointInPolygon(coords, px, py, contourStarts[pos], contourEnd(pos))) {
184
- bestAbsArea = absArea;
185
- bestPos = pos;
186
- }
187
- }
188
- if (bestPos >= 0) {
189
- const arr = holesByPositive.get(bestPos) ?? [];
190
- arr.push(n);
191
- holesByPositive.set(bestPos, arr);
192
- } else {
193
- orphanPositives.push(n);
194
- }
195
- }
196
- const allPositives = [...positives, ...orphanPositives];
197
- const finalCoords = [];
198
- const finalAnchorA = [];
199
- const finalAnchorB = [];
200
- const finalAnchorT = [];
201
- const finalIndices = [];
202
- for (const pos of allPositives) {
203
- const holes = holesByPositive.get(pos) ?? [];
204
- const offset = finalCoords.length / 2;
205
- const groupCoords = [];
206
- const groupStarts = [0];
207
- for (let i = contourStarts[pos]; i < contourEnd(pos); i++) {
208
- groupCoords.push(coords[i * 2], coords[i * 2 + 1]);
209
- finalAnchorA.push(anchorA[i]);
210
- finalAnchorB.push(anchorB[i]);
211
- finalAnchorT.push(anchorT[i]);
212
- }
213
- for (const h of holes) {
214
- groupStarts.push(groupCoords.length / 2);
215
- for (let i = contourStarts[h]; i < contourEnd(h); i++) {
216
- groupCoords.push(coords[i * 2], coords[i * 2 + 1]);
217
- finalAnchorA.push(anchorA[i]);
218
- finalAnchorB.push(anchorB[i]);
219
- finalAnchorT.push(anchorT[i]);
220
- }
221
- }
222
- const tri = earcut(groupCoords, groupStarts.length > 1 ? groupStarts.slice(1) : void 0);
223
- for (const v of groupCoords) finalCoords.push(v);
224
- for (const idx of tri) finalIndices.push(idx + offset);
225
- }
226
- return {
227
- vertices: new Float32Array(finalCoords),
228
- indices: new Uint32Array(finalIndices),
229
- anchorA: new Uint32Array(finalAnchorA),
230
- anchorB: new Uint32Array(finalAnchorB),
231
- anchorT: new Float32Array(finalAnchorT)
232
- };
233
- }
234
- function tessellateEvenoddWithAnchors(coords, contourStarts, anchorA, anchorB, anchorT) {
235
- const indices = [];
236
- const totalVerts = coords.length / 2;
237
- for (let c = 0; c < contourStarts.length; c++) {
238
- const start = contourStarts[c];
239
- const end = c + 1 < contourStarts.length ? contourStarts[c + 1] : totalVerts;
240
- for (let i = start + 1; i < end - 1; i++) {
241
- indices.push(start, i, i + 1);
242
- }
243
- }
244
- return {
245
- vertices: new Float32Array(coords),
246
- indices: new Uint32Array(indices),
247
- requiresStencil: true,
248
- anchorA: new Uint32Array(anchorA),
249
- anchorB: new Uint32Array(anchorB),
250
- anchorT: new Float32Array(anchorT)
251
- };
252
- }
253
- function signedArea(coords, start, end) {
254
- let a = 0;
255
- for (let i = start; i < end; i++) {
256
- const j = i + 1 === end ? start : i + 1;
257
- a += coords[i * 2] * coords[j * 2 + 1] - coords[j * 2] * coords[i * 2 + 1];
258
- }
259
- return a * 0.5;
7
+ // src/tessellate/anchorParams.ts
8
+ function anchorParamsBetween(a0, b0, t0, a1, b1, t1, frac) {
9
+ if (a0 === a1 && b0 === b1) return [a0, b0, t0 + (t1 - t0) * frac];
10
+ return frac < 0.5 ? [a0, b0, t0] : [a1, b1, t1];
260
11
  }
261
12
 
262
13
  // src/tessellate/trim.ts
263
14
  var EPS = 1e-9;
264
- function sampleAt(pl, cum, A, B, T, W, dist, vertexFollows) {
15
+ function sampleAt(pl, cum, A, B, T, W, O, dist, vertexFollows) {
265
16
  const n = cum.length;
266
17
  let i = 1;
267
18
  while (i < n - 1 && (vertexFollows ? cum[i] <= dist : cum[i] < dist)) i++;
@@ -270,22 +21,10 @@ function sampleAt(pl, cum, A, B, T, W, dist, vertexFollows) {
270
21
  const f = segLen > EPS ? (dist - segStart) / segLen : 0;
271
22
  const px = pl.points[(i - 1) * 2], py = pl.points[(i - 1) * 2 + 1];
272
23
  const qx = pl.points[i * 2], qy = pl.points[i * 2 + 1];
273
- let a, b, t;
274
- if (A[i - 1] === A[i] && B[i - 1] === B[i]) {
275
- a = A[i - 1];
276
- b = B[i - 1];
277
- t = T[i - 1] + (T[i] - T[i - 1]) * f;
278
- } else if (f < 0.5) {
279
- a = A[i - 1];
280
- b = B[i - 1];
281
- t = T[i - 1];
282
- } else {
283
- a = A[i];
284
- b = B[i];
285
- t = T[i];
286
- }
24
+ const [a, b, t] = anchorParamsBetween(A[i - 1], B[i - 1], T[i - 1], A[i], B[i], T[i], f);
287
25
  const w = W ? W[i - 1] + (W[i] - W[i - 1]) * f : 0;
288
- return { x: px + (qx - px) * f, y: py + (qy - py) * f, a, b, t, w, next: i };
26
+ const o = O ? O[i - 1] + (O[i] - O[i - 1]) * f : 0;
27
+ return { x: px + (qx - px) * f, y: py + (qy - py) * f, a, b, t, w, o, next: i };
289
28
  }
290
29
  function trimPolyline(pl, startInset, endInset) {
291
30
  const from = Math.max(0, startInset);
@@ -298,6 +37,7 @@ function trimPolyline(pl, startInset, endInset) {
298
37
  const B = pl.anchorB ?? new Uint32Array(n);
299
38
  const T = pl.anchorT ?? new Float32Array(n);
300
39
  const W = pl.widths;
40
+ const O = pl.offsets;
301
41
  const cum = new Float64Array(n);
302
42
  for (let i = 1; i < n; i++) {
303
43
  const dx = pl.points[i * 2] - pl.points[(i - 1) * 2];
@@ -308,35 +48,39 @@ function trimPolyline(pl, startInset, endInset) {
308
48
  const cutA = from;
309
49
  const cutB = total - to;
310
50
  if (cutB - cutA <= EPS) return null;
311
- const head = sampleAt(pl, cum, A, B, T, W, cutA, true);
312
- const tail = sampleAt(pl, cum, A, B, T, W, cutB, false);
51
+ const head = sampleAt(pl, cum, A, B, T, W, O, cutA, true);
52
+ const tail = sampleAt(pl, cum, A, B, T, W, O, cutB, false);
313
53
  const points = [head.x, head.y];
314
54
  const aOut = [head.a];
315
55
  const bOut = [head.b];
316
56
  const tOut = [head.t];
317
57
  const wOut = W ? [head.w] : void 0;
58
+ const oOut = O ? [head.o] : void 0;
318
59
  for (let i = head.next; i < tail.next; i++) {
319
60
  points.push(pl.points[i * 2], pl.points[i * 2 + 1]);
320
61
  aOut.push(A[i]);
321
62
  bOut.push(B[i]);
322
63
  tOut.push(T[i]);
323
64
  if (wOut) wOut.push(W[i]);
65
+ if (oOut) oOut.push(O[i]);
324
66
  }
325
67
  points.push(tail.x, tail.y);
326
68
  aOut.push(tail.a);
327
69
  bOut.push(tail.b);
328
70
  tOut.push(tail.t);
329
71
  if (wOut) wOut.push(tail.w);
72
+ if (oOut) oOut.push(tail.o);
330
73
  return {
331
74
  points,
332
75
  closed: false,
333
76
  anchorA: new Uint32Array(aOut),
334
77
  anchorB: new Uint32Array(bOut),
335
78
  anchorT: new Float32Array(tOut),
336
- ...wOut ? { widths: new Float32Array(wOut) } : {}
79
+ ...wOut ? { widths: new Float32Array(wOut) } : {},
80
+ ...oOut ? { offsets: new Float32Array(oOut) } : {}
337
81
  };
338
82
  }
339
83
 
340
- export { tessellate, trimPolyline };
84
+ export { anchorParamsBetween, trimPolyline };
341
85
  //# sourceMappingURL=index.js.map
342
86
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tessellate/tessellate.ts","../../src/tessellate/trim.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import earcut from 'earcut';\nimport { forEachSegment, PATH_M, PATH_L, PATH_Z, PATH_C, PATH_Q } from '../commands';\nimport { pointInPolygon } from '../polyline';\nimport { rectToContour } from '../box';\nimport type { Path, PolygonPath, RectPath } from '../path';\nimport { fillsOpenSubpaths } from '../openFill';\nimport {\n DEFAULT_FLATTEN_TOLERANCE,\n flattenCubicWithArcLen,\n flattenQuadraticWithArcLen,\n} from '../flatten';\nimport type { Mesh } from './mesh';\n\n/** Options for `tessellate`. A smaller tolerance means more triangles and\n * smoother curves; it is in path-local units, so callers rendering at a\n * larger scale should tighten it. */\nexport interface TessellateOptions {\n /** Flatness tolerance for bezier subdivision in path-local units. */\n flattenTolerance?: number;\n}\n\n/** Turn a path into a triangle mesh the renderer can draw: curves flattened to\n * line segments, then the resulting polygon triangulated. */\nexport function tessellate(path: Path, opts: TessellateOptions = {}): Mesh {\n if (path.kind === 'rect') return tessellateRect(path);\n return tessellatePolygon(path, opts);\n}\n\nfunction tessellateRect(p: RectPath): Mesh {\n const { x, y, width: w, height: h } = p;\n return {\n vertices: Float32Array.from(rectToContour(x, y, w, h)),\n indices: new Uint32Array([0, 1, 2, 0, 2, 3]),\n anchorA: new Uint32Array([0, 1, 2, 3]),\n anchorB: new Uint32Array([0, 1, 2, 3]),\n anchorT: new Float32Array([0, 0, 0, 0]),\n };\n}\n\ninterface FlattenedContours {\n coords: number[];\n contourStarts: number[];\n anchorA: number[];\n anchorB: number[];\n anchorT: number[];\n}\n\n/** The contours a fill covers: all of them, or only those a `Z` closed. */\nfunction flattenPolygon(p: PolygonPath, tolerance: number): FlattenedContours {\n const closed = new Set<number>();\n const all = flattenContours(p, tolerance, closed);\n if (fillsOpenSubpaths(p)) return all;\n const kept: FlattenedContours = { coords: [], contourStarts: [], anchorA: [], anchorB: [], anchorT: [] };\n all.contourStarts.forEach((start, c) => {\n if (!closed.has(c)) return;\n const end = c + 1 < all.contourStarts.length ? all.contourStarts[c + 1] : all.coords.length / 2;\n kept.contourStarts.push(kept.coords.length / 2);\n kept.coords.push(...all.coords.slice(start * 2, end * 2));\n kept.anchorA.push(...all.anchorA.slice(start, end));\n kept.anchorB.push(...all.anchorB.slice(start, end));\n kept.anchorT.push(...all.anchorT.slice(start, end));\n });\n return kept;\n}\n\n/** Flatten every contour, noting in `closed` the index of each one a `Z` ends. */\nfunction flattenContours(p: PolygonPath, tolerance: number, closed: Set<number>): FlattenedContours {\n const { commands, coords } = p;\n const out: number[] = [];\n const anchorA: number[] = [];\n const anchorB: number[] = [];\n const anchorT: number[] = [];\n const contourStarts: number[] = [];\n let startAnchor = -1;\n let prevAnchor = -1;\n let anchorCounter = 0;\n\n // Anchor bookkeeping for the points a curve just appended: interior points\n // interpolate (prevAnchor → target); the last is pinned anchor-exact.\n const pushCurveAnchors = (anchorStart: number, arcAccum: number[], total: number, target: number): void => {\n for (let k = 0; k < arcAccum.length; k++) {\n anchorA.push(prevAnchor);\n anchorB.push(target);\n anchorT.push(total > 0 ? arcAccum[k] / total : 0);\n }\n const lastIdx = anchorStart + arcAccum.length - 1;\n anchorA[lastIdx] = target;\n anchorB[lastIdx] = target;\n anchorT[lastIdx] = 0;\n };\n\n forEachSegment(commands, coords, (cmd, coordIdx, prevX, prevY, _i, opensSubpath) => {\n if (opensSubpath) {\n const anchor = Math.max(startAnchor, 0);\n contourStarts.push(out.length / 2);\n out.push(prevX, prevY);\n anchorA.push(anchor);\n anchorB.push(anchor);\n anchorT.push(0);\n prevAnchor = anchor;\n }\n switch (cmd) {\n case PATH_M:\n case PATH_L: {\n if (cmd === PATH_M) {\n contourStarts.push(out.length / 2);\n startAnchor = anchorCounter;\n }\n out.push(coords[coordIdx], coords[coordIdx + 1]);\n anchorA.push(anchorCounter);\n anchorB.push(anchorCounter);\n anchorT.push(0);\n prevAnchor = anchorCounter;\n anchorCounter++;\n break;\n }\n case PATH_Q: {\n const target = anchorCounter;\n const arcAccum: number[] = [];\n const anchorStart = anchorA.length;\n const total = flattenQuadraticWithArcLen(\n prevX, prevY,\n coords[coordIdx], coords[coordIdx + 1],\n coords[coordIdx + 2], coords[coordIdx + 3],\n tolerance, out, arcAccum,\n );\n pushCurveAnchors(anchorStart, arcAccum, total, target);\n prevAnchor = target;\n anchorCounter++;\n break;\n }\n case PATH_C: {\n const target = anchorCounter;\n const arcAccum: number[] = [];\n const anchorStart = anchorA.length;\n const total = flattenCubicWithArcLen(\n prevX, prevY,\n coords[coordIdx], coords[coordIdx + 1],\n coords[coordIdx + 2], coords[coordIdx + 3],\n coords[coordIdx + 4], coords[coordIdx + 5],\n tolerance, out, arcAccum,\n );\n pushCurveAnchors(anchorStart, arcAccum, total, target);\n prevAnchor = target;\n anchorCounter++;\n break;\n }\n case PATH_Z:\n closed.add(contourStarts.length - 1);\n // The pen returns to the subpath start (forEachSegment does that); the\n // anchor it carries has to follow, or a curve after the Z interpolates\n // from the wrong end.\n prevAnchor = startAnchor;\n break;\n default:\n throw new Error(`tessellate: unknown command code ${cmd}`);\n }\n });\n\n return { coords: out, contourStarts, anchorA, anchorB, anchorT };\n}\n\nfunction tessellatePolygon(p: PolygonPath, opts: TessellateOptions): Mesh {\n const tolerance = opts.flattenTolerance ?? DEFAULT_FLATTEN_TOLERANCE;\n const { coords, contourStarts, anchorA, anchorB, anchorT } = flattenPolygon(p, tolerance);\n\n if (p.fillRule === 'evenodd') {\n return tessellateEvenoddWithAnchors(coords, contourStarts, anchorA, anchorB, anchorT);\n }\n\n // nonzero compound-path tessellation:\n // - The first contour establishes the reference winding direction.\n // - Subsequent contours with the SAME winding as the first are positives\n // (filled, disjoint shapes).\n // - Subsequent contours with OPPOSITE winding are holes; each is grouped\n // with the smallest positive whose polygon contains its first vertex.\n // - Each (positive, [its holes]) group is earcut'd independently;\n // triangles concatenated.\n // Using shoelace sign relative to the first contour avoids guessing about\n // screen-down vs math-up axis conventions.\n\n const totalVerts = coords.length / 2;\n const contourEnd = (i: number): number =>\n i + 1 < contourStarts.length ? contourStarts[i + 1] : totalVerts;\n\n if (contourStarts.length <= 1) {\n const tri = earcut(coords);\n return {\n vertices: new Float32Array(coords),\n indices: new Uint32Array(tri),\n anchorA: new Uint32Array(anchorA),\n anchorB: new Uint32Array(anchorB),\n anchorT: new Float32Array(anchorT),\n };\n }\n\n const areas: number[] = contourStarts.map((s, i) => signedArea(coords, s, contourEnd(i)));\n const refSign = Math.sign(areas[0]) || 1;\n\n const positives: number[] = [];\n const negatives: number[] = [];\n for (let i = 0; i < contourStarts.length; i++) {\n if (areas[i] === 0) continue;\n if (Math.sign(areas[i]) === refSign) positives.push(i);\n else negatives.push(i);\n }\n\n if (positives.length === 1 && negatives.length > 0) {\n // Classic outer-with-holes pattern; pass directly to earcut.\n const holeIndices = contourStarts.slice(1);\n const tri = earcut(coords, holeIndices);\n return {\n vertices: new Float32Array(coords),\n indices: new Uint32Array(tri),\n anchorA: new Uint32Array(anchorA),\n anchorB: new Uint32Array(anchorB),\n anchorT: new Float32Array(anchorT),\n };\n }\n\n // Orphans (opposite-wound but not inside any positive) get promoted to\n // independent positives — author probably intended them as separate shapes\n // with inconsistent winding.\n const holesByPositive = new Map<number, number[]>();\n const orphanPositives: number[] = [];\n for (const n of negatives) {\n const px = coords[contourStarts[n] * 2];\n const py = coords[contourStarts[n] * 2 + 1];\n let bestPos = -1;\n let bestAbsArea = Infinity;\n for (const pos of positives) {\n const absArea = Math.abs(areas[pos]);\n if (absArea < bestAbsArea && pointInPolygon(coords, px, py, contourStarts[pos], contourEnd(pos))) {\n bestAbsArea = absArea;\n bestPos = pos;\n }\n }\n if (bestPos >= 0) {\n const arr = holesByPositive.get(bestPos) ?? [];\n arr.push(n);\n holesByPositive.set(bestPos, arr);\n } else {\n orphanPositives.push(n);\n }\n }\n\n const allPositives = [...positives, ...orphanPositives];\n\n const finalCoords: number[] = [];\n const finalAnchorA: number[] = [];\n const finalAnchorB: number[] = [];\n const finalAnchorT: number[] = [];\n const finalIndices: number[] = [];\n for (const pos of allPositives) {\n const holes = holesByPositive.get(pos) ?? [];\n const offset = finalCoords.length / 2;\n const groupCoords: number[] = [];\n const groupStarts: number[] = [0];\n for (let i = contourStarts[pos]; i < contourEnd(pos); i++) {\n groupCoords.push(coords[i * 2], coords[i * 2 + 1]);\n finalAnchorA.push(anchorA[i]);\n finalAnchorB.push(anchorB[i]);\n finalAnchorT.push(anchorT[i]);\n }\n for (const h of holes) {\n groupStarts.push(groupCoords.length / 2);\n for (let i = contourStarts[h]; i < contourEnd(h); i++) {\n groupCoords.push(coords[i * 2], coords[i * 2 + 1]);\n finalAnchorA.push(anchorA[i]);\n finalAnchorB.push(anchorB[i]);\n finalAnchorT.push(anchorT[i]);\n }\n }\n const tri = earcut(groupCoords, groupStarts.length > 1 ? groupStarts.slice(1) : undefined);\n for (const v of groupCoords) finalCoords.push(v);\n for (const idx of tri) finalIndices.push(idx + offset);\n }\n\n return {\n vertices: new Float32Array(finalCoords),\n indices: new Uint32Array(finalIndices),\n anchorA: new Uint32Array(finalAnchorA),\n anchorB: new Uint32Array(finalAnchorB),\n anchorT: new Float32Array(finalAnchorT),\n };\n}\n\nfunction tessellateEvenoddWithAnchors(\n coords: number[],\n contourStarts: number[],\n anchorA: number[],\n anchorB: number[],\n anchorT: number[],\n): Mesh {\n const indices: number[] = [];\n const totalVerts = coords.length / 2;\n for (let c = 0; c < contourStarts.length; c++) {\n const start = contourStarts[c];\n const end = c + 1 < contourStarts.length ? contourStarts[c + 1] : totalVerts;\n for (let i = start + 1; i < end - 1; i++) {\n indices.push(start, i, i + 1);\n }\n }\n return {\n vertices: new Float32Array(coords),\n indices: new Uint32Array(indices),\n requiresStencil: true,\n anchorA: new Uint32Array(anchorA),\n anchorB: new Uint32Array(anchorB),\n anchorT: new Float32Array(anchorT),\n };\n}\n\nfunction signedArea(coords: number[], start: number, end: number): number {\n let a = 0;\n for (let i = start; i < end; i++) {\n const j = i + 1 === end ? start : i + 1;\n a += coords[i * 2] * coords[j * 2 + 1] - coords[j * 2] * coords[i * 2 + 1];\n }\n return a * 0.5;\n}\n","/**\n * Shortening a flattened subpath so a filled marker is not speared by its own\n * line. SVG has no equivalent — it paints the marker over a full-length\n * stroke — so this is the one place our rendering deliberately differs.\n *\n * Runs before dash splitting, so a dash pattern fits the visible line rather\n * than running off under the head. The anchor-param interpolation matches\n * `splitForDash`'s rule for a boundary landing mid-segment.\n */\n\nimport type { Polyline } from './polyline';\n\nconst EPS = 1e-9;\n\ninterface Sample {\n x: number; y: number;\n a: number; b: number; t: number;\n w: number;\n /** Index of the first original point at or after this sample. */\n next: number;\n}\n\nfunction sampleAt(\n pl: Polyline, cum: Float64Array,\n A: Uint32Array, B: Uint32Array, T: Float32Array, W: Float32Array | undefined,\n dist: number,\n /** For a cut landing exactly on a vertex: whether the vertex belongs to the\n * run after the sample (a head) or before it (a tail), so it is kept once. */\n vertexFollows: boolean,\n): Sample {\n const n = cum.length;\n let i = 1;\n while (i < n - 1 && (vertexFollows ? cum[i] <= dist : cum[i] < dist)) i++;\n const segStart = cum[i - 1];\n const segLen = cum[i] - segStart;\n const f = segLen > EPS ? (dist - segStart) / segLen : 0;\n\n const px = pl.points[(i - 1) * 2], py = pl.points[(i - 1) * 2 + 1];\n const qx = pl.points[i * 2], qy = pl.points[i * 2 + 1];\n\n let a: number, b: number, t: number;\n if (A[i - 1] === A[i] && B[i - 1] === B[i]) {\n a = A[i - 1]; b = B[i - 1];\n t = T[i - 1] + (T[i] - T[i - 1]) * f;\n } else if (f < 0.5) {\n a = A[i - 1]; b = B[i - 1]; t = T[i - 1];\n } else {\n a = A[i]; b = B[i]; t = T[i];\n }\n\n const w = W ? W[i - 1] + (W[i] - W[i - 1]) * f : 0;\n return { x: px + (qx - px) * f, y: py + (qy - py) * f, a, b, t, w, next: i };\n}\n\n/**\n * Shorten `pl` by `startInset` from its first point and `endInset` from its\n * last, both in the same world units as the points.\n *\n * Returns `pl` itself when there is nothing to do (both insets zero, or the\n * subpath is closed and so has no free ends), and `null` when the insets\n * consume the whole run — a caller should then draw no ribbon at all.\n */\nexport function trimPolyline(\n pl: Polyline,\n startInset: number,\n endInset: number,\n): Polyline | null {\n const from = Math.max(0, startInset);\n const to = Math.max(0, endInset);\n if (from <= 0 && to <= 0) return pl;\n if (pl.closed) return pl;\n\n const n = pl.points.length / 2;\n if (n < 2) return null;\n\n const A = pl.anchorA ?? new Uint32Array(n);\n const B = pl.anchorB ?? new Uint32Array(n);\n const T = pl.anchorT ?? new Float32Array(n);\n const W = pl.widths;\n\n const cum = new Float64Array(n);\n for (let i = 1; i < n; i++) {\n const dx = pl.points[i * 2] - pl.points[(i - 1) * 2];\n const dy = pl.points[i * 2 + 1] - pl.points[(i - 1) * 2 + 1];\n cum[i] = cum[i - 1] + Math.hypot(dx, dy);\n }\n const total = cum[n - 1];\n const cutA = from;\n const cutB = total - to;\n if (cutB - cutA <= EPS) return null;\n\n const head = sampleAt(pl, cum, A, B, T, W, cutA, true);\n const tail = sampleAt(pl, cum, A, B, T, W, cutB, false);\n\n const points: number[] = [head.x, head.y];\n const aOut: number[] = [head.a];\n const bOut: number[] = [head.b];\n const tOut: number[] = [head.t];\n const wOut: number[] | undefined = W ? [head.w] : undefined;\n\n for (let i = head.next; i < tail.next; i++) {\n points.push(pl.points[i * 2], pl.points[i * 2 + 1]);\n aOut.push(A[i]); bOut.push(B[i]); tOut.push(T[i]);\n if (wOut) wOut.push(W![i]);\n }\n\n points.push(tail.x, tail.y);\n aOut.push(tail.a); bOut.push(tail.b); tOut.push(tail.t);\n if (wOut) wOut.push(tail.w);\n\n return {\n points,\n closed: false,\n anchorA: new Uint32Array(aOut),\n anchorB: new Uint32Array(bOut),\n anchorT: new Float32Array(tOut),\n ...(wOut ? { widths: new Float32Array(wOut) } : {}),\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/tessellate/anchorParams.ts","../../src/tessellate/trim.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The anchor parameters `(A, B, t)` of a point a fraction `frac` of the way\n * from one polyline point to the next: `t` interpolated when both lie between\n * the same two anchors, otherwise the nearer point's own.\n */\nexport function anchorParamsBetween(\n a0: number, b0: number, t0: number,\n a1: number, b1: number, t1: number,\n frac: number,\n): [number, number, number] {\n if (a0 === a1 && b0 === b1) return [a0, b0, t0 + (t1 - t0) * frac];\n return frac < 0.5 ? [a0, b0, t0] : [a1, b1, t1];\n}\n","/**\n * Shortening a flattened subpath so a filled marker is not speared by its own\n * line. SVG has no equivalent — it paints the marker over a full-length\n * stroke — so this is the one place our rendering deliberately differs.\n *\n * Runs before dash splitting, so a dash pattern fits the visible line rather\n * than running off under the head.\n */\n\nimport { anchorParamsBetween } from './anchorParams';\nimport type { Polyline } from './polyline';\n\nconst EPS = 1e-9;\n\ninterface Sample {\n x: number; y: number;\n a: number; b: number; t: number;\n w: number;\n o: number;\n /** Index of the first original point at or after this sample. */\n next: number;\n}\n\nfunction sampleAt(\n pl: Polyline, cum: Float64Array,\n A: Uint32Array, B: Uint32Array, T: Float32Array, W: Float32Array | undefined, O: Float32Array | undefined,\n dist: number,\n /** For a cut landing exactly on a vertex: whether the vertex belongs to the\n * run after the sample (a head) or before it (a tail), so it is kept once. */\n vertexFollows: boolean,\n): Sample {\n const n = cum.length;\n let i = 1;\n while (i < n - 1 && (vertexFollows ? cum[i] <= dist : cum[i] < dist)) i++;\n const segStart = cum[i - 1];\n const segLen = cum[i] - segStart;\n const f = segLen > EPS ? (dist - segStart) / segLen : 0;\n\n const px = pl.points[(i - 1) * 2], py = pl.points[(i - 1) * 2 + 1];\n const qx = pl.points[i * 2], qy = pl.points[i * 2 + 1];\n\n const [a, b, t] = anchorParamsBetween(A[i - 1], B[i - 1], T[i - 1], A[i], B[i], T[i], f);\n\n const w = W ? W[i - 1] + (W[i] - W[i - 1]) * f : 0;\n const o = O ? O[i - 1] + (O[i] - O[i - 1]) * f : 0;\n return { x: px + (qx - px) * f, y: py + (qy - py) * f, a, b, t, w, o, next: i };\n}\n\n/**\n * Shorten `pl` by `startInset` from its first point and `endInset` from its\n * last, both in the same world units as the points.\n *\n * Returns `pl` itself when there is nothing to do (both insets zero, or the\n * subpath is closed and so has no free ends), and `null` when the insets\n * consume the whole run — a caller should then draw no ribbon at all.\n */\nexport function trimPolyline(\n pl: Polyline,\n startInset: number,\n endInset: number,\n): Polyline | null {\n const from = Math.max(0, startInset);\n const to = Math.max(0, endInset);\n if (from <= 0 && to <= 0) return pl;\n if (pl.closed) return pl;\n\n const n = pl.points.length / 2;\n if (n < 2) return null;\n\n const A = pl.anchorA ?? new Uint32Array(n);\n const B = pl.anchorB ?? new Uint32Array(n);\n const T = pl.anchorT ?? new Float32Array(n);\n const W = pl.widths;\n const O = pl.offsets;\n\n const cum = new Float64Array(n);\n for (let i = 1; i < n; i++) {\n const dx = pl.points[i * 2] - pl.points[(i - 1) * 2];\n const dy = pl.points[i * 2 + 1] - pl.points[(i - 1) * 2 + 1];\n cum[i] = cum[i - 1] + Math.hypot(dx, dy);\n }\n const total = cum[n - 1];\n const cutA = from;\n const cutB = total - to;\n if (cutB - cutA <= EPS) return null;\n\n const head = sampleAt(pl, cum, A, B, T, W, O, cutA, true);\n const tail = sampleAt(pl, cum, A, B, T, W, O, cutB, false);\n\n const points: number[] = [head.x, head.y];\n const aOut: number[] = [head.a];\n const bOut: number[] = [head.b];\n const tOut: number[] = [head.t];\n const wOut: number[] | undefined = W ? [head.w] : undefined;\n const oOut: number[] | undefined = O ? [head.o] : undefined;\n\n for (let i = head.next; i < tail.next; i++) {\n points.push(pl.points[i * 2], pl.points[i * 2 + 1]);\n aOut.push(A[i]); bOut.push(B[i]); tOut.push(T[i]);\n if (wOut) wOut.push(W![i]);\n if (oOut) oOut.push(O![i]);\n }\n\n points.push(tail.x, tail.y);\n aOut.push(tail.a); bOut.push(tail.b); tOut.push(tail.t);\n if (wOut) wOut.push(tail.w);\n if (oOut) oOut.push(tail.o);\n\n return {\n points,\n closed: false,\n anchorA: new Uint32Array(aOut),\n anchorB: new Uint32Array(bOut),\n anchorT: new Float32Array(tOut),\n ...(wOut ? { widths: new Float32Array(wOut) } : {}),\n ...(oOut ? { offsets: new Float32Array(oOut) } : {}),\n };\n}\n"]}