@weasel-js/geom 1.7.0 → 1.7.2

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.
@@ -0,0 +1,513 @@
1
+ import { cubicPointAt } from '../chunk-HPVINMOM.js';
2
+ import '../chunk-URQMDR6Q.js';
3
+ import { PATH_M, PATH_C, PATH_L, PATH_Q } from '../chunk-HEZTRG2M.js';
4
+
5
+ // src/curves/bezierCubic.ts
6
+ var DEFAULT_HANDLE_FRACTION = 1 / 3;
7
+ function smoothTangent(anchors, i) {
8
+ const prev = i > 0 ? anchors[i - 1] : null;
9
+ const next = i + 1 < anchors.length ? anchors[i + 1] : null;
10
+ if (!prev && next) return { x: next.x - anchors[i].x, y: next.y - anchors[i].y };
11
+ if (prev && !next) return { x: anchors[i].x - prev.x, y: anchors[i].y - prev.y };
12
+ if (prev && next) {
13
+ const inLen = Math.hypot(anchors[i].x - prev.x, anchors[i].y - prev.y) || 1;
14
+ const outLen = Math.hypot(next.x - anchors[i].x, next.y - anchors[i].y) || 1;
15
+ return {
16
+ x: (anchors[i].x - prev.x) / inLen + (next.x - anchors[i].x) / outLen,
17
+ y: (anchors[i].y - prev.y) / inLen + (next.y - anchors[i].y) / outLen
18
+ };
19
+ }
20
+ return { x: 0, y: 0 };
21
+ }
22
+ function defaultOutHandle(anchors, i) {
23
+ const a = anchors[i];
24
+ if (a.outHandle) return a.outHandle;
25
+ const next = anchors[i + 1];
26
+ const edgeLen = Math.hypot(next.x - a.x, next.y - a.y);
27
+ const t = smoothTangent(anchors, i);
28
+ const tLen = Math.hypot(t.x, t.y) || 1;
29
+ return {
30
+ x: a.x + t.x / tLen * edgeLen * DEFAULT_HANDLE_FRACTION,
31
+ y: a.y + t.y / tLen * edgeLen * DEFAULT_HANDLE_FRACTION
32
+ };
33
+ }
34
+ function defaultInHandle(anchors, i) {
35
+ const b = anchors[i + 1];
36
+ if (b.inHandle) return b.inHandle;
37
+ const a = anchors[i];
38
+ const edgeLen = Math.hypot(b.x - a.x, b.y - a.y);
39
+ const t = smoothTangent(anchors, i + 1);
40
+ const tLen = Math.hypot(t.x, t.y) || 1;
41
+ return {
42
+ x: b.x - t.x / tLen * edgeLen * DEFAULT_HANDLE_FRACTION,
43
+ y: b.y - t.y / tLen * edgeLen * DEFAULT_HANDLE_FRACTION
44
+ };
45
+ }
46
+ function segmentAt(anchors, t) {
47
+ if (anchors.length < 2) return { segIdx: 0, localT: 0 };
48
+ const segments = anchors.length - 1;
49
+ const scaled = Math.min(Math.max(t, 0), 1) * segments;
50
+ const segIdx = Math.min(Math.floor(scaled), segments - 1);
51
+ const localT = scaled - segIdx;
52
+ return { segIdx, localT };
53
+ }
54
+ function cubicDeriv1(p0, p1, p2, p3, t) {
55
+ const u = 1 - t;
56
+ return {
57
+ x: 3 * u * u * (p1.x - p0.x) + 6 * u * t * (p2.x - p1.x) + 3 * t * t * (p3.x - p2.x),
58
+ y: 3 * u * u * (p1.y - p0.y) + 6 * u * t * (p2.y - p1.y) + 3 * t * t * (p3.y - p2.y)
59
+ };
60
+ }
61
+ function cubicDeriv2(p0, p1, p2, p3, t) {
62
+ const u = 1 - t;
63
+ return {
64
+ x: 6 * u * (p2.x - 2 * p1.x + p0.x) + 6 * t * (p3.x - 2 * p2.x + p1.x),
65
+ y: 6 * u * (p2.y - 2 * p1.y + p0.y) + 6 * t * (p3.y - 2 * p2.y + p1.y)
66
+ };
67
+ }
68
+ var bezierCubic = {
69
+ kind: "bezierCubic",
70
+ label: "Cubic Bezier",
71
+ evaluate(anchors, t) {
72
+ if (anchors.length < 2) return { x: anchors[0]?.x ?? 0, y: anchors[0]?.y ?? 0 };
73
+ const { segIdx, localT } = segmentAt(anchors, t);
74
+ const a = anchors[segIdx];
75
+ const b = anchors[segIdx + 1];
76
+ return cubicPointAt(a, defaultOutHandle(anchors, segIdx), defaultInHandle(anchors, segIdx), b, localT);
77
+ },
78
+ toPath(anchors) {
79
+ if (anchors.length < 2) {
80
+ return { kind: "polygon", commands: new Uint8Array(), coords: new Float32Array(), fillRule: "nonzero" };
81
+ }
82
+ const cmds = [PATH_M];
83
+ const xs = [anchors[0].x, anchors[0].y];
84
+ for (let i = 0; i + 1 < anchors.length; i++) {
85
+ const b = anchors[i + 1];
86
+ const c1 = defaultOutHandle(anchors, i);
87
+ const c2 = defaultInHandle(anchors, i);
88
+ cmds.push(PATH_C);
89
+ xs.push(c1.x, c1.y, c2.x, c2.y, b.x, b.y);
90
+ }
91
+ return {
92
+ kind: "polygon",
93
+ commands: new Uint8Array(cmds),
94
+ coords: new Float32Array(xs),
95
+ fillRule: "nonzero"
96
+ };
97
+ },
98
+ curvatureAt(anchors, t) {
99
+ if (anchors.length < 2) return 0;
100
+ const { segIdx, localT } = segmentAt(anchors, t);
101
+ const a = anchors[segIdx];
102
+ const b = anchors[segIdx + 1];
103
+ const p0 = a;
104
+ const p1 = defaultOutHandle(anchors, segIdx);
105
+ const p2 = defaultInHandle(anchors, segIdx);
106
+ const p3 = b;
107
+ const d1 = cubicDeriv1(p0, p1, p2, p3, localT);
108
+ const d2 = cubicDeriv2(p0, p1, p2, p3, localT);
109
+ const num = d1.x * d2.y - d1.y * d2.x;
110
+ const den = Math.pow(d1.x * d1.x + d1.y * d1.y, 1.5);
111
+ if (den < 1e-12) return 0;
112
+ return num / den;
113
+ },
114
+ discriminators(anchors) {
115
+ const out = [];
116
+ for (let i = 0; i < anchors.length; i++) {
117
+ const a = anchors[i];
118
+ if (a.outHandle || i + 1 < anchors.length) {
119
+ out.push({ kind: "handle", anchorIndex: i, which: "out" });
120
+ }
121
+ if (a.inHandle || i > 0) {
122
+ out.push({ kind: "handle", anchorIndex: i, which: "in" });
123
+ }
124
+ }
125
+ return out;
126
+ }
127
+ };
128
+
129
+ // src/curves/bezierQuadratic.ts
130
+ var DEFAULT_HANDLE_FRACTION2 = 1 / 3;
131
+ function smoothTangent2(anchors, i) {
132
+ const prev = i > 0 ? anchors[i - 1] : null;
133
+ const next = i + 1 < anchors.length ? anchors[i + 1] : null;
134
+ if (!prev && next) return { x: next.x - anchors[i].x, y: next.y - anchors[i].y };
135
+ if (prev && !next) return { x: anchors[i].x - prev.x, y: anchors[i].y - prev.y };
136
+ if (prev && next) {
137
+ const inLen = Math.hypot(anchors[i].x - prev.x, anchors[i].y - prev.y) || 1;
138
+ const outLen = Math.hypot(next.x - anchors[i].x, next.y - anchors[i].y) || 1;
139
+ return {
140
+ x: (anchors[i].x - prev.x) / inLen + (next.x - anchors[i].x) / outLen,
141
+ y: (anchors[i].y - prev.y) / inLen + (next.y - anchors[i].y) / outLen
142
+ };
143
+ }
144
+ return { x: 0, y: 0 };
145
+ }
146
+ function defaultOutHandle2(anchors, i) {
147
+ const a = anchors[i];
148
+ if (a.outHandle) return a.outHandle;
149
+ const next = anchors[i + 1];
150
+ const edgeLen = Math.hypot(next.x - a.x, next.y - a.y);
151
+ const t = smoothTangent2(anchors, i);
152
+ const tLen = Math.hypot(t.x, t.y) || 1;
153
+ return {
154
+ x: a.x + t.x / tLen * edgeLen * DEFAULT_HANDLE_FRACTION2,
155
+ y: a.y + t.y / tLen * edgeLen * DEFAULT_HANDLE_FRACTION2
156
+ };
157
+ }
158
+ function defaultInHandle2(anchors, i) {
159
+ const b = anchors[i + 1];
160
+ if (b.inHandle) return b.inHandle;
161
+ const a = anchors[i];
162
+ const edgeLen = Math.hypot(b.x - a.x, b.y - a.y);
163
+ const t = smoothTangent2(anchors, i + 1);
164
+ const tLen = Math.hypot(t.x, t.y) || 1;
165
+ return {
166
+ x: b.x - t.x / tLen * edgeLen * DEFAULT_HANDLE_FRACTION2,
167
+ y: b.y - t.y / tLen * edgeLen * DEFAULT_HANDLE_FRACTION2
168
+ };
169
+ }
170
+ function quadControl(anchors, i) {
171
+ const c1 = defaultOutHandle2(anchors, i);
172
+ const c2 = defaultInHandle2(anchors, i);
173
+ return { x: (c1.x + c2.x) / 2, y: (c1.y + c2.y) / 2 };
174
+ }
175
+ function segmentAt2(anchors, t) {
176
+ if (anchors.length < 2) return { segIdx: 0, localT: 0 };
177
+ const segments = anchors.length - 1;
178
+ const scaled = Math.min(Math.max(t, 0), 1) * segments;
179
+ const segIdx = Math.min(Math.floor(scaled), segments - 1);
180
+ const localT = scaled - segIdx;
181
+ return { segIdx, localT };
182
+ }
183
+ function quadEval(p0, p1, p2, t) {
184
+ const u = 1 - t;
185
+ return {
186
+ x: u * u * p0.x + 2 * u * t * p1.x + t * t * p2.x,
187
+ y: u * u * p0.y + 2 * u * t * p1.y + t * t * p2.y
188
+ };
189
+ }
190
+ function quadDeriv1(p0, p1, p2, t) {
191
+ const u = 1 - t;
192
+ return {
193
+ x: 2 * u * (p1.x - p0.x) + 2 * t * (p2.x - p1.x),
194
+ y: 2 * u * (p1.y - p0.y) + 2 * t * (p2.y - p1.y)
195
+ };
196
+ }
197
+ function quadDeriv2(p0, p1, p2) {
198
+ return {
199
+ x: 2 * (p2.x - 2 * p1.x + p0.x),
200
+ y: 2 * (p2.y - 2 * p1.y + p0.y)
201
+ };
202
+ }
203
+ var bezierQuadratic = {
204
+ kind: "bezierQuadratic",
205
+ label: "Quadratic Bezier",
206
+ evaluate(anchors, t) {
207
+ if (anchors.length < 2) return { x: anchors[0]?.x ?? 0, y: anchors[0]?.y ?? 0 };
208
+ const { segIdx, localT } = segmentAt2(anchors, t);
209
+ const a = anchors[segIdx];
210
+ const b = anchors[segIdx + 1];
211
+ return quadEval(a, quadControl(anchors, segIdx), b, localT);
212
+ },
213
+ toPath(anchors) {
214
+ if (anchors.length < 2) {
215
+ return { kind: "polygon", commands: new Uint8Array(), coords: new Float32Array(), fillRule: "nonzero" };
216
+ }
217
+ const cmds = [PATH_M];
218
+ const xs = [anchors[0].x, anchors[0].y];
219
+ for (let i = 0; i + 1 < anchors.length; i++) {
220
+ const b = anchors[i + 1];
221
+ const q = quadControl(anchors, i);
222
+ cmds.push(PATH_Q);
223
+ xs.push(q.x, q.y, b.x, b.y);
224
+ }
225
+ return {
226
+ kind: "polygon",
227
+ commands: new Uint8Array(cmds),
228
+ coords: new Float32Array(xs),
229
+ fillRule: "nonzero"
230
+ };
231
+ },
232
+ curvatureAt(anchors, t) {
233
+ if (anchors.length < 2) return 0;
234
+ const { segIdx, localT } = segmentAt2(anchors, t);
235
+ const a = anchors[segIdx];
236
+ const b = anchors[segIdx + 1];
237
+ const p1 = quadControl(anchors, segIdx);
238
+ const d1 = quadDeriv1(a, p1, b, localT);
239
+ const d2 = quadDeriv2(a, p1, b);
240
+ const num = d1.x * d2.y - d1.y * d2.x;
241
+ const den = Math.pow(d1.x * d1.x + d1.y * d1.y, 1.5);
242
+ if (den < 1e-12) return 0;
243
+ return num / den;
244
+ },
245
+ discriminators(_anchors) {
246
+ return [];
247
+ }
248
+ };
249
+
250
+ // src/curves/nurbs.ts
251
+ var DEGREE = 3;
252
+ var WEIGHT_MIN = 1e-3;
253
+ var WEIGHT_MAX = 8;
254
+ var FLATTEN_SAMPLES = 64;
255
+ function openUniformKnots(n, p = DEGREE) {
256
+ const m = n + p + 1;
257
+ const knots = [];
258
+ for (let i = 0; i < m; i++) {
259
+ if (i <= p) knots.push(0);
260
+ else if (i >= n) knots.push(1);
261
+ else knots.push((i - p) / (n - p));
262
+ }
263
+ return knots;
264
+ }
265
+ function findSpan(n, p, u, knots) {
266
+ if (u >= knots[n]) return n - 1;
267
+ if (u <= knots[p]) return p;
268
+ let lo = p;
269
+ let hi = n;
270
+ let mid = lo + hi >> 1;
271
+ while (u < knots[mid] || u >= knots[mid + 1]) {
272
+ if (u < knots[mid]) hi = mid;
273
+ else lo = mid;
274
+ mid = lo + hi >> 1;
275
+ }
276
+ return mid;
277
+ }
278
+ function basisFunctions(i, u, p, knots) {
279
+ const N = new Array(p + 1).fill(0);
280
+ N[0] = 1;
281
+ const left = new Array(p + 1).fill(0);
282
+ const right = new Array(p + 1).fill(0);
283
+ for (let j = 1; j <= p; j++) {
284
+ left[j] = u - knots[i + 1 - j];
285
+ right[j] = knots[i + j] - u;
286
+ let saved = 0;
287
+ for (let r = 0; r < j; r++) {
288
+ const temp = N[r] / (right[r + 1] + left[j - r]);
289
+ N[r] = saved + right[r + 1] * temp;
290
+ saved = left[j - r] * temp;
291
+ }
292
+ N[j] = saved;
293
+ }
294
+ return N;
295
+ }
296
+ function weightOf(a) {
297
+ const w = a.weight ?? 1;
298
+ return Math.max(WEIGHT_MIN, Math.min(WEIGHT_MAX, w));
299
+ }
300
+ function evalNurbs(anchors, u) {
301
+ const n = anchors.length;
302
+ if (n === 0) return { x: 0, y: 0 };
303
+ if (n === 1) return { x: anchors[0].x, y: anchors[0].y };
304
+ const p = Math.min(DEGREE, n - 1);
305
+ const knots = openUniformKnots(n, p);
306
+ const clamped = Math.min(Math.max(u, 0), 1);
307
+ const span = findSpan(n, p, clamped, knots);
308
+ const N = basisFunctions(span, clamped, p, knots);
309
+ let wx = 0;
310
+ let wy = 0;
311
+ let wTotal = 0;
312
+ for (let j = 0; j <= p; j++) {
313
+ const idx = span - p + j;
314
+ const a = anchors[idx];
315
+ const w = weightOf(a);
316
+ wx += N[j] * w * a.x;
317
+ wy += N[j] * w * a.y;
318
+ wTotal += N[j] * w;
319
+ }
320
+ if (wTotal < 1e-12) return { x: anchors[0].x, y: anchors[0].y };
321
+ return { x: wx / wTotal, y: wy / wTotal };
322
+ }
323
+ var nurbs = {
324
+ kind: "nurbs",
325
+ label: "NURBS",
326
+ evaluate(anchors, t) {
327
+ return evalNurbs(anchors, t);
328
+ },
329
+ toPath(anchors) {
330
+ if (anchors.length < 2) {
331
+ return { kind: "polygon", commands: new Uint8Array(), coords: new Float32Array(), fillRule: "nonzero" };
332
+ }
333
+ const cmds = [PATH_M];
334
+ const xs = [];
335
+ for (let s = 0; s <= FLATTEN_SAMPLES; s++) {
336
+ const t = s / FLATTEN_SAMPLES;
337
+ const p = evalNurbs(anchors, t);
338
+ xs.push(p.x, p.y);
339
+ if (s > 0) cmds.push(PATH_L);
340
+ }
341
+ return {
342
+ kind: "polygon",
343
+ commands: new Uint8Array(cmds),
344
+ coords: new Float32Array(xs),
345
+ fillRule: "nonzero"
346
+ };
347
+ },
348
+ curvatureAt(anchors, t) {
349
+ if (anchors.length < 2) return 0;
350
+ const eps = 1e-3;
351
+ const t0 = Math.max(0, t - eps);
352
+ const t1 = Math.min(1, t + eps);
353
+ const p0 = evalNurbs(anchors, t0);
354
+ const p2 = evalNurbs(anchors, t1);
355
+ const pm = evalNurbs(anchors, t);
356
+ const d1x = (p2.x - p0.x) / (t1 - t0);
357
+ const d1y = (p2.y - p0.y) / (t1 - t0);
358
+ const d2x = (p2.x - 2 * pm.x + p0.x) / (eps * eps);
359
+ const d2y = (p2.y - 2 * pm.y + p0.y) / (eps * eps);
360
+ const num = d1x * d2y - d1y * d2x;
361
+ const den = Math.pow(d1x * d1x + d1y * d1y, 1.5);
362
+ if (den < 1e-12) return 0;
363
+ return num / den;
364
+ },
365
+ discriminators(anchors) {
366
+ const out = [];
367
+ for (let i = 0; i < anchors.length; i++) {
368
+ out.push({
369
+ kind: "slider",
370
+ label: `w${i}`,
371
+ anchorIndex: i,
372
+ field: "weight",
373
+ min: WEIGHT_MIN,
374
+ max: WEIGHT_MAX,
375
+ step: 0.1,
376
+ value: weightOf(anchors[i])
377
+ });
378
+ }
379
+ return out;
380
+ }
381
+ };
382
+
383
+ // src/curves/spiro.ts
384
+ var TANGENT_SCALE = 1 / 3;
385
+ function isCorner(a) {
386
+ return a.spiroType === "corner";
387
+ }
388
+ function smoothTangent3(anchors, i) {
389
+ if (isCorner(anchors[i])) return null;
390
+ const prev = i > 0 ? anchors[i - 1] : null;
391
+ const next = i + 1 < anchors.length ? anchors[i + 1] : null;
392
+ if (!prev && !next) return null;
393
+ if (!prev) {
394
+ return { x: next.x - anchors[i].x, y: next.y - anchors[i].y };
395
+ }
396
+ if (!next) {
397
+ return { x: anchors[i].x - prev.x, y: anchors[i].y - prev.y };
398
+ }
399
+ const inDX = anchors[i].x - prev.x;
400
+ const inDY = anchors[i].y - prev.y;
401
+ const outDX = next.x - anchors[i].x;
402
+ const outDY = next.y - anchors[i].y;
403
+ const inLen = Math.hypot(inDX, inDY) || 1;
404
+ const outLen = Math.hypot(outDX, outDY) || 1;
405
+ return {
406
+ x: inDX / inLen + outDX / outLen,
407
+ y: inDY / inLen + outDY / outLen
408
+ };
409
+ }
410
+ function controlsFor(anchors, i) {
411
+ const a = anchors[i];
412
+ const b = anchors[i + 1];
413
+ const edge = { x: b.x - a.x, y: b.y - a.y };
414
+ const edgeLen = Math.hypot(edge.x, edge.y) || 1;
415
+ const tA = smoothTangent3(anchors, i);
416
+ const tB = smoothTangent3(anchors, i + 1);
417
+ const outA = tA ?? edge;
418
+ const outB = tB ?? edge;
419
+ const outALen = Math.hypot(outA.x, outA.y) || 1;
420
+ const outBLen = Math.hypot(outB.x, outB.y) || 1;
421
+ const handleLen = edgeLen * TANGENT_SCALE;
422
+ return {
423
+ c1: {
424
+ x: a.x + outA.x / outALen * handleLen,
425
+ y: a.y + outA.y / outALen * handleLen
426
+ },
427
+ c2: {
428
+ x: b.x - outB.x / outBLen * handleLen,
429
+ y: b.y - outB.y / outBLen * handleLen
430
+ }
431
+ };
432
+ }
433
+ function segmentAt3(anchors, t) {
434
+ if (anchors.length < 2) return { segIdx: 0, localT: 0 };
435
+ const segments = anchors.length - 1;
436
+ const scaled = Math.min(Math.max(t, 0), 1) * segments;
437
+ const segIdx = Math.min(Math.floor(scaled), segments - 1);
438
+ const localT = scaled - segIdx;
439
+ return { segIdx, localT };
440
+ }
441
+ var spiro = {
442
+ kind: "spiro",
443
+ label: "Spiro (\u03BA-curves v1)",
444
+ evaluate(anchors, t) {
445
+ if (anchors.length < 2) return { x: anchors[0]?.x ?? 0, y: anchors[0]?.y ?? 0 };
446
+ const { segIdx, localT } = segmentAt3(anchors, t);
447
+ const a = anchors[segIdx];
448
+ const b = anchors[segIdx + 1];
449
+ const { c1, c2 } = controlsFor(anchors, segIdx);
450
+ return cubicPointAt(a, c1, c2, b, localT);
451
+ },
452
+ toPath(anchors) {
453
+ if (anchors.length < 2) {
454
+ return { kind: "polygon", commands: new Uint8Array(), coords: new Float32Array(), fillRule: "nonzero" };
455
+ }
456
+ const cmds = [PATH_M];
457
+ const xs = [anchors[0].x, anchors[0].y];
458
+ for (let i = 0; i + 1 < anchors.length; i++) {
459
+ const b = anchors[i + 1];
460
+ const { c1, c2 } = controlsFor(anchors, i);
461
+ cmds.push(PATH_C);
462
+ xs.push(c1.x, c1.y, c2.x, c2.y, b.x, b.y);
463
+ }
464
+ return {
465
+ kind: "polygon",
466
+ commands: new Uint8Array(cmds),
467
+ coords: new Float32Array(xs),
468
+ fillRule: "nonzero"
469
+ };
470
+ },
471
+ curvatureAt(anchors, t) {
472
+ if (anchors.length < 2) return 0;
473
+ const { segIdx, localT } = segmentAt3(anchors, t);
474
+ const a = anchors[segIdx];
475
+ const b = anchors[segIdx + 1];
476
+ const { c1, c2 } = controlsFor(anchors, segIdx);
477
+ const u = 1 - localT;
478
+ const d1x = 3 * u * u * (c1.x - a.x) + 6 * u * localT * (c2.x - c1.x) + 3 * localT * localT * (b.x - c2.x);
479
+ const d1y = 3 * u * u * (c1.y - a.y) + 6 * u * localT * (c2.y - c1.y) + 3 * localT * localT * (b.y - c2.y);
480
+ const d2x = 6 * u * (c2.x - 2 * c1.x + a.x) + 6 * localT * (b.x - 2 * c2.x + c1.x);
481
+ const d2y = 6 * u * (c2.y - 2 * c1.y + a.y) + 6 * localT * (b.y - 2 * c2.y + c1.y);
482
+ const num = d1x * d2y - d1y * d2x;
483
+ const den = Math.pow(d1x * d1x + d1y * d1y, 1.5);
484
+ if (den < 1e-12) return 0;
485
+ return num / den;
486
+ },
487
+ discriminators(anchors) {
488
+ const out = [];
489
+ for (let i = 0; i < anchors.length; i++) {
490
+ out.push({
491
+ kind: "enum",
492
+ label: `t${i}`,
493
+ anchorIndex: i,
494
+ field: "spiroType",
495
+ options: ["g2-smooth", "g4-smooth", "corner"],
496
+ value: anchors[i].spiroType ?? "g2-smooth"
497
+ });
498
+ }
499
+ return out;
500
+ }
501
+ };
502
+
503
+ // src/curves/index.ts
504
+ var CURVE_REPS = {
505
+ bezierCubic,
506
+ bezierQuadratic,
507
+ nurbs,
508
+ spiro
509
+ };
510
+
511
+ export { CURVE_REPS, bezierCubic, bezierQuadratic, nurbs, spiro };
512
+ //# sourceMappingURL=index.js.map
513
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/curves/bezierCubic.ts","../../src/curves/bezierQuadratic.ts","../../src/curves/nurbs.ts","../../src/curves/spiro.ts","../../src/curves/index.ts"],"names":["DEFAULT_HANDLE_FRACTION","smoothTangent","defaultOutHandle","defaultInHandle","segmentAt"],"mappings":"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","file":"index.js","sourcesContent":["import type { CurveRepresentation, Discriminator, SharedAnchor } from './types';\nimport { PATH_C, PATH_M } from '../commands';\nimport { cubicPointAt } from '../paths/cubicMath';\n\nconst DEFAULT_HANDLE_FRACTION = 1 / 3;\n\n/** Smooth tangent at anchor i derived from neighbor edges. Average the\n * incoming and outgoing edge directions weighted by inverse edge length\n * (centripetal-style) so short edges don't dominate. At endpoints the\n * single available edge wins. Without this, a handle colinear with one\n * segment produces a degenerate (visually straight) cubic. */\nfunction smoothTangent(anchors: SharedAnchor[], i: number): { x: number; y: number } {\n const prev = i > 0 ? anchors[i - 1] : null;\n const next = i + 1 < anchors.length ? anchors[i + 1] : null;\n if (!prev && next) return { x: next.x - anchors[i].x, y: next.y - anchors[i].y };\n if (prev && !next) return { x: anchors[i].x - prev.x, y: anchors[i].y - prev.y };\n if (prev && next) {\n const inLen = Math.hypot(anchors[i].x - prev.x, anchors[i].y - prev.y) || 1;\n const outLen = Math.hypot(next.x - anchors[i].x, next.y - anchors[i].y) || 1;\n return {\n x: (anchors[i].x - prev.x) / inLen + (next.x - anchors[i].x) / outLen,\n y: (anchors[i].y - prev.y) / inLen + (next.y - anchors[i].y) / outLen,\n };\n }\n return { x: 0, y: 0 };\n}\n\nfunction defaultOutHandle(anchors: SharedAnchor[], i: number): { x: number; y: number } {\n const a = anchors[i];\n if (a.outHandle) return a.outHandle;\n const next = anchors[i + 1];\n const edgeLen = Math.hypot(next.x - a.x, next.y - a.y);\n const t = smoothTangent(anchors, i);\n const tLen = Math.hypot(t.x, t.y) || 1;\n return {\n x: a.x + (t.x / tLen) * edgeLen * DEFAULT_HANDLE_FRACTION,\n y: a.y + (t.y / tLen) * edgeLen * DEFAULT_HANDLE_FRACTION,\n };\n}\n\nfunction defaultInHandle(anchors: SharedAnchor[], i: number): { x: number; y: number } {\n const b = anchors[i + 1];\n if (b.inHandle) return b.inHandle;\n const a = anchors[i];\n const edgeLen = Math.hypot(b.x - a.x, b.y - a.y);\n const t = smoothTangent(anchors, i + 1);\n const tLen = Math.hypot(t.x, t.y) || 1;\n return {\n x: b.x - (t.x / tLen) * edgeLen * DEFAULT_HANDLE_FRACTION,\n y: b.y - (t.y / tLen) * edgeLen * DEFAULT_HANDLE_FRACTION,\n };\n}\n\nfunction segmentAt(anchors: SharedAnchor[], t: number): { segIdx: number; localT: number } {\n if (anchors.length < 2) return { segIdx: 0, localT: 0 };\n const segments = anchors.length - 1;\n const scaled = Math.min(Math.max(t, 0), 1) * segments;\n const segIdx = Math.min(Math.floor(scaled), segments - 1);\n const localT = scaled - segIdx;\n return { segIdx, localT };\n}\n\nfunction cubicDeriv1(\n p0: { x: number; y: number },\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n p3: { x: number; y: number },\n t: number,\n): { x: number; y: number } {\n const u = 1 - t;\n return {\n x: 3 * u * u * (p1.x - p0.x) + 6 * u * t * (p2.x - p1.x) + 3 * t * t * (p3.x - p2.x),\n y: 3 * u * u * (p1.y - p0.y) + 6 * u * t * (p2.y - p1.y) + 3 * t * t * (p3.y - p2.y),\n };\n}\n\nfunction cubicDeriv2(\n p0: { x: number; y: number },\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n p3: { x: number; y: number },\n t: number,\n): { x: number; y: number } {\n const u = 1 - t;\n return {\n x: 6 * u * (p2.x - 2 * p1.x + p0.x) + 6 * t * (p3.x - 2 * p2.x + p1.x),\n y: 6 * u * (p2.y - 2 * p1.y + p0.y) + 6 * t * (p3.y - 2 * p2.y + p1.y),\n };\n}\n\n/** Cubic bezier: each segment takes two control handles. The familiar pen-tool curve, and what SVG path data stores natively. */\nexport const bezierCubic: CurveRepresentation = {\n kind: 'bezierCubic',\n label: 'Cubic Bezier',\n evaluate(anchors, t) {\n if (anchors.length < 2) return { x: anchors[0]?.x ?? 0, y: anchors[0]?.y ?? 0 };\n const { segIdx, localT } = segmentAt(anchors, t);\n const a = anchors[segIdx];\n const b = anchors[segIdx + 1];\n return cubicPointAt(a, defaultOutHandle(anchors, segIdx), defaultInHandle(anchors, segIdx), b, localT);\n },\n toPath(anchors) {\n if (anchors.length < 2) {\n return { kind: 'polygon', commands: new Uint8Array(), coords: new Float32Array(), fillRule: 'nonzero' };\n }\n const cmds: number[] = [PATH_M];\n const xs: number[] = [anchors[0].x, anchors[0].y];\n for (let i = 0; i + 1 < anchors.length; i++) {\n const b = anchors[i + 1];\n const c1 = defaultOutHandle(anchors, i);\n const c2 = defaultInHandle(anchors, i);\n cmds.push(PATH_C);\n xs.push(c1.x, c1.y, c2.x, c2.y, b.x, b.y);\n }\n return {\n kind: 'polygon',\n commands: new Uint8Array(cmds),\n coords: new Float32Array(xs),\n fillRule: 'nonzero',\n };\n },\n curvatureAt(anchors, t) {\n if (anchors.length < 2) return 0;\n const { segIdx, localT } = segmentAt(anchors, t);\n const a = anchors[segIdx];\n const b = anchors[segIdx + 1];\n const p0 = a;\n const p1 = defaultOutHandle(anchors, segIdx);\n const p2 = defaultInHandle(anchors, segIdx);\n const p3 = b;\n const d1 = cubicDeriv1(p0, p1, p2, p3, localT);\n const d2 = cubicDeriv2(p0, p1, p2, p3, localT);\n const num = d1.x * d2.y - d1.y * d2.x;\n const den = Math.pow(d1.x * d1.x + d1.y * d1.y, 1.5);\n if (den < 1e-12) return 0;\n return num / den;\n },\n discriminators(anchors) {\n const out: Discriminator[] = [];\n for (let i = 0; i < anchors.length; i++) {\n const a = anchors[i];\n if (a.outHandle || i + 1 < anchors.length) {\n out.push({ kind: 'handle', anchorIndex: i, which: 'out' });\n }\n if (a.inHandle || i > 0) {\n out.push({ kind: 'handle', anchorIndex: i, which: 'in' });\n }\n }\n return out;\n },\n};\n","import type { CurveRepresentation, Discriminator, SharedAnchor } from './types';\nimport { PATH_M, PATH_Q } from '../commands';\n\nconst DEFAULT_HANDLE_FRACTION = 1 / 3;\n\nfunction smoothTangent(anchors: SharedAnchor[], i: number): { x: number; y: number } {\n const prev = i > 0 ? anchors[i - 1] : null;\n const next = i + 1 < anchors.length ? anchors[i + 1] : null;\n if (!prev && next) return { x: next.x - anchors[i].x, y: next.y - anchors[i].y };\n if (prev && !next) return { x: anchors[i].x - prev.x, y: anchors[i].y - prev.y };\n if (prev && next) {\n const inLen = Math.hypot(anchors[i].x - prev.x, anchors[i].y - prev.y) || 1;\n const outLen = Math.hypot(next.x - anchors[i].x, next.y - anchors[i].y) || 1;\n return {\n x: (anchors[i].x - prev.x) / inLen + (next.x - anchors[i].x) / outLen,\n y: (anchors[i].y - prev.y) / inLen + (next.y - anchors[i].y) / outLen,\n };\n }\n return { x: 0, y: 0 };\n}\n\nfunction defaultOutHandle(anchors: SharedAnchor[], i: number): { x: number; y: number } {\n const a = anchors[i];\n if (a.outHandle) return a.outHandle;\n const next = anchors[i + 1];\n const edgeLen = Math.hypot(next.x - a.x, next.y - a.y);\n const t = smoothTangent(anchors, i);\n const tLen = Math.hypot(t.x, t.y) || 1;\n return {\n x: a.x + (t.x / tLen) * edgeLen * DEFAULT_HANDLE_FRACTION,\n y: a.y + (t.y / tLen) * edgeLen * DEFAULT_HANDLE_FRACTION,\n };\n}\n\nfunction defaultInHandle(anchors: SharedAnchor[], i: number): { x: number; y: number } {\n const b = anchors[i + 1];\n if (b.inHandle) return b.inHandle;\n const a = anchors[i];\n const edgeLen = Math.hypot(b.x - a.x, b.y - a.y);\n const t = smoothTangent(anchors, i + 1);\n const tLen = Math.hypot(t.x, t.y) || 1;\n return {\n x: b.x - (t.x / tLen) * edgeLen * DEFAULT_HANDLE_FRACTION,\n y: b.y - (t.y / tLen) * edgeLen * DEFAULT_HANDLE_FRACTION,\n };\n}\n\nfunction quadControl(anchors: SharedAnchor[], i: number): { x: number; y: number } {\n const c1 = defaultOutHandle(anchors, i);\n const c2 = defaultInHandle(anchors, i);\n return { x: (c1.x + c2.x) / 2, y: (c1.y + c2.y) / 2 };\n}\n\nfunction segmentAt(anchors: SharedAnchor[], t: number): { segIdx: number; localT: number } {\n if (anchors.length < 2) return { segIdx: 0, localT: 0 };\n const segments = anchors.length - 1;\n const scaled = Math.min(Math.max(t, 0), 1) * segments;\n const segIdx = Math.min(Math.floor(scaled), segments - 1);\n const localT = scaled - segIdx;\n return { segIdx, localT };\n}\n\nfunction quadEval(\n p0: { x: number; y: number },\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n t: number,\n): { x: number; y: number } {\n const u = 1 - t;\n return {\n x: u * u * p0.x + 2 * u * t * p1.x + t * t * p2.x,\n y: u * u * p0.y + 2 * u * t * p1.y + t * t * p2.y,\n };\n}\n\nfunction quadDeriv1(\n p0: { x: number; y: number },\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n t: number,\n): { x: number; y: number } {\n const u = 1 - t;\n return {\n x: 2 * u * (p1.x - p0.x) + 2 * t * (p2.x - p1.x),\n y: 2 * u * (p1.y - p0.y) + 2 * t * (p2.y - p1.y),\n };\n}\n\nfunction quadDeriv2(\n p0: { x: number; y: number },\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n): { x: number; y: number } {\n return {\n x: 2 * (p2.x - 2 * p1.x + p0.x),\n y: 2 * (p2.y - 2 * p1.y + p0.y),\n };\n}\n\n/** Quadratic bezier: one control point per segment. Cheaper than cubic and what TrueType glyph outlines use, at the cost of expressiveness. */\nexport const bezierQuadratic: CurveRepresentation = {\n kind: 'bezierQuadratic',\n label: 'Quadratic Bezier',\n evaluate(anchors, t) {\n if (anchors.length < 2) return { x: anchors[0]?.x ?? 0, y: anchors[0]?.y ?? 0 };\n const { segIdx, localT } = segmentAt(anchors, t);\n const a = anchors[segIdx];\n const b = anchors[segIdx + 1];\n return quadEval(a, quadControl(anchors, segIdx), b, localT);\n },\n toPath(anchors) {\n if (anchors.length < 2) {\n return { kind: 'polygon', commands: new Uint8Array(), coords: new Float32Array(), fillRule: 'nonzero' };\n }\n const cmds: number[] = [PATH_M];\n const xs: number[] = [anchors[0].x, anchors[0].y];\n for (let i = 0; i + 1 < anchors.length; i++) {\n const b = anchors[i + 1];\n const q = quadControl(anchors, i);\n cmds.push(PATH_Q);\n xs.push(q.x, q.y, b.x, b.y);\n }\n return {\n kind: 'polygon',\n commands: new Uint8Array(cmds),\n coords: new Float32Array(xs),\n fillRule: 'nonzero',\n };\n },\n curvatureAt(anchors, t) {\n if (anchors.length < 2) return 0;\n const { segIdx, localT } = segmentAt(anchors, t);\n const a = anchors[segIdx];\n const b = anchors[segIdx + 1];\n const p1 = quadControl(anchors, segIdx);\n const d1 = quadDeriv1(a, p1, b, localT);\n const d2 = quadDeriv2(a, p1, b);\n const num = d1.x * d2.y - d1.y * d2.x;\n const den = Math.pow(d1.x * d1.x + d1.y * d1.y, 1.5);\n if (den < 1e-12) return 0;\n return num / den;\n },\n discriminators(_anchors): Discriminator[] {\n // Quadratic has no user-facing controls — each segment's quadratic\n // control is fully determined by the cubic handles via midpoint.\n return [];\n },\n};\n","import type { CurveRepresentation, Discriminator, SharedAnchor } from './types';\nimport { PATH_L, PATH_M } from '../commands';\n\nconst DEGREE = 3;\nconst WEIGHT_MIN = 1e-3;\nconst WEIGHT_MAX = 8;\nconst FLATTEN_SAMPLES = 64;\n\n/** Build a uniform open knot vector. For n control points and degree p,\n * knot vector length is n + p + 1: the first p+1 knots are 0, the last\n * p+1 knots are 1, intermediate knots are evenly spaced. Standard\n * \"clamped\" form so the curve passes through first and last anchors. */\nfunction openUniformKnots(n: number, p = DEGREE): number[] {\n const m = n + p + 1;\n const knots: number[] = [];\n for (let i = 0; i < m; i++) {\n if (i <= p) knots.push(0);\n else if (i >= n) knots.push(1);\n else knots.push((i - p) / (n - p));\n }\n return knots;\n}\n\nfunction findSpan(n: number, p: number, u: number, knots: number[]): number {\n if (u >= knots[n]) return n - 1;\n if (u <= knots[p]) return p;\n let lo = p;\n let hi = n;\n let mid = (lo + hi) >> 1;\n while (u < knots[mid] || u >= knots[mid + 1]) {\n if (u < knots[mid]) hi = mid;\n else lo = mid;\n mid = (lo + hi) >> 1;\n }\n return mid;\n}\n\nfunction basisFunctions(i: number, u: number, p: number, knots: number[]): number[] {\n const N = new Array<number>(p + 1).fill(0);\n N[0] = 1;\n const left = new Array<number>(p + 1).fill(0);\n const right = new Array<number>(p + 1).fill(0);\n for (let j = 1; j <= p; j++) {\n left[j] = u - knots[i + 1 - j];\n right[j] = knots[i + j] - u;\n let saved = 0;\n for (let r = 0; r < j; r++) {\n const temp = N[r] / (right[r + 1] + left[j - r]);\n N[r] = saved + right[r + 1] * temp;\n saved = left[j - r] * temp;\n }\n N[j] = saved;\n }\n return N;\n}\n\nfunction weightOf(a: SharedAnchor): number {\n const w = a.weight ?? 1;\n return Math.max(WEIGHT_MIN, Math.min(WEIGHT_MAX, w));\n}\n\nfunction evalNurbs(anchors: SharedAnchor[], u: number): { x: number; y: number } {\n const n = anchors.length;\n if (n === 0) return { x: 0, y: 0 };\n if (n === 1) return { x: anchors[0].x, y: anchors[0].y };\n const p = Math.min(DEGREE, n - 1);\n const knots = openUniformKnots(n, p);\n const clamped = Math.min(Math.max(u, 0), 1);\n const span = findSpan(n, p, clamped, knots);\n const N = basisFunctions(span, clamped, p, knots);\n let wx = 0;\n let wy = 0;\n let wTotal = 0;\n for (let j = 0; j <= p; j++) {\n const idx = span - p + j;\n const a = anchors[idx];\n const w = weightOf(a);\n wx += N[j] * w * a.x;\n wy += N[j] * w * a.y;\n wTotal += N[j] * w;\n }\n if (wTotal < 1e-12) return { x: anchors[0].x, y: anchors[0].y };\n return { x: wx / wTotal, y: wy / wTotal };\n}\n\n/** NURBS: anchors act as weighted control points the curve is pulled toward rather than passing through. Flattened to line segments when converted to a path. */\nexport const nurbs: CurveRepresentation = {\n kind: 'nurbs',\n label: 'NURBS',\n evaluate(anchors, t) {\n return evalNurbs(anchors, t);\n },\n toPath(anchors) {\n if (anchors.length < 2) {\n return { kind: 'polygon', commands: new Uint8Array(), coords: new Float32Array(), fillRule: 'nonzero' };\n }\n const cmds: number[] = [PATH_M];\n const xs: number[] = [];\n for (let s = 0; s <= FLATTEN_SAMPLES; s++) {\n const t = s / FLATTEN_SAMPLES;\n const p = evalNurbs(anchors, t);\n xs.push(p.x, p.y);\n if (s > 0) cmds.push(PATH_L);\n }\n return {\n kind: 'polygon',\n commands: new Uint8Array(cmds),\n coords: new Float32Array(xs),\n fillRule: 'nonzero',\n };\n },\n curvatureAt(anchors, t) {\n if (anchors.length < 2) return 0;\n const eps = 1e-3;\n const t0 = Math.max(0, t - eps);\n const t1 = Math.min(1, t + eps);\n const p0 = evalNurbs(anchors, t0);\n const p2 = evalNurbs(anchors, t1);\n const pm = evalNurbs(anchors, t);\n const d1x = (p2.x - p0.x) / (t1 - t0);\n const d1y = (p2.y - p0.y) / (t1 - t0);\n const d2x = (p2.x - 2 * pm.x + p0.x) / (eps * eps);\n const d2y = (p2.y - 2 * pm.y + p0.y) / (eps * eps);\n const num = d1x * d2y - d1y * d2x;\n const den = Math.pow(d1x * d1x + d1y * d1y, 1.5);\n if (den < 1e-12) return 0;\n return num / den;\n },\n discriminators(anchors) {\n const out: Discriminator[] = [];\n for (let i = 0; i < anchors.length; i++) {\n out.push({\n kind: 'slider',\n label: `w${i}`,\n anchorIndex: i,\n field: 'weight',\n min: WEIGHT_MIN,\n max: WEIGHT_MAX,\n step: 0.1,\n value: weightOf(anchors[i]),\n });\n }\n return out;\n },\n};\n","// v1 Spiro: interpolating cubic spline with tangents computed from\n// neighbor positions for smooth anchors and pinned to incoming/outgoing\n// edges for corner anchors. This is NOT the full Raph Levien κ-curve\n// solver — that's a global numerical iteration. v1.1 swaps the real\n// Spiro in behind this same module surface.\nimport type { CurveRepresentation, Discriminator, SharedAnchor } from './types';\nimport { PATH_C, PATH_M } from '../commands';\nimport { cubicPointAt } from '../paths/cubicMath';\n\nconst TANGENT_SCALE = 1 / 3;\n\nfunction isCorner(a: SharedAnchor): boolean {\n return a.spiroType === 'corner';\n}\n\nfunction smoothTangent(anchors: SharedAnchor[], i: number): { x: number; y: number } | null {\n if (isCorner(anchors[i])) return null;\n const prev = i > 0 ? anchors[i - 1] : null;\n const next = i + 1 < anchors.length ? anchors[i + 1] : null;\n if (!prev && !next) return null;\n if (!prev) {\n return { x: next!.x - anchors[i].x, y: next!.y - anchors[i].y };\n }\n if (!next) {\n return { x: anchors[i].x - prev.x, y: anchors[i].y - prev.y };\n }\n const inDX = anchors[i].x - prev.x;\n const inDY = anchors[i].y - prev.y;\n const outDX = next.x - anchors[i].x;\n const outDY = next.y - anchors[i].y;\n const inLen = Math.hypot(inDX, inDY) || 1;\n const outLen = Math.hypot(outDX, outDY) || 1;\n return {\n x: inDX / inLen + outDX / outLen,\n y: inDY / inLen + outDY / outLen,\n };\n}\n\nfunction controlsFor(\n anchors: SharedAnchor[],\n i: number,\n): { c1: { x: number; y: number }; c2: { x: number; y: number } } {\n const a = anchors[i];\n const b = anchors[i + 1];\n const edge = { x: b.x - a.x, y: b.y - a.y };\n const edgeLen = Math.hypot(edge.x, edge.y) || 1;\n\n const tA = smoothTangent(anchors, i);\n const tB = smoothTangent(anchors, i + 1);\n\n const outA = tA ?? edge;\n const outB = tB ?? edge;\n\n const outALen = Math.hypot(outA.x, outA.y) || 1;\n const outBLen = Math.hypot(outB.x, outB.y) || 1;\n const handleLen = edgeLen * TANGENT_SCALE;\n return {\n c1: {\n x: a.x + (outA.x / outALen) * handleLen,\n y: a.y + (outA.y / outALen) * handleLen,\n },\n c2: {\n x: b.x - (outB.x / outBLen) * handleLen,\n y: b.y - (outB.y / outBLen) * handleLen,\n },\n };\n}\n\nfunction segmentAt(anchors: SharedAnchor[], t: number): { segIdx: number; localT: number } {\n if (anchors.length < 2) return { segIdx: 0, localT: 0 };\n const segments = anchors.length - 1;\n const scaled = Math.min(Math.max(t, 0), 1) * segments;\n const segIdx = Math.min(Math.floor(scaled), segments - 1);\n const localT = scaled - segIdx;\n return { segIdx, localT };\n}\n\n/** Spiro (κ-curves): curvature-continuous through each anchor, so joins stay visually smooth without hand-tuned handles. Approximated as cubics when converted to a path. */\nexport const spiro: CurveRepresentation = {\n kind: 'spiro',\n label: 'Spiro (κ-curves v1)',\n evaluate(anchors, t) {\n if (anchors.length < 2) return { x: anchors[0]?.x ?? 0, y: anchors[0]?.y ?? 0 };\n const { segIdx, localT } = segmentAt(anchors, t);\n const a = anchors[segIdx];\n const b = anchors[segIdx + 1];\n const { c1, c2 } = controlsFor(anchors, segIdx);\n return cubicPointAt(a, c1, c2, b, localT);\n },\n toPath(anchors) {\n if (anchors.length < 2) {\n return { kind: 'polygon', commands: new Uint8Array(), coords: new Float32Array(), fillRule: 'nonzero' };\n }\n const cmds: number[] = [PATH_M];\n const xs: number[] = [anchors[0].x, anchors[0].y];\n for (let i = 0; i + 1 < anchors.length; i++) {\n const b = anchors[i + 1];\n const { c1, c2 } = controlsFor(anchors, i);\n cmds.push(PATH_C);\n xs.push(c1.x, c1.y, c2.x, c2.y, b.x, b.y);\n }\n return {\n kind: 'polygon',\n commands: new Uint8Array(cmds),\n coords: new Float32Array(xs),\n fillRule: 'nonzero',\n };\n },\n curvatureAt(anchors, t) {\n if (anchors.length < 2) return 0;\n const { segIdx, localT } = segmentAt(anchors, t);\n const a = anchors[segIdx];\n const b = anchors[segIdx + 1];\n const { c1, c2 } = controlsFor(anchors, segIdx);\n const u = 1 - localT;\n const d1x = 3 * u * u * (c1.x - a.x) + 6 * u * localT * (c2.x - c1.x) + 3 * localT * localT * (b.x - c2.x);\n const d1y = 3 * u * u * (c1.y - a.y) + 6 * u * localT * (c2.y - c1.y) + 3 * localT * localT * (b.y - c2.y);\n const d2x = 6 * u * (c2.x - 2 * c1.x + a.x) + 6 * localT * (b.x - 2 * c2.x + c1.x);\n const d2y = 6 * u * (c2.y - 2 * c1.y + a.y) + 6 * localT * (b.y - 2 * c2.y + c1.y);\n const num = d1x * d2y - d1y * d2x;\n const den = Math.pow(d1x * d1x + d1y * d1y, 1.5);\n if (den < 1e-12) return 0;\n return num / den;\n },\n discriminators(anchors) {\n const out: Discriminator[] = [];\n for (let i = 0; i < anchors.length; i++) {\n out.push({\n kind: 'enum',\n label: `t${i}`,\n anchorIndex: i,\n field: 'spiroType',\n options: ['g2-smooth', 'g4-smooth', 'corner'] as const,\n value: anchors[i].spiroType ?? 'g2-smooth',\n });\n }\n return out;\n },\n};\n","export type { SharedAnchor, CurveRepKind, CurveRepresentation, Discriminator } from './types';\nexport { bezierCubic } from './bezierCubic';\nexport { bezierQuadratic } from './bezierQuadratic';\nexport { nurbs } from './nurbs';\nexport { spiro } from './spiro';\n\nimport { bezierCubic } from './bezierCubic';\nimport { bezierQuadratic } from './bezierQuadratic';\nimport { nurbs } from './nurbs';\nimport { spiro } from './spiro';\nimport type { CurveRepresentation, CurveRepKind } from './types';\n\n/** Every curve representation the kit ships, keyed by kind. */\nexport const CURVE_REPS: Readonly<Record<CurveRepKind, CurveRepresentation>> = {\n bezierCubic,\n bezierQuadratic,\n nurbs,\n spiro,\n};\n"]}