@weasel-js/geom 1.7.0 → 1.7.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.
- package/README.md +11 -1
- package/dist/3d/index.d.ts +17 -0
- package/dist/3d/index.js +3 -2
- package/dist/3d/index.js.map +1 -1
- package/dist/booleans/index.d.ts +90 -44
- package/dist/booleans/index.js +645 -5
- package/dist/booleans/index.js.map +1 -1
- package/dist/chunk-6T5I3PR5.js +172 -0
- package/dist/chunk-6T5I3PR5.js.map +1 -0
- package/dist/chunk-7ROQRYOA.js +29 -0
- package/dist/chunk-7ROQRYOA.js.map +1 -0
- package/dist/chunk-HEZTRG2M.js +55 -0
- package/dist/chunk-HEZTRG2M.js.map +1 -0
- package/dist/chunk-HPVINMOM.js +34 -0
- package/dist/chunk-HPVINMOM.js.map +1 -0
- package/dist/{chunk-36DHVSOV.js → chunk-RQYCDPU5.js} +36 -134
- package/dist/chunk-RQYCDPU5.js.map +1 -0
- package/dist/{chunk-3GFNUO4N.js → chunk-TXEGHCJ4.js} +3 -29
- package/dist/chunk-TXEGHCJ4.js.map +1 -0
- package/dist/chunk-URQMDR6Q.js +80 -0
- package/dist/chunk-URQMDR6Q.js.map +1 -0
- package/dist/cubicMath-CpCvuEl8.d.ts +37 -0
- package/dist/curves/index.d.ts +84 -0
- package/dist/curves/index.js +513 -0
- package/dist/curves/index.js.map +1 -0
- package/dist/index.d.ts +539 -2
- package/dist/index.js +1550 -60
- package/dist/index.js.map +1 -1
- package/dist/path-D0CoudGM.d.ts +45 -0
- package/dist/tessellate/index.d.ts +87 -0
- package/dist/tessellate/index.js +316 -0
- package/dist/tessellate/index.js.map +1 -0
- package/package.json +15 -2
- package/dist/chunk-36DHVSOV.js.map +0 -1
- package/dist/chunk-3GFNUO4N.js.map +0 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { cubicEvalAt, splitCubicAt } from './chunk-URQMDR6Q.js';
|
|
2
|
+
|
|
3
|
+
// src/paths/cubicMath.ts
|
|
4
|
+
function cubicPointAt(p0, p1, p2, p3, t) {
|
|
5
|
+
const [x, y] = cubicEvalAt(p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, t);
|
|
6
|
+
return { x, y };
|
|
7
|
+
}
|
|
8
|
+
function splitCubicAtT(p0, p1, p2, p3, t) {
|
|
9
|
+
const [l, r] = splitCubicAt(p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, t);
|
|
10
|
+
const quad = (c) => [{ x: c[0], y: c[1] }, { x: c[2], y: c[3] }, { x: c[4], y: c[5] }, { x: c[6], y: c[7] }];
|
|
11
|
+
return { left: quad(l), right: quad(r) };
|
|
12
|
+
}
|
|
13
|
+
function fitCubicThroughDeletion(prev, next) {
|
|
14
|
+
const dx = next.x - prev.x;
|
|
15
|
+
const dy = next.y - prev.y;
|
|
16
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
17
|
+
const c1DirX = prev.outHandle ? prev.outHandle.x - prev.x : dx;
|
|
18
|
+
const c1DirY = prev.outHandle ? prev.outHandle.y - prev.y : dy;
|
|
19
|
+
const c1 = controlOnSide(prev, c1DirX, c1DirY, dist, 1 / 3);
|
|
20
|
+
const c2DirX = next.inHandle ? next.inHandle.x - next.x : -dx;
|
|
21
|
+
const c2DirY = next.inHandle ? next.inHandle.y - next.y : -dy;
|
|
22
|
+
const c2 = controlOnSide(next, c2DirX, c2DirY, dist, 1 / 3);
|
|
23
|
+
return { c1, c2 };
|
|
24
|
+
}
|
|
25
|
+
function controlOnSide(anchor, dirX, dirY, dist, fraction) {
|
|
26
|
+
const targetDist = dist * fraction;
|
|
27
|
+
const len = Math.hypot(dirX, dirY) || 1;
|
|
28
|
+
const ux = dirX / len, uy = dirY / len;
|
|
29
|
+
return { x: anchor.x + ux * targetDist, y: anchor.y + uy * targetDist };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { cubicPointAt, fitCubicThroughDeletion, splitCubicAtT };
|
|
33
|
+
//# sourceMappingURL=chunk-HPVINMOM.js.map
|
|
34
|
+
//# sourceMappingURL=chunk-HPVINMOM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/paths/cubicMath.ts"],"names":[],"mappings":"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","file":"chunk-HPVINMOM.js","sourcesContent":["import { cubicEvalAt, splitCubicAt, type CubicCoords } from '../curve';\n\n/** A 2D point, the shape the point-taking path helpers read and return. */\nexport interface Point { x: number; y: number; }\n\n/** Point on the cubic Bezier (p0, p1, p2, p3) at parameter t. The point-shaped\n * face of geom's `cubicEvalAt`. */\nexport function cubicPointAt(p0: Point, p1: Point, p2: Point, p3: Point, t: number): Point {\n const [x, y] = cubicEvalAt(p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, t);\n return { x, y };\n}\n\ninterface AnchorRef {\n x: number; y: number;\n inHandle?: Point;\n outHandle?: Point;\n}\n\n/** De Casteljau subdivision of a cubic at parameter t. The point-shaped face\n * of geom's `splitCubicAt`; `left[3]` and `right[0]` are the point at t. */\nexport function splitCubicAtT(\n p0: Point, p1: Point, p2: Point, p3: Point,\n t: number,\n): { left: [Point, Point, Point, Point]; right: [Point, Point, Point, Point] } {\n const [l, r] = splitCubicAt(p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, t);\n const quad = (c: CubicCoords): [Point, Point, Point, Point] =>\n [{ x: c[0], y: c[1] }, { x: c[2], y: c[3] }, { x: c[4], y: c[5] }, { x: c[6], y: c[7] }];\n return { left: quad(l), right: quad(r) };\n}\n\n/**\n * When an interior anchor is deleted, the two flanking segments fuse into one\n * cubic. We pick controls c1 and c2 that:\n * - lie along prev's outHandle direction (if present)\n * - lie along next's inHandle direction (if present)\n * - are placed at roughly 1/3 and 2/3 of the prev→next distance\n * Fallbacks: missing handles use prev→next as the direction.\n *\n * This is an approximate fit — the new curve will shift slightly from the\n * original two-segment path. Acceptable per spec.\n */\nexport function fitCubicThroughDeletion(\n prev: AnchorRef,\n next: AnchorRef,\n): { c1: Point; c2: Point } {\n const dx = next.x - prev.x;\n const dy = next.y - prev.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n // c1: project along outHandle direction (or prev→next fallback) at 1/3 of dist.\n const c1DirX = prev.outHandle ? prev.outHandle.x - prev.x : dx;\n const c1DirY = prev.outHandle ? prev.outHandle.y - prev.y : dy;\n const c1 = controlOnSide(prev, c1DirX, c1DirY, dist, 1 / 3);\n // c2: project along inHandle direction (or next→prev fallback) at 1/3 of dist.\n const c2DirX = next.inHandle ? next.inHandle.x - next.x : -dx;\n const c2DirY = next.inHandle ? next.inHandle.y - next.y : -dy;\n const c2 = controlOnSide(next, c2DirX, c2DirY, dist, 1 / 3);\n return { c1, c2 };\n}\n\nfunction controlOnSide(\n anchor: AnchorRef,\n dirX: number,\n dirY: number,\n dist: number,\n fraction: number,\n): Point {\n const targetDist = dist * fraction;\n const len = Math.hypot(dirX, dirY) || 1;\n const ux = dirX / len, uy = dirY / len;\n return { x: anchor.x + ux * targetDist, y: anchor.y + uy * targetDist };\n}\n"]}
|
|
@@ -1,131 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
var PATH_COMMANDS = {
|
|
3
|
-
/** moveTo — opens a new subpath. */
|
|
4
|
-
M: { code: 0, coords: 2 },
|
|
5
|
-
/** Straight segment from the pen to the next coord pair. */
|
|
6
|
-
L: { code: 1, coords: 2 },
|
|
7
|
-
/** Cubic bezier: two control points then the endpoint. */
|
|
8
|
-
C: { code: 2, coords: 6 },
|
|
9
|
-
/** Quadratic bezier: one control point then the endpoint. */
|
|
10
|
-
Q: { code: 3, coords: 4 },
|
|
11
|
-
/** Close the current subpath back to its start. Consumes no coords and
|
|
12
|
-
* leaves the pen where it is. */
|
|
13
|
-
Z: { code: 4, coords: 0 }
|
|
14
|
-
};
|
|
15
|
-
var PATH_M = PATH_COMMANDS.M.code;
|
|
16
|
-
var PATH_L = PATH_COMMANDS.L.code;
|
|
17
|
-
var PATH_C = PATH_COMMANDS.C.code;
|
|
18
|
-
var PATH_Q = PATH_COMMANDS.Q.code;
|
|
19
|
-
var PATH_Z = PATH_COMMANDS.Z.code;
|
|
20
|
-
var PATH_CMD_LENGTHS = buildCmdLengths();
|
|
21
|
-
function buildCmdLengths() {
|
|
22
|
-
const lengths = [];
|
|
23
|
-
for (const { code, coords } of Object.values(PATH_COMMANDS)) lengths[code] = coords;
|
|
24
|
-
return lengths;
|
|
25
|
-
}
|
|
26
|
-
function pathCommandCoordCount(cmd) {
|
|
27
|
-
return PATH_CMD_LENGTHS[cmd];
|
|
28
|
-
}
|
|
29
|
-
function forEachSegment(commands, coords, visit) {
|
|
30
|
-
let ci = 0;
|
|
31
|
-
let px = 0, py = 0;
|
|
32
|
-
let startX = 0, startY = 0;
|
|
33
|
-
for (let i = 0; i < commands.length; i++) {
|
|
34
|
-
const cmd = commands[i];
|
|
35
|
-
if (visit(cmd, ci, px, py, i) === false) return;
|
|
36
|
-
const len = pathCommandCoordCount(cmd);
|
|
37
|
-
if (len === void 0) throw new Error(`forEachSegment: unknown command code ${cmd}`);
|
|
38
|
-
if (len > 0) {
|
|
39
|
-
px = coords[ci + len - 2];
|
|
40
|
-
py = coords[ci + len - 1];
|
|
41
|
-
ci += len;
|
|
42
|
-
if (cmd === PATH_M) {
|
|
43
|
-
startX = px;
|
|
44
|
-
startY = py;
|
|
45
|
-
}
|
|
46
|
-
} else if (cmd === PATH_Z) {
|
|
47
|
-
px = startX;
|
|
48
|
-
py = startY;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// src/curve.ts
|
|
54
|
-
function cubicEvalAt(x0, y0, x1, y1, x2, y2, x3, y3, t) {
|
|
55
|
-
const u = 1 - t;
|
|
56
|
-
const a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;
|
|
57
|
-
return [
|
|
58
|
-
a * x0 + b * x1 + c * x2 + d * x3,
|
|
59
|
-
a * y0 + b * y1 + c * y2 + d * y3
|
|
60
|
-
];
|
|
61
|
-
}
|
|
62
|
-
function elevateQuadraticToCubic(q0x, q0y, cx, cy, q1x, q1y) {
|
|
63
|
-
return [
|
|
64
|
-
q0x + 2 / 3 * (cx - q0x),
|
|
65
|
-
q0y + 2 / 3 * (cy - q0y),
|
|
66
|
-
q1x + 2 / 3 * (cx - q1x),
|
|
67
|
-
q1y + 2 / 3 * (cy - q1y)
|
|
68
|
-
];
|
|
69
|
-
}
|
|
70
|
-
function componentExtremaTs(p0, p1, p2, p3) {
|
|
71
|
-
const a = -p0 + 3 * p1 - 3 * p2 + p3;
|
|
72
|
-
const b = 2 * (p0 - 2 * p1 + p2);
|
|
73
|
-
const c = -p0 + p1;
|
|
74
|
-
const ts = [];
|
|
75
|
-
const push = (t) => {
|
|
76
|
-
if (t > 0 && t < 1) ts.push(t);
|
|
77
|
-
};
|
|
78
|
-
if (Math.abs(a) < 1e-12) {
|
|
79
|
-
if (Math.abs(b) > 1e-12) push(-c / b);
|
|
80
|
-
} else {
|
|
81
|
-
const disc = b * b - 4 * a * c;
|
|
82
|
-
if (disc >= 0) {
|
|
83
|
-
const sq = Math.sqrt(disc);
|
|
84
|
-
push((-b + sq) / (2 * a));
|
|
85
|
-
push((-b - sq) / (2 * a));
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return ts;
|
|
89
|
-
}
|
|
90
|
-
function cubicBounds(x0, y0, x1, y1, x2, y2, x3, y3) {
|
|
91
|
-
let minX = Math.min(x0, x3), maxX = Math.max(x0, x3);
|
|
92
|
-
let minY = Math.min(y0, y3), maxY = Math.max(y0, y3);
|
|
93
|
-
for (const t of componentExtremaTs(x0, x1, x2, x3)) {
|
|
94
|
-
const [ex] = cubicEvalAt(x0, y0, x1, y1, x2, y2, x3, y3, t);
|
|
95
|
-
if (ex < minX) minX = ex;
|
|
96
|
-
if (ex > maxX) maxX = ex;
|
|
97
|
-
}
|
|
98
|
-
for (const t of componentExtremaTs(y0, y1, y2, y3)) {
|
|
99
|
-
const [, ey] = cubicEvalAt(x0, y0, x1, y1, x2, y2, x3, y3, t);
|
|
100
|
-
if (ey < minY) minY = ey;
|
|
101
|
-
if (ey > maxY) maxY = ey;
|
|
102
|
-
}
|
|
103
|
-
return [minX, minY, maxX, maxY];
|
|
104
|
-
}
|
|
105
|
-
function quadraticEvalAt(x0, y0, x1, y1, x2, y2, t) {
|
|
106
|
-
const u = 1 - t;
|
|
107
|
-
const a = u * u, b = 2 * u * t, c = t * t;
|
|
108
|
-
return [a * x0 + b * x1 + c * x2, a * y0 + b * y1 + c * y2];
|
|
109
|
-
}
|
|
110
|
-
function splitCubicAt(x0, y0, x1, y1, x2, y2, x3, y3, t) {
|
|
111
|
-
const ax = x0 + (x1 - x0) * t, ay = y0 + (y1 - y0) * t;
|
|
112
|
-
const bx = x1 + (x2 - x1) * t, by = y1 + (y2 - y1) * t;
|
|
113
|
-
const cx = x2 + (x3 - x2) * t, cy = y2 + (y3 - y2) * t;
|
|
114
|
-
const dx = ax + (bx - ax) * t, dy = ay + (by - ay) * t;
|
|
115
|
-
const ex = bx + (cx - bx) * t, ey = by + (cy - by) * t;
|
|
116
|
-
const mx = dx + (ex - dx) * t, my = dy + (ey - dy) * t;
|
|
117
|
-
return [[x0, y0, ax, ay, dx, dy, mx, my], [mx, my, ex, ey, cx, cy, x3, y3]];
|
|
118
|
-
}
|
|
119
|
-
function splitQuadraticAt(x0, y0, x1, y1, x2, y2, t) {
|
|
120
|
-
const ax = x0 + (x1 - x0) * t, ay = y0 + (y1 - y0) * t;
|
|
121
|
-
const bx = x1 + (x2 - x1) * t, by = y1 + (y2 - y1) * t;
|
|
122
|
-
const mx = ax + (bx - ax) * t, my = ay + (by - ay) * t;
|
|
123
|
-
return [[x0, y0, ax, ay, mx, my], [mx, my, bx, by, x2, y2]];
|
|
124
|
-
}
|
|
125
|
-
function splitLineAt(x0, y0, x1, y1, t) {
|
|
126
|
-
const mx = x0 + (x1 - x0) * t, my = y0 + (y1 - y0) * t;
|
|
127
|
-
return [[x0, y0, mx, my], [mx, my, x1, y1]];
|
|
128
|
-
}
|
|
1
|
+
import { sign, len2, dot } from './chunk-7ROQRYOA.js';
|
|
129
2
|
|
|
130
3
|
// src/flatten.ts
|
|
131
4
|
var DEFAULT_FLATTEN_TOLERANCE = 0.5;
|
|
@@ -143,14 +16,14 @@ function finite8(a, b, c, d, e, f, g, h) {
|
|
|
143
16
|
function distPointToLine(px, py, ax, ay, bx, by) {
|
|
144
17
|
const dx = bx - ax;
|
|
145
18
|
const dy = by - ay;
|
|
146
|
-
const
|
|
147
|
-
if (
|
|
19
|
+
const len22 = dx * dx + dy * dy;
|
|
20
|
+
if (len22 === 0) {
|
|
148
21
|
const ex = px - ax;
|
|
149
22
|
const ey = py - ay;
|
|
150
23
|
return Math.sqrt(ex * ex + ey * ey);
|
|
151
24
|
}
|
|
152
25
|
const cross = (px - ax) * dy - (py - ay) * dx;
|
|
153
|
-
return Math.abs(cross) / Math.sqrt(
|
|
26
|
+
return Math.abs(cross) / Math.sqrt(len22);
|
|
154
27
|
}
|
|
155
28
|
function flattenCubic(x0, y0, x1, y1, x2, y2, x3, y3, tolerance, out) {
|
|
156
29
|
if (!finite8(x0, y0, x1, y1, x2, y2, x3, y3)) {
|
|
@@ -251,6 +124,35 @@ function flattenQuadraticArcRec(x0, y0, x1, y1, x2, y2, tolerance, out, arcOut,
|
|
|
251
124
|
return accum;
|
|
252
125
|
}
|
|
253
126
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
127
|
+
// src/polyline.ts
|
|
128
|
+
function pointInPolygon(coords, px, py, start = 0, end = coords.length >> 1) {
|
|
129
|
+
if (end - start < 3) return false;
|
|
130
|
+
let inside = false;
|
|
131
|
+
for (let i = start, j = end - 1; i < end; j = i++) {
|
|
132
|
+
const xi = coords[i * 2], yi = coords[i * 2 + 1];
|
|
133
|
+
const xj = coords[j * 2], yj = coords[j * 2 + 1];
|
|
134
|
+
const crosses = yi > py !== yj > py && px < (xj - xi) * (py - yi) / (yj - yi) + xi;
|
|
135
|
+
if (crosses) inside = !inside;
|
|
136
|
+
}
|
|
137
|
+
return inside;
|
|
138
|
+
}
|
|
139
|
+
function segmentsCross(ax, ay, bx, by, cx, cy, dx, dy) {
|
|
140
|
+
const d1 = sign((dx - cx) * (ay - cy) - (dy - cy) * (ax - cx));
|
|
141
|
+
const d2 = sign((dx - cx) * (by - cy) - (dy - cy) * (bx - cx));
|
|
142
|
+
const d3 = sign((bx - ax) * (cy - ay) - (by - ay) * (cx - ax));
|
|
143
|
+
const d4 = sign((bx - ax) * (dy - ay) - (by - ay) * (dx - ax));
|
|
144
|
+
return d1 !== d2 && d3 !== d4;
|
|
145
|
+
}
|
|
146
|
+
function pointSegmentDist2(px, py, ax, ay, bx, by) {
|
|
147
|
+
const vx = bx - ax, vy = by - ay;
|
|
148
|
+
const wx = px - ax, wy = py - ay;
|
|
149
|
+
const vv = len2(vx, vy);
|
|
150
|
+
let t = vv === 0 ? 0 : dot(wx, wy, vx, vy) / vv;
|
|
151
|
+
t = t < 0 ? 0 : t > 1 ? 1 : t;
|
|
152
|
+
const dx = px - (ax + t * vx), dy = py - (ay + t * vy);
|
|
153
|
+
return len2(dx, dy);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export { DEFAULT_FLATTEN_TOLERANCE, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, pointInPolygon, pointSegmentDist2, segmentsCross };
|
|
157
|
+
//# sourceMappingURL=chunk-RQYCDPU5.js.map
|
|
158
|
+
//# sourceMappingURL=chunk-RQYCDPU5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/flatten.ts","../src/polyline.ts"],"names":["len2"],"mappings":"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","file":"chunk-RQYCDPU5.js","sourcesContent":["/**\n * Bezier flattening — subdivide cubic and quadratic segments into polyline\n * approximations within a flatness tolerance. Used by hit-testing and\n * (eventually) any kernel that doesn't want to special-case curves.\n *\n * The flatness metric is the maximum perpendicular distance from any\n * control point to the chord between endpoints. When that distance falls\n * below `tolerance`, the segment is \"flat enough\" and emitted as a single\n * line segment.\n *\n * Tolerance is in world units. 0.5 is a sensible default for screen-rate\n * rendering at 1× zoom; consumers that zoom in heavily should pass a\n * tighter tolerance.\n */\n\nexport const DEFAULT_FLATTEN_TOLERANCE = 0.5;\n\n/** Floor for a non-positive or NaN tolerance. Without it the flatness test can\n * never be satisfied and the subdivision recurses until the stack blows. */\nconst MIN_FLATTEN_TOLERANCE = 1e-6;\n\n/** Subdivision ceiling. The tolerance floor bounds the common runaway; this\n * bounds the other one, coordinates large enough that reaching 1e-6 takes\n * hundreds of levels. Error falls roughly 4x per level, so 16 is far beyond\n * any tolerance a caller can mean. */\nconst MAX_FLATTEN_DEPTH = 16;\n\nfunction usableTolerance(tolerance: number): number {\n return tolerance > 0 ? tolerance : MIN_FLATTEN_TOLERANCE;\n}\n\nfunction finite6(a: number, b: number, c: number, d: number, e: number, f: number): boolean {\n return Number.isFinite(a) && Number.isFinite(b) && Number.isFinite(c)\n && Number.isFinite(d) && Number.isFinite(e) && Number.isFinite(f);\n}\n\nfunction finite8(\n a: number, b: number, c: number, d: number,\n e: number, f: number, g: number, h: number,\n): boolean {\n return finite6(a, b, c, d, e, f) && Number.isFinite(g) && Number.isFinite(h);\n}\n\n/** Distance from point P to line AB (perpendicular). */\nfunction distPointToLine(px: number, py: number, ax: number, ay: number, bx: number, by: number): number {\n const dx = bx - ax;\n const dy = by - ay;\n const len2 = dx * dx + dy * dy;\n if (len2 === 0) {\n const ex = px - ax;\n const ey = py - ay;\n return Math.sqrt(ex * ex + ey * ey);\n }\n const cross = (px - ax) * dy - (py - ay) * dx;\n return Math.abs(cross) / Math.sqrt(len2);\n}\n\n/**\n * Recursively subdivide a cubic bezier (P0..P3) and append `lineTo`-style\n * vertices to `out` (interleaved x,y). The starting endpoint is *not*\n * appended — callers usually emitted it as the segment's previous vertex.\n */\nexport function flattenCubic(\n x0: number, y0: number,\n x1: number, y1: number,\n x2: number, y2: number,\n x3: number, y3: number,\n tolerance: number,\n out: number[],\n): void {\n if (!finite8(x0, y0, x1, y1, x2, y2, x3, y3)) {\n out.push(x3, y3);\n return;\n }\n flattenCubicRec(x0, y0, x1, y1, x2, y2, x3, y3, usableTolerance(tolerance), out, 0);\n}\n\nfunction flattenCubicRec(\n x0: number, y0: number,\n x1: number, y1: number,\n x2: number, y2: number,\n x3: number, y3: number,\n tolerance: number,\n out: number[],\n depth: number,\n): void {\n const d1 = distPointToLine(x1, y1, x0, y0, x3, y3);\n const d2 = distPointToLine(x2, y2, x0, y0, x3, y3);\n if (Math.max(d1, d2) <= tolerance || depth >= MAX_FLATTEN_DEPTH) {\n out.push(x3, y3);\n return;\n }\n // De Casteljau split at t=0.5\n const x01 = (x0 + x1) * 0.5, y01 = (y0 + y1) * 0.5;\n const x12 = (x1 + x2) * 0.5, y12 = (y1 + y2) * 0.5;\n const x23 = (x2 + x3) * 0.5, y23 = (y2 + y3) * 0.5;\n const x012 = (x01 + x12) * 0.5, y012 = (y01 + y12) * 0.5;\n const x123 = (x12 + x23) * 0.5, y123 = (y12 + y23) * 0.5;\n const x0123 = (x012 + x123) * 0.5, y0123 = (y012 + y123) * 0.5;\n flattenCubicRec(x0, y0, x01, y01, x012, y012, x0123, y0123, tolerance, out, depth + 1);\n flattenCubicRec(x0123, y0123, x123, y123, x23, y23, x3, y3, tolerance, out, depth + 1);\n}\n\n/** Recursively subdivide a quadratic bezier (P0, P1, P2). */\nexport function flattenQuadratic(\n x0: number, y0: number,\n x1: number, y1: number,\n x2: number, y2: number,\n tolerance: number,\n out: number[],\n): void {\n if (!finite6(x0, y0, x1, y1, x2, y2)) {\n out.push(x2, y2);\n return;\n }\n flattenQuadraticRec(x0, y0, x1, y1, x2, y2, usableTolerance(tolerance), out, 0);\n}\n\nfunction flattenQuadraticRec(\n x0: number, y0: number,\n x1: number, y1: number,\n x2: number, y2: number,\n tolerance: number,\n out: number[],\n depth: number,\n): void {\n const d = distPointToLine(x1, y1, x0, y0, x2, y2);\n if (d <= tolerance || depth >= MAX_FLATTEN_DEPTH) {\n out.push(x2, y2);\n return;\n }\n const x01 = (x0 + x1) * 0.5, y01 = (y0 + y1) * 0.5;\n const x12 = (x1 + x2) * 0.5, y12 = (y1 + y2) * 0.5;\n const x012 = (x01 + x12) * 0.5, y012 = (y01 + y12) * 0.5;\n flattenQuadraticRec(x0, y0, x01, y01, x012, y012, tolerance, out, depth + 1);\n flattenQuadraticRec(x012, y012, x12, y12, x2, y2, tolerance, out, depth + 1);\n}\n\n/**\n * Like `flattenCubic` but also appends, for each new flattened point, its\n * arc-length fraction `t` (relative to the polyline distance accumulated so\n * far inside this curve) to `arcOut`. Caller then post-processes the segment's\n * `arcOut` range by dividing each by the segment's total flattened arc length\n * to yield t ∈ (0, 1].\n *\n * The returned values are *cumulative distance from the segment start*, not\n * normalized fractions. Two-pass design (accumulate, then divide) keeps the\n * recursive splitter simple — it doesn't need to know the total length up\n * front.\n */\nexport function flattenCubicWithArcLen(\n x0: number, y0: number,\n x1: number, y1: number,\n x2: number, y2: number,\n x3: number, y3: number,\n tolerance: number,\n out: number[],\n arcOut: number[],\n): number {\n if (!finite8(x0, y0, x1, y1, x2, y2, x3, y3)) {\n out.push(x3, y3);\n arcOut.push(0);\n return 0;\n }\n return flattenCubicArcRec(x0, y0, x1, y1, x2, y2, x3, y3, usableTolerance(tolerance), out, arcOut, 0, 0);\n}\n\nfunction flattenCubicArcRec(\n x0: number, y0: number,\n x1: number, y1: number,\n x2: number, y2: number,\n x3: number, y3: number,\n tolerance: number,\n out: number[],\n arcOut: number[],\n accum: number,\n depth: number,\n): number {\n const d1 = distPointToLine(x1, y1, x0, y0, x3, y3);\n const d2 = distPointToLine(x2, y2, x0, y0, x3, y3);\n if (Math.max(d1, d2) <= tolerance || depth >= MAX_FLATTEN_DEPTH) {\n const lastX = out.length >= 2 ? out[out.length - 2] : x0;\n const lastY = out.length >= 2 ? out[out.length - 1] : y0;\n const seg = Math.hypot(x3 - lastX, y3 - lastY);\n accum += seg;\n out.push(x3, y3);\n arcOut.push(accum);\n return accum;\n }\n const x01 = (x0 + x1) * 0.5, y01 = (y0 + y1) * 0.5;\n const x12 = (x1 + x2) * 0.5, y12 = (y1 + y2) * 0.5;\n const x23 = (x2 + x3) * 0.5, y23 = (y2 + y3) * 0.5;\n const x012 = (x01 + x12) * 0.5, y012 = (y01 + y12) * 0.5;\n const x123 = (x12 + x23) * 0.5, y123 = (y12 + y23) * 0.5;\n const x0123 = (x012 + x123) * 0.5, y0123 = (y012 + y123) * 0.5;\n accum = flattenCubicArcRec(x0, y0, x01, y01, x012, y012, x0123, y0123, tolerance, out, arcOut, accum, depth + 1);\n accum = flattenCubicArcRec(x0123, y0123, x123, y123, x23, y23, x3, y3, tolerance, out, arcOut, accum, depth + 1);\n return accum;\n}\n\n/** Flatten a quadratic bezier into line segments within `tolerance`, appending\n * points to `out` and their cumulative arc lengths to `arcOut`. The arc\n * lengths are what lets per-anchor color and dash phase be interpolated\n * evenly along the curve rather than per segment. */\nexport function flattenQuadraticWithArcLen(\n x0: number, y0: number,\n x1: number, y1: number,\n x2: number, y2: number,\n tolerance: number,\n out: number[],\n arcOut: number[],\n): number {\n if (!finite6(x0, y0, x1, y1, x2, y2)) {\n out.push(x2, y2);\n arcOut.push(0);\n return 0;\n }\n return flattenQuadraticArcRec(x0, y0, x1, y1, x2, y2, usableTolerance(tolerance), out, arcOut, 0, 0);\n}\n\nfunction flattenQuadraticArcRec(\n x0: number, y0: number,\n x1: number, y1: number,\n x2: number, y2: number,\n tolerance: number,\n out: number[],\n arcOut: number[],\n accum: number,\n depth: number,\n): number {\n const d = distPointToLine(x1, y1, x0, y0, x2, y2);\n if (d <= tolerance || depth >= MAX_FLATTEN_DEPTH) {\n const lastX = out.length >= 2 ? out[out.length - 2] : x0;\n const lastY = out.length >= 2 ? out[out.length - 1] : y0;\n const seg = Math.hypot(x2 - lastX, y2 - lastY);\n accum += seg;\n out.push(x2, y2);\n arcOut.push(accum);\n return accum;\n }\n const x01 = (x0 + x1) * 0.5, y01 = (y0 + y1) * 0.5;\n const x12 = (x1 + x2) * 0.5, y12 = (y1 + y2) * 0.5;\n const x012 = (x01 + x12) * 0.5, y012 = (y01 + y12) * 0.5;\n accum = flattenQuadraticArcRec(x0, y0, x01, y01, x012, y012, tolerance, out, arcOut, accum, depth + 1);\n accum = flattenQuadraticArcRec(x012, y012, x12, y12, x2, y2, tolerance, out, arcOut, accum, depth + 1);\n return accum;\n}\n\n","import { sign, dot, len2 } from './scalar';\n\n/**\n * Even-odd ray-cast point-in-polygon over an interleaved, unclosed contour\n * [x0,y0,x1,y1,…]. The closing edge (last→first) is implicit.\n *\n * `start`/`end` are vertex indices, not float offsets, and bound one contour\n * inside a buffer holding several.\n */\nexport function pointInPolygon(\n coords: ArrayLike<number>,\n px: number,\n py: number,\n start = 0,\n end = coords.length >> 1,\n): boolean {\n if (end - start < 3) return false;\n let inside = false;\n for (let i = start, j = end - 1; i < end; j = i++) {\n const xi = coords[i * 2], yi = coords[i * 2 + 1];\n const xj = coords[j * 2], yj = coords[j * 2 + 1];\n const crosses =\n (yi > py) !== (yj > py) &&\n px < ((xj - xi) * (py - yi)) / (yj - yi) + xi;\n if (crosses) inside = !inside;\n }\n return inside;\n}\n\n/**\n * True if segments (ax,ay)-(bx,by) and (cx,cy)-(dx,dy) intersect at a single\n * point. An endpoint landing on the other segment counts (a T-junction and a\n * shared endpoint both answer true) — hit-testing wants a grazing edge to\n * register. Collinear overlap answers false: there is no single crossing\n * point, so the sign test both segments rely on is zero on all four sides.\n */\nexport function segmentsCross(\n ax: number, ay: number, bx: number, by: number,\n cx: number, cy: number, dx: number, dy: number,\n): boolean {\n const d1 = sign((dx - cx) * (ay - cy) - (dy - cy) * (ax - cx));\n const d2 = sign((dx - cx) * (by - cy) - (dy - cy) * (bx - cx));\n const d3 = sign((bx - ax) * (cy - ay) - (by - ay) * (cx - ax));\n const d4 = sign((bx - ax) * (dy - ay) - (by - ay) * (dx - ax));\n return d1 !== d2 && d3 !== d4;\n}\n\n/** Squared distance from (px,py) to segment (ax,ay)-(bx,by), endpoint-clamped. */\nexport function pointSegmentDist2(\n px: number, py: number, ax: number, ay: number, bx: number, by: number,\n): number {\n const vx = bx - ax, vy = by - ay;\n const wx = px - ax, wy = py - ay;\n const vv = len2(vx, vy);\n let t = vv === 0 ? 0 : dot(wx, wy, vx, vy) / vv;\n t = t < 0 ? 0 : t > 1 ? 1 : t;\n const dx = px - (ax + t * vx), dy = py - (ay + t * vy);\n return len2(dx, dy);\n}\n"]}
|
|
@@ -1,29 +1,3 @@
|
|
|
1
|
-
// src/scalar.ts
|
|
2
|
-
var EPS = 1e-6;
|
|
3
|
-
var SINGULAR_RATIO = 1e-12;
|
|
4
|
-
function cross(ax, ay, bx, by) {
|
|
5
|
-
return ax * by - ay * bx;
|
|
6
|
-
}
|
|
7
|
-
function dot(ax, ay, bx, by) {
|
|
8
|
-
return ax * bx + ay * by;
|
|
9
|
-
}
|
|
10
|
-
function sub(ax, ay, bx, by) {
|
|
11
|
-
return [ax - bx, ay - by];
|
|
12
|
-
}
|
|
13
|
-
function len2(x, y) {
|
|
14
|
-
return x * x + y * y;
|
|
15
|
-
}
|
|
16
|
-
function sign(n) {
|
|
17
|
-
return n > 0 ? 1 : n < 0 ? -1 : 0;
|
|
18
|
-
}
|
|
19
|
-
function approxEq(a, b, eps = EPS) {
|
|
20
|
-
if (a === b) return true;
|
|
21
|
-
const diff = Math.abs(a - b);
|
|
22
|
-
if (!Number.isFinite(diff)) return false;
|
|
23
|
-
const scale = Math.max(1, Math.abs(a), Math.abs(b));
|
|
24
|
-
return diff <= eps * scale;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
1
|
// src/portCurve.ts
|
|
28
2
|
var PORT_REACH = 0.4;
|
|
29
3
|
function portControls(a, b, outNormal, inNormal, reach = PORT_REACH) {
|
|
@@ -56,6 +30,6 @@ function cubicAt(p0, p1, p2, p3, t) {
|
|
|
56
30
|
return out;
|
|
57
31
|
}
|
|
58
32
|
|
|
59
|
-
export {
|
|
60
|
-
//# sourceMappingURL=chunk-
|
|
61
|
-
//# sourceMappingURL=chunk-
|
|
33
|
+
export { PORT_REACH, cubicAt, portControls };
|
|
34
|
+
//# sourceMappingURL=chunk-TXEGHCJ4.js.map
|
|
35
|
+
//# sourceMappingURL=chunk-TXEGHCJ4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/portCurve.ts"],"names":[],"mappings":";AAaO,IAAM,UAAA,GAAa;AAWnB,SAAS,aACd,CAAA,EACA,CAAA,EACA,SAAA,EACA,QAAA,EACA,QAAgB,UAAA,EACM;AACtB,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AACjC,IAAA,MAAM,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAK,EAAE,CAAC,CAAA;AACrB,IAAA,GAAA,IAAO,CAAA,GAAI,CAAA;AAAA,EACb;AACA,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA,GAAI,KAAA;AAE9B,EAAA,MAAM,KAAe,EAAC;AACtB,EAAA,MAAM,KAAe,EAAC;AACtB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AACjC,IAAA,MAAM,EAAA,GAAK,EAAE,CAAC,CAAA;AACd,IAAA,MAAM,EAAA,GAAK,EAAE,CAAC,CAAA;AACd,IAAA,EAAA,CAAG,IAAA,CAAK,SAAA,IAAa,IAAA,GAAO,EAAA,GAAA,CAAM,EAAA,GAAK,EAAA,IAAM,KAAA,GAAQ,EAAA,GAAK,SAAA,CAAU,CAAC,CAAA,GAAK,IAAI,CAAA;AAC9E,IAAA,EAAA,CAAG,IAAA,CAAK,QAAA,IAAY,IAAA,GAAO,EAAA,GAAA,CAAM,EAAA,GAAK,EAAA,IAAM,KAAA,GAAQ,EAAA,GAAK,QAAA,CAAS,CAAC,CAAA,GAAK,IAAI,CAAA;AAAA,EAC9E;AACA,EAAA,OAAO,CAAC,IAAI,EAAE,CAAA;AAChB;AAGO,SAAS,OAAA,CACd,EAAA,EACA,EAAA,EACA,EAAA,EACA,IACA,CAAA,EACU;AACV,EAAA,MAAM,IAAI,CAAA,GAAI,CAAA;AACd,EAAA,MAAM,CAAA,GAAI,IAAI,CAAA,GAAI,CAAA;AAClB,EAAA,MAAM,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAA;AACtB,EAAA,MAAM,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAA;AACtB,EAAA,MAAM,CAAA,GAAI,IAAI,CAAA,GAAI,CAAA;AAClB,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,CAAG,QAAQ,CAAA,EAAA,EAAK;AAClC,IAAA,GAAA,CAAI,KAAK,CAAA,GAAI,EAAA,CAAG,CAAC,CAAA,GAAK,IAAI,EAAA,CAAG,CAAC,CAAA,GAAK,CAAA,GAAI,GAAG,CAAC,CAAA,GAAK,CAAA,GAAI,EAAA,CAAG,CAAC,CAAE,CAAA;AAAA,EAC5D;AACA,EAAA,OAAO,GAAA;AACT","file":"chunk-TXEGHCJ4.js","sourcesContent":["/**\n * The cubic control points that make a curve leave a port along its normal and\n * arrive at the next against that port's normal — what makes a routed edge read\n * as plugged into a box rather than aimed at it.\n *\n * The rule is stated once, over loose components, and the 2D barrel and `./3d`\n * each wrap it in their own currency. Every operation here is closed on the\n * plane z = 0, so a planar problem answered through the 3D wrapper returns the\n * same numbers as through the 2D one, not an approximation of them.\n */\n\n/** How far a control point reaches toward the other end, as a fraction of the\n * straight-line distance between the two. */\nexport const PORT_REACH = 0.4;\n\n/**\n * `[c1, c2]` for the cubic from `a` to `b`.\n *\n * A null normal falls back to a plain lerp along the chord, which is what makes\n * an unported waypoint curve smoothly instead of kinking. The two ends are not\n * symmetric: `outNormal` points the way the curve departs, while `inNormal`\n * points out of the receiving port, so `c2` is pushed *along* it to arrive\n * against it.\n */\nexport function portControls(\n a: readonly number[],\n b: readonly number[],\n outNormal: readonly number[] | null | undefined,\n inNormal: readonly number[] | null | undefined,\n reach: number = PORT_REACH,\n): [number[], number[]] {\n let sum = 0;\n for (let i = 0; i < a.length; i++) {\n const d = b[i]! - a[i]!;\n sum += d * d;\n }\n const span = Math.sqrt(sum) * reach;\n\n const c1: number[] = [];\n const c2: number[] = [];\n for (let i = 0; i < a.length; i++) {\n const ai = a[i]!;\n const bi = b[i]!;\n c1.push(outNormal == null ? ai + (bi - ai) * reach : ai + outNormal[i]! * span);\n c2.push(inNormal == null ? bi - (bi - ai) * reach : bi + inNormal[i]! * span);\n }\n return [c1, c2];\n}\n\n/** A cubic evaluated at `t`, component-wise, in whatever dimension it was given. */\nexport function cubicAt(\n p0: readonly number[],\n p1: readonly number[],\n p2: readonly number[],\n p3: readonly number[],\n t: number,\n): number[] {\n const u = 1 - t;\n const a = u * u * u;\n const b = 3 * u * u * t;\n const c = 3 * u * t * t;\n const d = t * t * t;\n const out: number[] = [];\n for (let i = 0; i < p0.length; i++) {\n out.push(a * p0[i]! + b * p1[i]! + c * p2[i]! + d * p3[i]!);\n }\n return out;\n}\n"]}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// src/curve.ts
|
|
2
|
+
function cubicEvalAt(x0, y0, x1, y1, x2, y2, x3, y3, t) {
|
|
3
|
+
const u = 1 - t;
|
|
4
|
+
const a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;
|
|
5
|
+
return [
|
|
6
|
+
a * x0 + b * x1 + c * x2 + d * x3,
|
|
7
|
+
a * y0 + b * y1 + c * y2 + d * y3
|
|
8
|
+
];
|
|
9
|
+
}
|
|
10
|
+
function elevateQuadraticToCubic(q0x, q0y, cx, cy, q1x, q1y) {
|
|
11
|
+
return [
|
|
12
|
+
q0x + 2 / 3 * (cx - q0x),
|
|
13
|
+
q0y + 2 / 3 * (cy - q0y),
|
|
14
|
+
q1x + 2 / 3 * (cx - q1x),
|
|
15
|
+
q1y + 2 / 3 * (cy - q1y)
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
function componentExtremaTs(p0, p1, p2, p3) {
|
|
19
|
+
const a = -p0 + 3 * p1 - 3 * p2 + p3;
|
|
20
|
+
const b = 2 * (p0 - 2 * p1 + p2);
|
|
21
|
+
const c = -p0 + p1;
|
|
22
|
+
const ts = [];
|
|
23
|
+
const push = (t) => {
|
|
24
|
+
if (t > 0 && t < 1) ts.push(t);
|
|
25
|
+
};
|
|
26
|
+
if (Math.abs(a) < 1e-12) {
|
|
27
|
+
if (Math.abs(b) > 1e-12) push(-c / b);
|
|
28
|
+
} else {
|
|
29
|
+
const disc = b * b - 4 * a * c;
|
|
30
|
+
if (disc >= 0) {
|
|
31
|
+
const sq = Math.sqrt(disc);
|
|
32
|
+
push((-b + sq) / (2 * a));
|
|
33
|
+
push((-b - sq) / (2 * a));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return ts;
|
|
37
|
+
}
|
|
38
|
+
function cubicBounds(x0, y0, x1, y1, x2, y2, x3, y3) {
|
|
39
|
+
let minX = Math.min(x0, x3), maxX = Math.max(x0, x3);
|
|
40
|
+
let minY = Math.min(y0, y3), maxY = Math.max(y0, y3);
|
|
41
|
+
for (const t of componentExtremaTs(x0, x1, x2, x3)) {
|
|
42
|
+
const [ex] = cubicEvalAt(x0, y0, x1, y1, x2, y2, x3, y3, t);
|
|
43
|
+
if (ex < minX) minX = ex;
|
|
44
|
+
if (ex > maxX) maxX = ex;
|
|
45
|
+
}
|
|
46
|
+
for (const t of componentExtremaTs(y0, y1, y2, y3)) {
|
|
47
|
+
const [, ey] = cubicEvalAt(x0, y0, x1, y1, x2, y2, x3, y3, t);
|
|
48
|
+
if (ey < minY) minY = ey;
|
|
49
|
+
if (ey > maxY) maxY = ey;
|
|
50
|
+
}
|
|
51
|
+
return [minX, minY, maxX, maxY];
|
|
52
|
+
}
|
|
53
|
+
function quadraticEvalAt(x0, y0, x1, y1, x2, y2, t) {
|
|
54
|
+
const u = 1 - t;
|
|
55
|
+
const a = u * u, b = 2 * u * t, c = t * t;
|
|
56
|
+
return [a * x0 + b * x1 + c * x2, a * y0 + b * y1 + c * y2];
|
|
57
|
+
}
|
|
58
|
+
function splitCubicAt(x0, y0, x1, y1, x2, y2, x3, y3, t) {
|
|
59
|
+
const ax = x0 + (x1 - x0) * t, ay = y0 + (y1 - y0) * t;
|
|
60
|
+
const bx = x1 + (x2 - x1) * t, by = y1 + (y2 - y1) * t;
|
|
61
|
+
const cx = x2 + (x3 - x2) * t, cy = y2 + (y3 - y2) * t;
|
|
62
|
+
const dx = ax + (bx - ax) * t, dy = ay + (by - ay) * t;
|
|
63
|
+
const ex = bx + (cx - bx) * t, ey = by + (cy - by) * t;
|
|
64
|
+
const mx = dx + (ex - dx) * t, my = dy + (ey - dy) * t;
|
|
65
|
+
return [[x0, y0, ax, ay, dx, dy, mx, my], [mx, my, ex, ey, cx, cy, x3, y3]];
|
|
66
|
+
}
|
|
67
|
+
function splitQuadraticAt(x0, y0, x1, y1, x2, y2, t) {
|
|
68
|
+
const ax = x0 + (x1 - x0) * t, ay = y0 + (y1 - y0) * t;
|
|
69
|
+
const bx = x1 + (x2 - x1) * t, by = y1 + (y2 - y1) * t;
|
|
70
|
+
const mx = ax + (bx - ax) * t, my = ay + (by - ay) * t;
|
|
71
|
+
return [[x0, y0, ax, ay, mx, my], [mx, my, bx, by, x2, y2]];
|
|
72
|
+
}
|
|
73
|
+
function splitLineAt(x0, y0, x1, y1, t) {
|
|
74
|
+
const mx = x0 + (x1 - x0) * t, my = y0 + (y1 - y0) * t;
|
|
75
|
+
return [[x0, y0, mx, my], [mx, my, x1, y1]];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export { cubicBounds, cubicEvalAt, elevateQuadraticToCubic, quadraticEvalAt, splitCubicAt, splitLineAt, splitQuadraticAt };
|
|
79
|
+
//# sourceMappingURL=chunk-URQMDR6Q.js.map
|
|
80
|
+
//# sourceMappingURL=chunk-URQMDR6Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/curve.ts"],"names":[],"mappings":"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","file":"chunk-URQMDR6Q.js","sourcesContent":["import type { Box } from './box';\n\n/** Cubic Bezier point at parameter t (de Casteljau / Bernstein form). */\nexport function cubicEvalAt(\n x0: number, y0: number, x1: number, y1: number,\n x2: number, y2: number, x3: number, y3: number, t: number,\n): [number, number] {\n const u = 1 - t;\n const a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;\n return [\n a * x0 + b * x1 + c * x2 + d * x3,\n a * y0 + b * y1 + c * y2 + d * y3,\n ];\n}\n\n/**\n * Degree-elevate a quadratic (q0, ctrl, q1) to a cubic. Returns the two\n * cubic control points [c1x, c1y, c2x, c2y]; the cubic endpoints equal the\n * quadratic endpoints. c1 = q0 + 2/3(ctrl-q0), c2 = q1 + 2/3(ctrl-q1).\n */\nexport function elevateQuadraticToCubic(\n q0x: number, q0y: number, cx: number, cy: number, q1x: number, q1y: number,\n): [number, number, number, number] {\n return [\n q0x + (2 / 3) * (cx - q0x),\n q0y + (2 / 3) * (cy - q0y),\n q1x + (2 / 3) * (cx - q1x),\n q1y + (2 / 3) * (cy - q1y),\n ];\n}\n\n/** Axis-aligned extrema parameters of one cubic component (the 0,1 ends plus\n * any derivative roots in (0,1)). Used by cubicBounds. */\nfunction componentExtremaTs(p0: number, p1: number, p2: number, p3: number): number[] {\n // B'(t)=0 → quadratic a t² + b t + c = 0 with:\n const a = -p0 + 3 * p1 - 3 * p2 + p3;\n const b = 2 * (p0 - 2 * p1 + p2);\n const c = -p0 + p1;\n const ts: number[] = [];\n const push = (t: number) => { if (t > 0 && t < 1) ts.push(t); };\n if (Math.abs(a) < 1e-12) {\n if (Math.abs(b) > 1e-12) push(-c / b);\n } else {\n const disc = b * b - 4 * a * c;\n if (disc >= 0) {\n const sq = Math.sqrt(disc);\n push((-b + sq) / (2 * a));\n push((-b - sq) / (2 * a));\n }\n }\n return ts;\n}\n\n/** Tight AABB of a cubic, evaluating only extrema that lie on the curve. */\nexport function cubicBounds(\n x0: number, y0: number, x1: number, y1: number,\n x2: number, y2: number, x3: number, y3: number,\n): Box {\n let minX = Math.min(x0, x3), maxX = Math.max(x0, x3);\n let minY = Math.min(y0, y3), maxY = Math.max(y0, y3);\n for (const t of componentExtremaTs(x0, x1, x2, x3)) {\n const [ex] = cubicEvalAt(x0, y0, x1, y1, x2, y2, x3, y3, t);\n if (ex < minX) minX = ex;\n if (ex > maxX) maxX = ex;\n }\n for (const t of componentExtremaTs(y0, y1, y2, y3)) {\n const [, ey] = cubicEvalAt(x0, y0, x1, y1, x2, y2, x3, y3, t);\n if (ey < minY) minY = ey;\n if (ey > maxY) maxY = ey;\n }\n return [minX, minY, maxX, maxY];\n}\n\n/** Quadratic Bezier point at parameter t (Bernstein form). */\nexport function quadraticEvalAt(\n x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, t: number,\n): [number, number] {\n const u = 1 - t;\n const a = u * u, b = 2 * u * t, c = t * t;\n return [a * x0 + b * x1 + c * x2, a * y0 + b * y1 + c * y2];\n}\n\n/** A line segment's coords: start, end. */\nexport type LineCoords = [number, number, number, number];\n/** A quadratic Bezier's coords: start, control, end. */\nexport type QuadraticCoords = [number, number, number, number, number, number];\n/** A cubic Bezier's coords: start, two controls, end. */\nexport type CubicCoords = [number, number, number, number, number, number, number, number];\n\n/**\n * Split a cubic at parameter t (de Casteljau). The two halves share the point\n * at t and together trace the original exactly. A t outside [0, 1] splits the\n * curve's polynomial extension.\n */\nexport function splitCubicAt(\n x0: number, y0: number, x1: number, y1: number,\n x2: number, y2: number, x3: number, y3: number, t: number,\n): [CubicCoords, CubicCoords] {\n const ax = x0 + (x1 - x0) * t, ay = y0 + (y1 - y0) * t;\n const bx = x1 + (x2 - x1) * t, by = y1 + (y2 - y1) * t;\n const cx = x2 + (x3 - x2) * t, cy = y2 + (y3 - y2) * t;\n const dx = ax + (bx - ax) * t, dy = ay + (by - ay) * t;\n const ex = bx + (cx - bx) * t, ey = by + (cy - by) * t;\n const mx = dx + (ex - dx) * t, my = dy + (ey - dy) * t;\n return [[x0, y0, ax, ay, dx, dy, mx, my], [mx, my, ex, ey, cx, cy, x3, y3]];\n}\n\n/** Split a quadratic at parameter t (de Casteljau). See {@link splitCubicAt}. */\nexport function splitQuadraticAt(\n x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, t: number,\n): [QuadraticCoords, QuadraticCoords] {\n const ax = x0 + (x1 - x0) * t, ay = y0 + (y1 - y0) * t;\n const bx = x1 + (x2 - x1) * t, by = y1 + (y2 - y1) * t;\n const mx = ax + (bx - ax) * t, my = ay + (by - ay) * t;\n return [[x0, y0, ax, ay, mx, my], [mx, my, bx, by, x2, y2]];\n}\n\n/** Split a line segment at parameter t. See {@link splitCubicAt}. */\nexport function splitLineAt(\n x0: number, y0: number, x1: number, y1: number, t: number,\n): [LineCoords, LineCoords] {\n const mx = x0 + (x1 - x0) * t, my = y0 + (y1 - y0) * t;\n return [[x0, y0, mx, my], [mx, my, x1, y1]];\n}\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** A 2D point, the shape the point-taking path helpers read and return. */
|
|
2
|
+
interface Point {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
}
|
|
6
|
+
/** Point on the cubic Bezier (p0, p1, p2, p3) at parameter t. The point-shaped
|
|
7
|
+
* face of geom's `cubicEvalAt`. */
|
|
8
|
+
declare function cubicPointAt(p0: Point, p1: Point, p2: Point, p3: Point, t: number): Point;
|
|
9
|
+
interface AnchorRef {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
inHandle?: Point;
|
|
13
|
+
outHandle?: Point;
|
|
14
|
+
}
|
|
15
|
+
/** De Casteljau subdivision of a cubic at parameter t. The point-shaped face
|
|
16
|
+
* of geom's `splitCubicAt`; `left[3]` and `right[0]` are the point at t. */
|
|
17
|
+
declare function splitCubicAtT(p0: Point, p1: Point, p2: Point, p3: Point, t: number): {
|
|
18
|
+
left: [Point, Point, Point, Point];
|
|
19
|
+
right: [Point, Point, Point, Point];
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* When an interior anchor is deleted, the two flanking segments fuse into one
|
|
23
|
+
* cubic. We pick controls c1 and c2 that:
|
|
24
|
+
* - lie along prev's outHandle direction (if present)
|
|
25
|
+
* - lie along next's inHandle direction (if present)
|
|
26
|
+
* - are placed at roughly 1/3 and 2/3 of the prev→next distance
|
|
27
|
+
* Fallbacks: missing handles use prev→next as the direction.
|
|
28
|
+
*
|
|
29
|
+
* This is an approximate fit — the new curve will shift slightly from the
|
|
30
|
+
* original two-segment path. Acceptable per spec.
|
|
31
|
+
*/
|
|
32
|
+
declare function fitCubicThroughDeletion(prev: AnchorRef, next: AnchorRef): {
|
|
33
|
+
c1: Point;
|
|
34
|
+
c2: Point;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export { type Point as P, cubicPointAt as c, fitCubicThroughDeletion as f, splitCubicAtT as s };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { a as PolygonPath } from '../path-D0CoudGM.js';
|
|
2
|
+
|
|
3
|
+
/** A point in the shared anchor set. Every representation reads only the
|
|
4
|
+
* fields it cares about: cubic Bezier reads inHandle/outHandle; NURBS
|
|
5
|
+
* reads weight; Spiro reads spiroType. Edits to position propagate to
|
|
6
|
+
* every representation; edits to per-rep fields only affect that rep. */
|
|
7
|
+
interface SharedAnchor {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
/** Cubic Bezier tangent handles in world coords. Default undefined =
|
|
11
|
+
* smooth (handles auto-derived from neighbors). */
|
|
12
|
+
inHandle?: {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
};
|
|
16
|
+
outHandle?: {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
};
|
|
20
|
+
/** NURBS rational weight. Default 1 (non-rational B-spline). Clamped
|
|
21
|
+
* ≥ 1e-3 by the UI. */
|
|
22
|
+
weight?: number;
|
|
23
|
+
/** Spiro continuity class at this anchor. Default 'g2-smooth'. */
|
|
24
|
+
spiroType?: 'corner' | 'g2-smooth' | 'g4-smooth';
|
|
25
|
+
}
|
|
26
|
+
/** Which curve representation an anchor set is interpreted through. */
|
|
27
|
+
type CurveRepKind = 'bezierCubic' | 'bezierQuadratic' | 'nurbs' | 'spiro';
|
|
28
|
+
/** A user-facing control surfaced by a representation. Rendered uniformly
|
|
29
|
+
* by the demo's panel sidebar. */
|
|
30
|
+
type Discriminator = {
|
|
31
|
+
kind: 'slider';
|
|
32
|
+
label: string;
|
|
33
|
+
anchorIndex: number;
|
|
34
|
+
field: string;
|
|
35
|
+
min: number;
|
|
36
|
+
max: number;
|
|
37
|
+
step: number;
|
|
38
|
+
value: number;
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'enum';
|
|
41
|
+
label: string;
|
|
42
|
+
anchorIndex: number;
|
|
43
|
+
field: string;
|
|
44
|
+
options: readonly string[];
|
|
45
|
+
value: string;
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'handle';
|
|
48
|
+
anchorIndex: number;
|
|
49
|
+
which: 'in' | 'out';
|
|
50
|
+
};
|
|
51
|
+
/** A curve representation. Same anchor set rendered four ways. */
|
|
52
|
+
interface CurveRepresentation {
|
|
53
|
+
kind: CurveRepKind;
|
|
54
|
+
label: string;
|
|
55
|
+
/** Evaluate the curve at parameter `t ∈ [0, 1]`. */
|
|
56
|
+
evaluate(anchors: SharedAnchor[], t: number): {
|
|
57
|
+
x: number;
|
|
58
|
+
y: number;
|
|
59
|
+
};
|
|
60
|
+
/** Convert anchors to a kit PolygonPath for the renderer. */
|
|
61
|
+
toPath(anchors: SharedAnchor[]): PolygonPath;
|
|
62
|
+
/** Signed local curvature at parameter `t`. Drives the curvature-comb
|
|
63
|
+
* overlay; positive curls left, negative curls right. */
|
|
64
|
+
curvatureAt(anchors: SharedAnchor[], t: number): number;
|
|
65
|
+
/** Per-rep controls (handle drag enables, weight sliders, type pickers). */
|
|
66
|
+
discriminators(anchors: SharedAnchor[]): Discriminator[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Cubic bezier: each segment takes two control handles. The familiar pen-tool curve, and what SVG path data stores natively. */
|
|
70
|
+
declare const bezierCubic: CurveRepresentation;
|
|
71
|
+
|
|
72
|
+
/** Quadratic bezier: one control point per segment. Cheaper than cubic and what TrueType glyph outlines use, at the cost of expressiveness. */
|
|
73
|
+
declare const bezierQuadratic: CurveRepresentation;
|
|
74
|
+
|
|
75
|
+
/** 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. */
|
|
76
|
+
declare const nurbs: CurveRepresentation;
|
|
77
|
+
|
|
78
|
+
/** Spiro (κ-curves): curvature-continuous through each anchor, so joins stay visually smooth without hand-tuned handles. Approximated as cubics when converted to a path. */
|
|
79
|
+
declare const spiro: CurveRepresentation;
|
|
80
|
+
|
|
81
|
+
/** Every curve representation the kit ships, keyed by kind. */
|
|
82
|
+
declare const CURVE_REPS: Readonly<Record<CurveRepKind, CurveRepresentation>>;
|
|
83
|
+
|
|
84
|
+
export { CURVE_REPS, type CurveRepKind, type CurveRepresentation, type Discriminator, type SharedAnchor, bezierCubic, bezierQuadratic, nurbs, spiro };
|