@weasel-js/geom 1.15.1 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/3d/index.d.ts +16 -2
- package/dist/3d/index.js +17 -10
- package/dist/3d/index.js.map +1 -1
- package/dist/booleans/index.js +5 -5
- package/dist/{chunk-B3D6KWW3.js → chunk-346XYYMX.js} +154 -3
- package/dist/chunk-346XYYMX.js.map +1 -0
- package/dist/{chunk-FROQPADA.js → chunk-5W425HJA.js} +82 -16
- package/dist/chunk-5W425HJA.js.map +1 -0
- package/dist/chunk-DNX24KBT.js +82 -0
- package/dist/chunk-DNX24KBT.js.map +1 -0
- package/dist/chunk-FOXMA54X.js +266 -0
- package/dist/chunk-FOXMA54X.js.map +1 -0
- package/dist/{chunk-3HQJGI63.js → chunk-HTT5AQIU.js} +3 -4
- package/dist/chunk-HTT5AQIU.js.map +1 -0
- package/dist/chunk-IOD2NFHQ.js +212 -0
- package/dist/chunk-IOD2NFHQ.js.map +1 -0
- package/dist/{chunk-HNLJO3E7.js → chunk-MOCSUHEI.js} +22 -8
- package/dist/chunk-MOCSUHEI.js.map +1 -0
- package/dist/{chunk-3YH5XU3H.js → chunk-OBPXEPUH.js} +14 -23
- package/dist/chunk-OBPXEPUH.js.map +1 -0
- package/dist/chunk-QSVZO7QZ.js +40 -0
- package/dist/chunk-QSVZO7QZ.js.map +1 -0
- package/dist/{chunk-EURWZUNY.js → chunk-TBS4NHGQ.js} +70 -93
- package/dist/chunk-TBS4NHGQ.js.map +1 -0
- package/dist/{chunk-HMGGJZTM.js → chunk-VJG5ZWCR.js} +7 -21
- package/dist/chunk-VJG5ZWCR.js.map +1 -0
- package/dist/{chunk-ZOMUTU7J.js → chunk-ZV24QZ6X.js} +5 -11
- package/dist/chunk-ZV24QZ6X.js.map +1 -0
- package/dist/{curvature-CDOI32hv.d.ts → curvature-DKPO4Qeh.d.ts} +0 -27
- package/dist/curves/index.d.ts +1 -1
- package/dist/curves/index.js +4 -4
- package/dist/index.d.ts +193 -13
- package/dist/index.js +409 -273
- package/dist/index.js.map +1 -1
- package/dist/lengthTable-Cv3W6lsH.d.ts +64 -0
- package/dist/nd/index.d.ts +28 -1
- package/dist/nd/index.js +2 -5
- package/dist/nd/index.js.map +1 -1
- package/dist/tessellate/index.d.ts +23 -1
- package/dist/tessellate/index.js +31 -17
- package/dist/tessellate/index.js.map +1 -1
- package/dist/warp/index.js +9 -15
- package/dist/warp/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-2N6OWA7E.js +0 -104
- package/dist/chunk-2N6OWA7E.js.map +0 -1
- package/dist/chunk-3HQJGI63.js.map +0 -1
- package/dist/chunk-3YH5XU3H.js.map +0 -1
- package/dist/chunk-755Y4YZS.js +0 -32
- package/dist/chunk-755Y4YZS.js.map +0 -1
- package/dist/chunk-B3D6KWW3.js.map +0 -1
- package/dist/chunk-EURWZUNY.js.map +0 -1
- package/dist/chunk-FROQPADA.js.map +0 -1
- package/dist/chunk-HMGGJZTM.js.map +0 -1
- package/dist/chunk-HNLJO3E7.js.map +0 -1
- package/dist/chunk-ZOMUTU7J.js.map +0 -1
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { segmentCoords, bezierDirection, bezierPoint } from './chunk-QSVZO7QZ.js';
|
|
2
|
+
import { arcLookup, segmentLength, lookupT } from './chunk-IOD2NFHQ.js';
|
|
3
|
+
|
|
4
|
+
// src/along/lengthTable.ts
|
|
5
|
+
var INTERNALS = /* @__PURE__ */ Symbol("lengthTable.internals");
|
|
6
|
+
function lengthTable(runs, dim, anchorSources) {
|
|
7
|
+
const runStart = new Float64Array(runs.length + 1);
|
|
8
|
+
const cum = [];
|
|
9
|
+
let total = 0;
|
|
10
|
+
runs.forEach((run, r) => {
|
|
11
|
+
const c = runLengths(run, dim, total);
|
|
12
|
+
cum.push(c);
|
|
13
|
+
total = c[c.length - 1];
|
|
14
|
+
runStart[r + 1] = total;
|
|
15
|
+
});
|
|
16
|
+
const anchors = anchorBreakpoints(runs, dim, cum, anchorSources ?? null);
|
|
17
|
+
const table = { dim, runs, total, runStart, segments: anchors.segments };
|
|
18
|
+
table[INTERNALS] = { cum, ...anchors, arcs: runs.map(() => []) };
|
|
19
|
+
return table;
|
|
20
|
+
}
|
|
21
|
+
function segmentArc(t, r, i) {
|
|
22
|
+
const ctl = t.runs[r].controls?.[i];
|
|
23
|
+
if (!ctl || ctl.length === 0) return null;
|
|
24
|
+
const arcs = tableInternals(t).arcs[r];
|
|
25
|
+
let arc = arcs[i];
|
|
26
|
+
if (!arc) {
|
|
27
|
+
const coords = segmentCoords(t.runs[r].points, ctl, t.dim, i);
|
|
28
|
+
arcs[i] = arc = { coords, lookup: arcLookup(coords, t.dim) };
|
|
29
|
+
}
|
|
30
|
+
return arc;
|
|
31
|
+
}
|
|
32
|
+
function tableInternals(t) {
|
|
33
|
+
const hit = t[INTERNALS];
|
|
34
|
+
if (!hit) throw new Error("LengthTable: not built by lengthTable(); build one with it rather than by hand");
|
|
35
|
+
return hit;
|
|
36
|
+
}
|
|
37
|
+
function lengthAtAnchor(t, anchor) {
|
|
38
|
+
if (Number.isNaN(anchor)) return NaN;
|
|
39
|
+
const { bpAnchor, bpLength } = tableInternals(t);
|
|
40
|
+
const n = bpAnchor.length;
|
|
41
|
+
if (n === 0) return 0;
|
|
42
|
+
if (anchor <= bpAnchor[0]) return bpLength[0];
|
|
43
|
+
if (anchor >= bpAnchor[n - 1]) return bpLength[n - 1];
|
|
44
|
+
let lo = 0;
|
|
45
|
+
let hi = n - 1;
|
|
46
|
+
while (hi - lo > 1) {
|
|
47
|
+
const mid = lo + hi >> 1;
|
|
48
|
+
if (bpAnchor[mid] <= anchor) lo = mid;
|
|
49
|
+
else hi = mid;
|
|
50
|
+
}
|
|
51
|
+
const span = bpAnchor[hi] - bpAnchor[lo];
|
|
52
|
+
const f = span > 0 ? (anchor - bpAnchor[lo]) / span : 1;
|
|
53
|
+
return bpLength[lo] + f * (bpLength[hi] - bpLength[lo]);
|
|
54
|
+
}
|
|
55
|
+
function anchorAtLength(t, s) {
|
|
56
|
+
if (Number.isNaN(s)) return NaN;
|
|
57
|
+
const { bpAnchor, bpLength } = tableInternals(t);
|
|
58
|
+
const n = bpAnchor.length;
|
|
59
|
+
if (n === 0) return 0;
|
|
60
|
+
if (s <= bpLength[0]) return bpAnchor[0];
|
|
61
|
+
if (s >= bpLength[n - 1]) return bpAnchor[n - 1];
|
|
62
|
+
let lo = 0;
|
|
63
|
+
let hi = n - 1;
|
|
64
|
+
while (hi - lo > 1) {
|
|
65
|
+
const mid = lo + hi >> 1;
|
|
66
|
+
if (bpLength[mid] <= s) lo = mid;
|
|
67
|
+
else hi = mid;
|
|
68
|
+
}
|
|
69
|
+
const f = (s - bpLength[lo]) / (bpLength[hi] - bpLength[lo]);
|
|
70
|
+
return bpAnchor[lo] + f * (bpAnchor[hi] - bpAnchor[lo]);
|
|
71
|
+
}
|
|
72
|
+
function lengthAtSubpath(t, subpath) {
|
|
73
|
+
if (Number.isNaN(subpath)) return NaN;
|
|
74
|
+
const n = t.runs.length;
|
|
75
|
+
const c = Math.min(Math.max(subpath, 0), n);
|
|
76
|
+
const i = Math.floor(c);
|
|
77
|
+
if (i >= n) return t.total;
|
|
78
|
+
return t.runStart[i] + (c - i) * (t.runStart[i + 1] - t.runStart[i]);
|
|
79
|
+
}
|
|
80
|
+
function lengthAtSegmentFraction(t, f) {
|
|
81
|
+
if (Number.isNaN(f)) return NaN;
|
|
82
|
+
const c = Math.min(Math.max(f, 0), 1);
|
|
83
|
+
if (t.segments <= 0) return c * t.total;
|
|
84
|
+
const { runAnchor } = tableInternals(t);
|
|
85
|
+
let s = c * t.segments;
|
|
86
|
+
for (let r = 0; r < runAnchor.length / 2; r++) {
|
|
87
|
+
const start = runAnchor[r * 2];
|
|
88
|
+
const span = runAnchor[r * 2 + 1] - start;
|
|
89
|
+
if (span > 0 && s <= span) return lengthAtAnchor(t, start + s);
|
|
90
|
+
s -= Math.max(span, 0);
|
|
91
|
+
}
|
|
92
|
+
return t.total;
|
|
93
|
+
}
|
|
94
|
+
var wraps = (run, n) => run.closed && (n >= 2 || n === 1 && (run.controls?.[0]?.length ?? 0) > 0);
|
|
95
|
+
function runLengths(run, dim, base) {
|
|
96
|
+
const p = run.points;
|
|
97
|
+
const n = Math.floor(p.length / dim);
|
|
98
|
+
const wrap = wraps(run, n);
|
|
99
|
+
const c = new Float64Array(Math.max(n + (wrap ? 1 : 0), 1));
|
|
100
|
+
c[0] = base;
|
|
101
|
+
for (let i = 1; i < c.length; i++) {
|
|
102
|
+
const ctl = run.controls?.[i - 1];
|
|
103
|
+
if (ctl && ctl.length > 0) {
|
|
104
|
+
const len = segmentLength(segmentCoords(p, ctl, dim, i - 1), dim);
|
|
105
|
+
c[i] = c[i - 1] + (Number.isFinite(len) ? len : 0);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const a = (i - 1) * dim;
|
|
109
|
+
const b = i % n * dim;
|
|
110
|
+
let d2 = 0;
|
|
111
|
+
for (let k = 0; k < dim; k++) d2 += (p[b + k] - p[a + k]) ** 2;
|
|
112
|
+
c[i] = c[i - 1] + Math.sqrt(d2);
|
|
113
|
+
}
|
|
114
|
+
return c;
|
|
115
|
+
}
|
|
116
|
+
function anchorBreakpoints(runs, dim, cum, sources) {
|
|
117
|
+
const ids = [];
|
|
118
|
+
const lens = [];
|
|
119
|
+
const runAnchor = new Float64Array(runs.length * 2);
|
|
120
|
+
let segments = 0;
|
|
121
|
+
let next = 0;
|
|
122
|
+
runs.forEach((run, r) => {
|
|
123
|
+
const n = Math.floor(run.points.length / dim);
|
|
124
|
+
const c = cum[r];
|
|
125
|
+
const raw = expandedBreaks(run, n, c, next);
|
|
126
|
+
next += n;
|
|
127
|
+
const folded = foldToAuthored(raw, sources, wraps(run, n));
|
|
128
|
+
if (folded.ids.length === 0) return;
|
|
129
|
+
const first = folded.ids[0];
|
|
130
|
+
let last = folded.ids[folded.ids.length - 1];
|
|
131
|
+
if (wraps(run, n)) {
|
|
132
|
+
last += 1;
|
|
133
|
+
folded.ids.push(last);
|
|
134
|
+
folded.lens.push(c[c.length - 1]);
|
|
135
|
+
}
|
|
136
|
+
runAnchor[r * 2] = first;
|
|
137
|
+
runAnchor[r * 2 + 1] = last;
|
|
138
|
+
segments += last - first;
|
|
139
|
+
ids.push(...folded.ids);
|
|
140
|
+
lens.push(...folded.lens);
|
|
141
|
+
});
|
|
142
|
+
return { bpAnchor: Float64Array.from(ids), bpLength: Float64Array.from(lens), runAnchor, segments };
|
|
143
|
+
}
|
|
144
|
+
function expandedBreaks(run, n, c, next) {
|
|
145
|
+
const ids = [];
|
|
146
|
+
const lens = [];
|
|
147
|
+
const { anchorA: A, anchorB: B } = run;
|
|
148
|
+
if (!A || !B) {
|
|
149
|
+
for (let i = 0; i < n; i++) {
|
|
150
|
+
ids.push(next + i);
|
|
151
|
+
lens.push(c[i]);
|
|
152
|
+
}
|
|
153
|
+
return { ids, lens };
|
|
154
|
+
}
|
|
155
|
+
for (let i = 0; i < n; i++) {
|
|
156
|
+
if (A[i] === B[i]) {
|
|
157
|
+
ids.push(A[i]);
|
|
158
|
+
lens.push(c[i]);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const dropped = closingAnchorOf(run, n);
|
|
162
|
+
if (dropped !== void 0) {
|
|
163
|
+
ids.push(dropped);
|
|
164
|
+
lens.push(c[n]);
|
|
165
|
+
}
|
|
166
|
+
return { ids, lens };
|
|
167
|
+
}
|
|
168
|
+
function closingAnchor(run, dim = 2) {
|
|
169
|
+
return closingAnchorOf(run, Math.floor(run.points.length / dim));
|
|
170
|
+
}
|
|
171
|
+
function closingAnchorOf(run, n) {
|
|
172
|
+
const { anchorA: A, anchorB: B } = run;
|
|
173
|
+
if (!wraps(run, n)) return void 0;
|
|
174
|
+
if (run.closeAnchor !== void 0) return run.closeAnchor;
|
|
175
|
+
return A && B && A[n - 1] !== B[n - 1] ? B[n - 1] : void 0;
|
|
176
|
+
}
|
|
177
|
+
function foldToAuthored(raw, sources, closed) {
|
|
178
|
+
const ids = [];
|
|
179
|
+
const lens = [];
|
|
180
|
+
let lo = 0;
|
|
181
|
+
let hi = 0;
|
|
182
|
+
const flush = () => {
|
|
183
|
+
if (ids.length > lens.length) lens.push((lo + hi) / 2);
|
|
184
|
+
};
|
|
185
|
+
for (let i = 0; i < raw.ids.length; i++) {
|
|
186
|
+
const id = sources ? sources[raw.ids[i]] ?? raw.ids[i] : raw.ids[i];
|
|
187
|
+
const len = raw.lens[i];
|
|
188
|
+
if (closed && ids.length > 0 && id === ids[0]) continue;
|
|
189
|
+
if (ids.length > 0 && id === ids[ids.length - 1]) {
|
|
190
|
+
hi = len;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
flush();
|
|
194
|
+
ids.push(id);
|
|
195
|
+
lo = len;
|
|
196
|
+
hi = len;
|
|
197
|
+
}
|
|
198
|
+
flush();
|
|
199
|
+
return { ids, lens };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// src/along/positions.ts
|
|
203
|
+
function pointAtLength(t, s) {
|
|
204
|
+
const { cum } = tableInternals(t);
|
|
205
|
+
const len = Number.isNaN(s) ? 0 : Math.min(Math.max(s, 0), t.total);
|
|
206
|
+
let r = cum.findIndex((c2, i) => c2.length >= 2 && len <= t.runStart[i + 1]);
|
|
207
|
+
if (r < 0) {
|
|
208
|
+
r = t.runs.length - 1;
|
|
209
|
+
while (r >= 0 && t.runs[r].points.length < t.dim) r--;
|
|
210
|
+
if (r < 0) return { point: [0, 0, 0], tangent: [0, 0, 0] };
|
|
211
|
+
return { point: at(t, r, 0), tangent: [0, 0, 0] };
|
|
212
|
+
}
|
|
213
|
+
const c = cum[r];
|
|
214
|
+
let lo = 0;
|
|
215
|
+
let hi = c.length - 2;
|
|
216
|
+
while (lo < hi) {
|
|
217
|
+
const mid = lo + hi >> 1;
|
|
218
|
+
if (c[mid + 1] < len) lo = mid + 1;
|
|
219
|
+
else hi = mid;
|
|
220
|
+
}
|
|
221
|
+
return pointOnSegment(t, r, lo, len);
|
|
222
|
+
}
|
|
223
|
+
function pointOnSegment(t, r, i, len) {
|
|
224
|
+
const c = tableInternals(t).cum[r];
|
|
225
|
+
const span = c[i + 1] - c[i];
|
|
226
|
+
const local = Math.min(Math.max(len - c[i], 0), span);
|
|
227
|
+
const arc = segmentArc(t, r, i);
|
|
228
|
+
if (arc) {
|
|
229
|
+
const u = lookupT(arc.coords, t.dim, arc.lookup, local);
|
|
230
|
+
return { point: bezierPoint(arc.coords, t.dim, u), tangent: bezierDirection(arc.coords, t.dim, u) ?? tangentNear(t, r, i) };
|
|
231
|
+
}
|
|
232
|
+
const f = span > 0 ? local / span : 0;
|
|
233
|
+
const a = at(t, r, i);
|
|
234
|
+
const b = at(t, r, i + 1);
|
|
235
|
+
return { point: [lerp(a[0], b[0], f), lerp(a[1], b[1], f), lerp(a[2], b[2], f)], tangent: tangentNear(t, r, i) };
|
|
236
|
+
}
|
|
237
|
+
function at(t, r, i) {
|
|
238
|
+
const { points } = t.runs[r];
|
|
239
|
+
const n = Math.floor(points.length / t.dim);
|
|
240
|
+
const o = i % n * t.dim;
|
|
241
|
+
return [points[o], points[o + 1], t.dim === 3 ? points[o + 2] : 0];
|
|
242
|
+
}
|
|
243
|
+
function tangentNear(t, r, i) {
|
|
244
|
+
const last = tableInternals(t).cum[r].length - 2;
|
|
245
|
+
for (let k = i; k >= 0; k--) {
|
|
246
|
+
const d = direction(t, r, k);
|
|
247
|
+
if (d) return d;
|
|
248
|
+
}
|
|
249
|
+
for (let k = i + 1; k <= last; k++) {
|
|
250
|
+
const d = direction(t, r, k);
|
|
251
|
+
if (d) return d;
|
|
252
|
+
}
|
|
253
|
+
return [0, 0, 0];
|
|
254
|
+
}
|
|
255
|
+
function direction(t, r, i) {
|
|
256
|
+
const a = at(t, r, i);
|
|
257
|
+
const b = at(t, r, i + 1);
|
|
258
|
+
const d = [b[0] - a[0], b[1] - a[1], b[2] - a[2]];
|
|
259
|
+
const l = Math.hypot(d[0], d[1], d[2]);
|
|
260
|
+
return l > 0 ? [d[0] / l, d[1] / l, d[2] / l] : null;
|
|
261
|
+
}
|
|
262
|
+
var lerp = (a, b, f) => a + (b - a) * f;
|
|
263
|
+
|
|
264
|
+
export { anchorAtLength, closingAnchor, lengthAtAnchor, lengthAtSegmentFraction, lengthAtSubpath, lengthTable, pointAtLength, pointOnSegment, segmentArc, tableInternals };
|
|
265
|
+
//# sourceMappingURL=chunk-FOXMA54X.js.map
|
|
266
|
+
//# sourceMappingURL=chunk-FOXMA54X.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/along/lengthTable.ts","../src/along/positions.ts"],"names":["c"],"mappings":"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","file":"chunk-FOXMA54X.js","sourcesContent":["import { arcLookup, segmentLength, type ArcLookup } from '../paths/segmentLength';\nimport { segmentCoords } from './bezier';\n\n/** One subpath of a path in pen order: points joined by straight segments, or by curves where `controls` gives them. */\nexport interface LengthRun {\n /** `dim` components per point. A closed run does not repeat its first point. */\n points: ArrayLike<number>;\n /** Whether a closing edge runs from the last point back to the first. */\n closed: boolean;\n /** Per point, the anchor before it, the anchor after it, and the arc-length\n * fraction between them, as `Polyline` carries them. Absent, every point is\n * an anchor, numbered on from the previous run's. */\n anchorA?: ArrayLike<number>;\n anchorB?: ArrayLike<number>;\n anchorT?: ArrayLike<number>;\n /** A closed run's last anchor when it sat on the first point and was dropped, as `Polyline` carries it. */\n closeAnchor?: number;\n /** Per segment, from point `i` to the next (a closed run's closing edge last), the control\n * points of the curve between them, `dim` components each; empty, null or absent where\n * the segment is straight. A curved segment is measured by its exact arc length. */\n controls?: readonly (ArrayLike<number> | null | undefined)[];\n}\n\n/** A stretch of a path between two pen-order lengths, `from` before `to`. */\nexport interface LengthSpan {\n from: number;\n to: number;\n}\n\n/** A path's arc length in pen order: subpaths in order, the lift between them covering no distance. */\nexport interface LengthTable {\n readonly dim: 2 | 3;\n readonly runs: readonly LengthRun[];\n /** Pen-order length, closing edges included. */\n readonly total: number;\n /** Where each run starts, `runs.length + 1` entries; the last is `total`. */\n readonly runStart: Float64Array;\n /** The anchor range: per subpath, the segments between its anchors, a closed one's closing edge included. */\n readonly segments: number;\n}\n\n/** @internal What the queries read, kept off the public shape. */\nexport interface LengthTableInternals {\n /** Per run, the pen-order length at each point, then at the closing edge's end for a closed run. */\n cum: Float64Array[];\n /** Authored anchor positions and their lengths, both ascending. */\n bpAnchor: Float64Array;\n bpLength: Float64Array;\n /** Per run, its first anchor and the anchor its last segment ends at. */\n runAnchor: Float64Array;\n /** Per run and segment, a curve's control points and arc lookup, filled on first query. */\n arcs: (SegmentArc | undefined)[][];\n}\n\n/** @internal A curved segment as flat control points, with its {@link ArcLookup}. */\nexport interface SegmentArc {\n coords: number[];\n lookup: ArcLookup;\n}\n\n// A symbol rather than a side table, so a spread copy of a table still answers.\nconst INTERNALS = Symbol('lengthTable.internals');\ntype WithInternals = LengthTable & { [INTERNALS]?: LengthTableInternals };\n\n/**\n * The length table of `runs`, in `dim` components per point. `anchorSources`\n * (from `resolveCornersWithSources`) maps the anchors of a corner-expanded path\n * back to the authored ones, so anchor queries answer in authored numbering:\n * an anchor rounded into an arc sits at the arc's midpoint.\n */\nexport function lengthTable(runs: readonly LengthRun[], dim: 2 | 3, anchorSources?: Uint32Array | null): LengthTable {\n const runStart = new Float64Array(runs.length + 1);\n const cum: Float64Array[] = [];\n let total = 0;\n runs.forEach((run, r) => {\n const c = runLengths(run, dim, total);\n cum.push(c);\n total = c[c.length - 1];\n runStart[r + 1] = total;\n });\n const anchors = anchorBreakpoints(runs, dim, cum, anchorSources ?? null);\n const table: WithInternals = { dim, runs, total, runStart, segments: anchors.segments };\n table[INTERNALS] = { cum, ...anchors, arcs: runs.map(() => []) };\n return table;\n}\n\n/** @internal Segment `i` of run `r` when it is a curve, with its arc lookup, built on first use; null when straight. */\nexport function segmentArc(t: LengthTable, r: number, i: number): SegmentArc | null {\n const ctl = t.runs[r].controls?.[i];\n if (!ctl || ctl.length === 0) return null;\n const arcs = tableInternals(t).arcs[r];\n let arc = arcs[i];\n if (!arc) {\n const coords = segmentCoords(t.runs[r].points, ctl, t.dim, i);\n arcs[i] = arc = { coords, lookup: arcLookup(coords, t.dim) };\n }\n return arc;\n}\n\n/** @internal */\nexport function tableInternals(t: LengthTable): LengthTableInternals {\n const hit = (t as WithInternals)[INTERNALS];\n if (!hit) throw new Error('LengthTable: not built by lengthTable(); build one with it rather than by hand');\n return hit;\n}\n\n/** The pen-order length at authored anchor position `anchor`; `3.5` is halfway\n * along the segment from anchor 3 by length. Clamps to the path. */\nexport function lengthAtAnchor(t: LengthTable, anchor: number): number {\n if (Number.isNaN(anchor)) return NaN;\n const { bpAnchor, bpLength } = tableInternals(t);\n const n = bpAnchor.length;\n if (n === 0) return 0;\n if (anchor <= bpAnchor[0]) return bpLength[0];\n if (anchor >= bpAnchor[n - 1]) return bpLength[n - 1];\n let lo = 0;\n let hi = n - 1;\n while (hi - lo > 1) {\n const mid = (lo + hi) >> 1;\n if (bpAnchor[mid] <= anchor) lo = mid;\n else hi = mid;\n }\n const span = bpAnchor[hi] - bpAnchor[lo];\n const f = span > 0 ? (anchor - bpAnchor[lo]) / span : 1;\n return bpLength[lo] + f * (bpLength[hi] - bpLength[lo]);\n}\n\n/** The authored anchor position at pen length `s`: the inverse of\n * {@link lengthAtAnchor}. Where a pen lift puts two anchors at one length,\n * the later. Clamps to the path. */\nexport function anchorAtLength(t: LengthTable, s: number): number {\n if (Number.isNaN(s)) return NaN;\n const { bpAnchor, bpLength } = tableInternals(t);\n const n = bpAnchor.length;\n if (n === 0) return 0;\n if (s <= bpLength[0]) return bpAnchor[0];\n if (s >= bpLength[n - 1]) return bpAnchor[n - 1];\n let lo = 0;\n let hi = n - 1;\n while (hi - lo > 1) {\n const mid = (lo + hi) >> 1;\n if (bpLength[mid] <= s) lo = mid;\n else hi = mid;\n }\n const f = (s - bpLength[lo]) / (bpLength[hi] - bpLength[lo]);\n return bpAnchor[lo] + f * (bpAnchor[hi] - bpAnchor[lo]);\n}\n\n/** The pen-order length at the start of subpath `subpath`; a fractional part\n * goes that share of the way along it by length. Clamps to the path. */\nexport function lengthAtSubpath(t: LengthTable, subpath: number): number {\n if (Number.isNaN(subpath)) return NaN;\n const n = t.runs.length;\n const c = Math.min(Math.max(subpath, 0), n);\n const i = Math.floor(c);\n if (i >= n) return t.total;\n return t.runStart[i] + (c - i) * (t.runStart[i + 1] - t.runStart[i]);\n}\n\n/** The pen-order length at fraction `f` of the anchor range: each segment an\n * equal share, a pen lift none. Clamps to the path. */\nexport function lengthAtSegmentFraction(t: LengthTable, f: number): number {\n if (Number.isNaN(f)) return NaN;\n const c = Math.min(Math.max(f, 0), 1);\n if (t.segments <= 0) return c * t.total;\n const { runAnchor } = tableInternals(t);\n let s = c * t.segments;\n for (let r = 0; r < runAnchor.length / 2; r++) {\n const start = runAnchor[r * 2];\n const span = runAnchor[r * 2 + 1] - start;\n if (span > 0 && s <= span) return lengthAtAnchor(t, start + s);\n s -= Math.max(span, 0);\n }\n return t.total;\n}\n\n/** Whether `run`, of `n` points, has a closing edge: a lone point closes only through a curve back to itself. */\nconst wraps = (run: LengthRun, n: number): boolean =>\n run.closed && (n >= 2 || (n === 1 && (run.controls?.[0]?.length ?? 0) > 0));\n\nfunction runLengths(run: LengthRun, dim: 2 | 3, base: number): Float64Array {\n const p = run.points;\n const n = Math.floor(p.length / dim);\n const wrap = wraps(run, n);\n const c = new Float64Array(Math.max(n + (wrap ? 1 : 0), 1));\n c[0] = base;\n for (let i = 1; i < c.length; i++) {\n const ctl = run.controls?.[i - 1];\n if (ctl && ctl.length > 0) {\n // A curve whose coordinates are not finite flattens to its end point, covering no distance.\n const len = segmentLength(segmentCoords(p, ctl, dim, i - 1), dim);\n c[i] = c[i - 1] + (Number.isFinite(len) ? len : 0);\n continue;\n }\n const a = (i - 1) * dim;\n const b = (i % n) * dim;\n let d2 = 0;\n for (let k = 0; k < dim; k++) d2 += (p[b + k] - p[a + k]) ** 2;\n c[i] = c[i - 1] + Math.sqrt(d2);\n }\n return c;\n}\n\n/** Per run, its anchor-aligned points as (expanded anchor, length) pairs, then\n * folded into authored numbering. */\nfunction anchorBreakpoints(\n runs: readonly LengthRun[], dim: number, cum: readonly Float64Array[], sources: Uint32Array | null,\n): Omit<LengthTableInternals, 'cum' | 'arcs'> & { segments: number } {\n const ids: number[] = [];\n const lens: number[] = [];\n const runAnchor = new Float64Array(runs.length * 2);\n let segments = 0;\n let next = 0;\n runs.forEach((run, r) => {\n const n = Math.floor(run.points.length / dim);\n const c = cum[r];\n const raw = expandedBreaks(run, n, c, next);\n next += n;\n const folded = foldToAuthored(raw, sources, wraps(run, n));\n if (folded.ids.length === 0) return;\n const first = folded.ids[0];\n let last = folded.ids[folded.ids.length - 1];\n if (wraps(run, n)) {\n last += 1;\n folded.ids.push(last);\n folded.lens.push(c[c.length - 1]);\n }\n runAnchor[r * 2] = first;\n runAnchor[r * 2 + 1] = last;\n segments += last - first;\n ids.push(...folded.ids);\n lens.push(...folded.lens);\n });\n return { bpAnchor: Float64Array.from(ids), bpLength: Float64Array.from(lens), runAnchor, segments };\n}\n\nfunction expandedBreaks(run: LengthRun, n: number, c: Float64Array, next: number): { ids: number[]; lens: number[] } {\n const ids: number[] = [];\n const lens: number[] = [];\n const { anchorA: A, anchorB: B } = run;\n if (!A || !B) {\n for (let i = 0; i < n; i++) { ids.push(next + i); lens.push(c[i]); }\n return { ids, lens };\n }\n for (let i = 0; i < n; i++) {\n if (A[i] === B[i]) { ids.push(A[i]); lens.push(c[i]); }\n }\n // A last anchor dropped as a duplicate of the first point ends the closing edge's drawn part.\n const dropped = closingAnchorOf(run, n);\n if (dropped !== undefined) { ids.push(dropped); lens.push(c[n]); }\n return { ids, lens };\n}\n\n/**\n * The anchor a closed run's closing edge ends at when that anchor was dropped\n * as a duplicate of the first point: `closeAnchor`, else the anchor the last\n * point is heading toward. `undefined` when none was dropped, so the edge\n * ends at the run's first anchor. `dim` is the run's components per point.\n */\nexport function closingAnchor(run: LengthRun, dim: 2 | 3 = 2): number | undefined {\n return closingAnchorOf(run, Math.floor(run.points.length / dim));\n}\n\nfunction closingAnchorOf(run: LengthRun, n: number): number | undefined {\n const { anchorA: A, anchorB: B } = run;\n if (!wraps(run, n)) return undefined;\n if (run.closeAnchor !== undefined) return run.closeAnchor;\n return A && B && A[n - 1] !== B[n - 1] ? B[n - 1] : undefined;\n}\n\nfunction foldToAuthored(\n raw: { ids: number[]; lens: number[] }, sources: Uint32Array | null, closed: boolean,\n): { ids: number[]; lens: number[] } {\n const ids: number[] = [];\n const lens: number[] = [];\n let lo = 0;\n let hi = 0;\n const flush = () => { if (ids.length > lens.length) lens.push((lo + hi) / 2); };\n for (let i = 0; i < raw.ids.length; i++) {\n const id = sources ? (sources[raw.ids[i]] ?? raw.ids[i]) : raw.ids[i];\n const len = raw.lens[i];\n // A closed run's first anchor stays at its start; the arc rounding it is drawn last, so it joins the closing edge.\n if (closed && ids.length > 0 && id === ids[0]) continue;\n if (ids.length > 0 && id === ids[ids.length - 1]) { hi = len; continue; }\n flush();\n ids.push(id);\n lo = len;\n hi = len;\n }\n flush();\n return { ids, lens };\n}\n","import { lookupT } from '../paths/segmentLength';\nimport { bezierDirection, bezierPoint } from './bezier';\nimport { segmentArc, tableInternals, type LengthTable } from './lengthTable';\n\ntype Comps = [number, number, number];\n\n/**\n * The point at pen-order length `s`, and the unit tangent of the segment\n * arriving there (leaving, at a run's start); on a curve, the exact point and\n * the curve's own direction. Components past the table's\n * `dim` read 0. Clamps to the path; where two runs meet, answers the end of the\n * earlier one. A path with no length answers a zero tangent.\n */\nexport function pointAtLength(t: LengthTable, s: number): { point: Comps; tangent: Comps } {\n const { cum } = tableInternals(t);\n const len = Number.isNaN(s) ? 0 : Math.min(Math.max(s, 0), t.total);\n let r = cum.findIndex((c, i) => c.length >= 2 && len <= t.runStart[i + 1]);\n if (r < 0) {\n r = t.runs.length - 1;\n while (r >= 0 && t.runs[r].points.length < t.dim) r--;\n if (r < 0) return { point: [0, 0, 0], tangent: [0, 0, 0] };\n return { point: at(t, r, 0), tangent: [0, 0, 0] };\n }\n const c = cum[r];\n let lo = 0;\n let hi = c.length - 2;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (c[mid + 1] < len) lo = mid + 1;\n else hi = mid;\n }\n return pointOnSegment(t, r, lo, len);\n}\n\n/**\n * @internal {@link pointAtLength} on a segment already found: the point at\n * pen-order length `len` on segment `i` of run `r`, `len` clamped to it.\n */\nexport function pointOnSegment(t: LengthTable, r: number, i: number, len: number): { point: Comps; tangent: Comps } {\n const c = tableInternals(t).cum[r];\n const span = c[i + 1] - c[i];\n const local = Math.min(Math.max(len - c[i], 0), span);\n const arc = segmentArc(t, r, i);\n if (arc) {\n const u = lookupT(arc.coords, t.dim, arc.lookup, local);\n return { point: bezierPoint(arc.coords, t.dim, u), tangent: bezierDirection(arc.coords, t.dim, u) ?? tangentNear(t, r, i) };\n }\n const f = span > 0 ? local / span : 0;\n const a = at(t, r, i);\n const b = at(t, r, i + 1);\n return { point: [lerp(a[0], b[0], f), lerp(a[1], b[1], f), lerp(a[2], b[2], f)], tangent: tangentNear(t, r, i) };\n}\n\n/** Point `i` of run `r`, wrapping a closed run's closing edge back to its first. */\nfunction at(t: LengthTable, r: number, i: number): Comps {\n const { points } = t.runs[r];\n const n = Math.floor(points.length / t.dim);\n const o = (i % n) * t.dim;\n return [points[o], points[o + 1], t.dim === 3 ? points[o + 2] : 0];\n}\n\n/** The direction of segment `i`, or of the nearest one with length, looking back first. */\nfunction tangentNear(t: LengthTable, r: number, i: number): Comps {\n const last = tableInternals(t).cum[r].length - 2;\n for (let k = i; k >= 0; k--) { const d = direction(t, r, k); if (d) return d; }\n for (let k = i + 1; k <= last; k++) { const d = direction(t, r, k); if (d) return d; }\n return [0, 0, 0];\n}\n\nfunction direction(t: LengthTable, r: number, i: number): Comps | null {\n const a = at(t, r, i);\n const b = at(t, r, i + 1);\n const d: Comps = [b[0] - a[0], b[1] - a[1], b[2] - a[2]];\n const l = Math.hypot(d[0], d[1], d[2]);\n return l > 0 ? [d[0] / l, d[1] / l, d[2] / l] : null;\n}\n\nconst lerp = (a: number, b: number, f: number): number => a + (b - a) * f;\n"]}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { nearestOnLine, nearestOnCubic } from './chunk-
|
|
2
|
-
import { worldCoords, forEachSegment, PATH_Z, PATH_Q, PATH_C, PATH_L, PATH_M, cornerSpecAt, PathBuilder, compactCorners, withoutCorners } from './chunk-B3D6KWW3.js';
|
|
1
|
+
import { worldCoords, forEachSegment, PATH_Z, PATH_Q, PATH_C, PATH_L, PATH_M, cornerSpecAt, PathBuilder, compactCorners, withoutCorners, nearestOnLine, nearestOnCubic } from './chunk-346XYYMX.js';
|
|
3
2
|
|
|
4
3
|
// src/paths/anchors.ts
|
|
5
4
|
function pathToAnchors(path) {
|
|
@@ -173,5 +172,5 @@ function nearestSegmentT(anchors, wx, wy, closed) {
|
|
|
173
172
|
}
|
|
174
173
|
|
|
175
174
|
export { anchorsToPath, countPathAnchors, isAnchorSmooth, isStraightSegment, nearestSegmentT, pathToAnchors, segmentEnds };
|
|
176
|
-
//# sourceMappingURL=chunk-
|
|
177
|
-
//# sourceMappingURL=chunk-
|
|
175
|
+
//# sourceMappingURL=chunk-HTT5AQIU.js.map
|
|
176
|
+
//# sourceMappingURL=chunk-HTT5AQIU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/paths/anchors.ts"],"names":[],"mappings":"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","file":"chunk-HTT5AQIU.js","sourcesContent":["/**\n * Counts the path anchors used by the per-anchor coloring surface. An\n * \"anchor\" is the destination point of a path command: M, L, C, Q each\n * contribute one (the (x, y) where the pen ends up); Z contributes none\n * (it closes back to the subpath's first M). RectPath has four implicit\n * anchors — the corners — matching its M/L/L/L/Z stroke tessellation.\n *\n * Consumers use this to size their per-anchor color array; the renderer\n * uses it to validate the array length in dev builds.\n */\n\nimport { PATH_C, PATH_L, PATH_M, PATH_Q, PATH_Z, forEachSegment } from '../commands';\nimport { nearestOnCubic, nearestOnLine } from '../nearest';\nimport type { Path, PolygonPath } from '../path';\nimport { PathBuilder } from './builder';\nimport { worldCoords } from './pathOrigin';\nimport { compactCorners, cornerSpecAt, withoutCorners, type CornerSpec } from './cornerSpec';\n\n/** One anchor of an editable path: its on-curve point plus the two control\n * handles that shape the segments either side of it. Handles are in the same\n * space as the point, and absent when the adjoining segment is straight. */\nexport interface PenAnchor {\n x: number;\n y: number;\n inHandle?: { x: number; y: number };\n outHandle?: { x: number; y: number };\n /** The corner shape cut at this anchor (`PolygonPath.corners`). */\n corner?: CornerSpec;\n}\n\n/**\n * Derive a per-subpath anchor model from a PolygonPath. Subpaths split on\n * every `M` command; a subpath is closed iff it ends with `Z`.\n *\n * Cubic-segment control points become the outHandle of the previous anchor\n * and the inHandle of the next anchor. A closed subpath whose last curve ends\n * exactly on its first point holds that point twice; the two are one anchor,\n * and the curve's second control is that anchor's inHandle. Quadratic segments are upgraded to\n * cubics (each control reused for both adjacent handles) — this loses no\n * geometry. Linear segments produce anchors with no handles.\n */\nexport function pathToAnchors(\n path: PolygonPath,\n): { anchors: PenAnchor[][]; closed: boolean[] } {\n const { commands } = path;\n const coords = worldCoords(path);\n const anchors: PenAnchor[][] = [];\n const closed: boolean[] = [];\n let current: PenAnchor[] | null = null;\n\n forEachSegment(commands, coords, (cmd, ci) => {\n switch (cmd) {\n case PATH_M: {\n if (current) { anchors.push(current); closed.push(false); }\n current = [{ x: coords[ci], y: coords[ci + 1] }];\n break;\n }\n case PATH_L: {\n if (!current) throw new Error('pathToAnchors: L without prior M');\n current.push({ x: coords[ci], y: coords[ci + 1] });\n break;\n }\n case PATH_C: {\n if (!current) throw new Error('pathToAnchors: C without prior M');\n const prev = current[current.length - 1];\n prev.outHandle = { x: coords[ci], y: coords[ci + 1] };\n current.push({\n x: coords[ci + 4], y: coords[ci + 5],\n inHandle: { x: coords[ci + 2], y: coords[ci + 3] },\n });\n break;\n }\n case PATH_Q: {\n if (!current) throw new Error('pathToAnchors: Q without prior M');\n // Quadratic → cubic: handle is the same control point on both sides.\n const handle = { x: coords[ci], y: coords[ci + 1] };\n const prev = current[current.length - 1];\n prev.outHandle = handle;\n current.push({ x: coords[ci + 2], y: coords[ci + 3], inHandle: { ...handle } });\n break;\n }\n case PATH_Z: {\n if (current) {\n foldClosingCurve(current);\n anchors.push(current);\n closed.push(true);\n current = null;\n }\n break;\n }\n default:\n throw new Error(`pathToAnchors: unknown command ${cmd}`);\n }\n });\n if (current) { anchors.push(current); closed.push(false); }\n if (path.corners) {\n let flat = 0;\n for (const sub of anchors) {\n for (const a of sub) {\n const corner = cornerSpecAt(path, flat++);\n if (corner) a.corner = { ...corner };\n }\n }\n }\n return { anchors, closed };\n}\n\n/** Merge a closing curve's end anchor into the subpath's first anchor when\n * the two coincide. */\nfunction foldClosingCurve(sub: PenAnchor[]): void {\n if (sub.length < 2) return;\n const first = sub[0];\n const last = sub[sub.length - 1];\n if (!last.inHandle || last.x !== first.x || last.y !== first.y) return;\n sub.pop();\n first.inHandle = last.inHandle;\n}\n\n/**\n * Serialize the per-subpath anchor model back to a PolygonPath. Inverse of\n * `pathToAnchors`. Curve-vs-line decision per segment:\n * - Both adjacent handles absent → straight L segment.\n * - Either handle present → C segment, with missing handles defaulting to\n * the anchor point itself (degenerate but valid; renders as a near-line).\n * Given `like`, the path being reshaped, the result keeps its fill rules and\n * its origin; without it, the result is measured from the origin `originFor`\n * picks for its points, if any.\n */\nexport function anchorsToPath(\n anchors: PenAnchor[][],\n closed: boolean[],\n like?: PolygonPath,\n): PolygonPath {\n const b = new PathBuilder();\n if (like?.origin) b.setOrigin(like.origin.x, like.origin.y);\n else if (!like) b.autoOrigin();\n for (let s = 0; s < anchors.length; s++) {\n const sub = anchors[s];\n if (sub.length === 0) continue;\n b.moveTo(sub[0].x, sub[0].y);\n for (let i = 1; i < sub.length; i++) {\n const prev = sub[i - 1];\n const cur = sub[i];\n const hasHandle = prev.outHandle != null || cur.inHandle != null;\n if (!hasHandle) {\n b.lineTo(cur.x, cur.y);\n } else {\n const c1 = prev.outHandle ?? { x: prev.x, y: prev.y };\n const c2 = cur.inHandle ?? { x: cur.x, y: cur.y };\n b.curveTo(c1.x, c1.y, c2.x, c2.y, cur.x, cur.y);\n }\n }\n if (closed[s]) {\n // Bridge last → first if they have curve handles; either way emit Z.\n const last = sub[sub.length - 1];\n const first = sub[0];\n const hasHandle = last.outHandle != null || first.inHandle != null;\n if (hasHandle) {\n const c1 = last.outHandle ?? { x: last.x, y: last.y };\n const c2 = first.inHandle ?? { x: first.x, y: first.y };\n b.curveTo(c1.x, c1.y, c2.x, c2.y, first.x, first.y);\n }\n b.close();\n }\n }\n const built = b.build();\n const corners = compactCorners(anchors.flatMap((sub) => sub.map((a) => a.corner ?? null)));\n const base = like ? { ...withoutCorners(like), commands: built.commands, coords: built.coords } : built;\n return corners ? { ...base, corners } : base;\n}\n\nconst SMOOTH_THRESHOLD = 0.001;\n\n/**\n * Returns true if the anchor's in-handle and out-handle are collinear with\n * the anchor point, indicating \"smooth\" (mirror-drag) behavior. Detected via\n * the magnitude of the normalized cross product of the two handle vectors.\n *\n * Edge cases:\n * - Missing in or out handle → false (corner by definition).\n * - Either handle at zero distance from anchor → false.\n */\nexport function isAnchorSmooth(a: PenAnchor): boolean {\n if (!a.inHandle || !a.outHandle) return false;\n const inDX = a.inHandle.x - a.x;\n const inDY = a.inHandle.y - a.y;\n const outDX = a.outHandle.x - a.x;\n const outDY = a.outHandle.y - a.y;\n const inLen = Math.hypot(inDX, inDY);\n const outLen = Math.hypot(outDX, outDY);\n if (inLen === 0 || outLen === 0) return false;\n // For collinear handles on opposite sides of the anchor, the cross product\n // of the two handle vectors should be zero. Normalize by both magnitudes.\n const cross = (inDX * outDY - inDY * outDX) / (inLen * outLen);\n return Math.abs(cross) < SMOOTH_THRESHOLD;\n}\n\n/** How many anchors a path has. Matches the per-anchor arrays the renderer\n * expects for `vertexColors`. */\nexport function countPathAnchors(path: Path): number {\n if (path.kind === 'rect') return 4;\n const cmds = path.commands;\n let n = 0;\n for (let i = 0; i < cmds.length; i++) {\n const c = cmds[i];\n if (c === PATH_M || c === PATH_L || c === PATH_C || c === PATH_Q) n++;\n }\n return n;\n}\n\n/** The segment `(sub, segIdx)` as its two end anchors, or null when it\n * doesn't exist. `segIdx === sub.length - 1` names a closed subpath's\n * closing segment, which runs from the last anchor back to the first. */\nexport function segmentEnds(\n anchors: readonly PenAnchor[][],\n closed: readonly boolean[] | undefined,\n sub: number,\n segIdx: number,\n): { a: PenAnchor; b: PenAnchor } | null {\n const s = anchors[sub];\n if (!s || segIdx < 0) return null;\n if (segIdx + 1 < s.length) return { a: s[segIdx], b: s[segIdx + 1] };\n if (closed?.[sub] && s.length > 1 && segIdx === s.length - 1) return { a: s[segIdx], b: s[0] };\n return null;\n}\n\n/** Whether the segment from `a` to `b` is a straight line (no handles). */\nexport function isStraightSegment(a: PenAnchor, b: PenAnchor): boolean {\n return a.outHandle == null && b.inHandle == null;\n}\n\n/** Nearest parameter on one segment to `(x, y)`, with its squared distance.\n * A straight segment is parameterized by arc length (`t` is the fraction of\n * the way from `a` to `b`), matching how {@link insertAnchorOnSegment}\n * splits one. */\nfunction nearestOnSegment(a: PenAnchor, b: PenAnchor, x: number, y: number): { t: number; d2: number } {\n const p1 = a.outHandle ?? a;\n const p2 = b.inHandle ?? b;\n const hit = isStraightSegment(a, b)\n ? nearestOnLine(x, y, a.x, a.y, b.x, b.y)\n : nearestOnCubic(x, y, a.x, a.y, p1.x, p1.y, p2.x, p2.y, b.x, b.y);\n return { t: hit.t, d2: hit.dist * hit.dist };\n}\n\n/** The segment of a decoded path nearest `(wx, wy)`, and the parameter `t`\n * on it closest to that point. Pass `closed` (from `pathToAnchors`) to\n * include each closed subpath's closing segment, reported as\n * `segIdx === sub.length - 1`. `t` spans `[0, 1]`, endpoints included.\n * Returns `null` only when there are no segments. */\nexport function nearestSegmentT(\n anchors: PenAnchor[][],\n wx: number,\n wy: number,\n closed?: readonly boolean[],\n): { sub: number; segIdx: number; t: number } | null {\n let bestD2 = Infinity;\n let best: { sub: number; segIdx: number; t: number } | null = null;\n for (let s = 0; s < anchors.length; s++) {\n const segCount = anchors[s].length - (closed?.[s] ? 0 : 1);\n for (let i = 0; i < segCount; i++) {\n const ends = segmentEnds(anchors, closed, s, i);\n if (!ends) continue;\n const hit = nearestOnSegment(ends.a, ends.b, wx, wy);\n if (hit.d2 < bestD2) {\n bestD2 = hit.d2;\n best = { sub: s, segIdx: i, t: hit.t };\n }\n }\n }\n return best;\n}\n"]}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// src/paths/segmentLength.ts
|
|
2
|
+
var GL_X = [
|
|
3
|
+
-0.9602898564975363,
|
|
4
|
+
-0.7966664774136267,
|
|
5
|
+
-0.525532409916329,
|
|
6
|
+
-0.1834346424956498,
|
|
7
|
+
0.1834346424956498,
|
|
8
|
+
0.525532409916329,
|
|
9
|
+
0.7966664774136267,
|
|
10
|
+
0.9602898564975363
|
|
11
|
+
];
|
|
12
|
+
var GL_W = [
|
|
13
|
+
0.1012285362903763,
|
|
14
|
+
0.2223810344533745,
|
|
15
|
+
0.3137066458778873,
|
|
16
|
+
0.362683783378362,
|
|
17
|
+
0.362683783378362,
|
|
18
|
+
0.3137066458778873,
|
|
19
|
+
0.2223810344533745,
|
|
20
|
+
0.1012285362903763
|
|
21
|
+
];
|
|
22
|
+
var G4_X = [-0.8611363115940526, -0.3399810435848563, 0.3399810435848563, 0.8611363115940526];
|
|
23
|
+
var G4_W = [0.3478548451374538, 0.6521451548625461, 0.6521451548625461, 0.3478548451374538];
|
|
24
|
+
var PANEL_AGREE = 1e-9;
|
|
25
|
+
var DIP_PANELS = 1;
|
|
26
|
+
var EDGE_NEAR = 0.05;
|
|
27
|
+
var SETTLE = 1e-13;
|
|
28
|
+
function speed(c, dim, t) {
|
|
29
|
+
const n = c.length / dim - 1;
|
|
30
|
+
const u = 1 - t;
|
|
31
|
+
let sum = 0;
|
|
32
|
+
for (let k = 0; k < dim; k++) {
|
|
33
|
+
const d0 = c[dim + k] - c[k];
|
|
34
|
+
const v = n === 1 ? d0 : n === 2 ? 2 * (u * d0 + t * (c[2 * dim + k] - c[dim + k])) : 3 * (u * u * d0 + 2 * u * t * (c[2 * dim + k] - c[dim + k]) + t * t * (c[3 * dim + k] - c[2 * dim + k]));
|
|
35
|
+
sum += v * v;
|
|
36
|
+
}
|
|
37
|
+
return Math.sqrt(sum);
|
|
38
|
+
}
|
|
39
|
+
function rule(c, dim, a, b, xs, ws) {
|
|
40
|
+
const mid = (a + b) / 2, half = (b - a) / 2;
|
|
41
|
+
let sum = 0;
|
|
42
|
+
for (let i = 0; i < xs.length; i++) sum += ws[i] * speed(c, dim, mid + xs[i] * half);
|
|
43
|
+
return sum * half;
|
|
44
|
+
}
|
|
45
|
+
function refined(c, dim, a, b, whole, tol, depth) {
|
|
46
|
+
const m = (a + b) / 2;
|
|
47
|
+
const l = rule(c, dim, a, m, GL_X, GL_W), r = rule(c, dim, m, b, GL_X, GL_W);
|
|
48
|
+
if (depth >= 20 || !(Math.abs(l + r - whole) > tol)) return l + r;
|
|
49
|
+
return refined(c, dim, a, m, l, tol, depth + 1) + refined(c, dim, m, b, r, tol, depth + 1);
|
|
50
|
+
}
|
|
51
|
+
function hullLength(c, dim) {
|
|
52
|
+
let sum = 0;
|
|
53
|
+
for (let i = dim; i < c.length; i += dim) {
|
|
54
|
+
let d2 = 0;
|
|
55
|
+
for (let k = 0; k < dim; k++) d2 += (c[i + k] - c[i - dim + k]) ** 2;
|
|
56
|
+
sum += Math.sqrt(d2);
|
|
57
|
+
}
|
|
58
|
+
return sum;
|
|
59
|
+
}
|
|
60
|
+
function finite(c) {
|
|
61
|
+
for (let i = 0; i < c.length; i++) if (!Number.isFinite(c[i])) return false;
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
function derivativeRoots(c, dim, a, b) {
|
|
65
|
+
const n = c.length / dim - 1;
|
|
66
|
+
const out = [];
|
|
67
|
+
const keep = (t) => {
|
|
68
|
+
if (t > a && t < b) out.push(t);
|
|
69
|
+
};
|
|
70
|
+
for (let k = 0; k < dim; k++) {
|
|
71
|
+
const d0 = c[dim + k] - c[k];
|
|
72
|
+
const d1 = c[2 * dim + k] - c[dim + k];
|
|
73
|
+
if (n === 2) {
|
|
74
|
+
if (d0 !== d1) keep(d0 / (d0 - d1));
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const d2 = c[3 * dim + k] - c[2 * dim + k];
|
|
78
|
+
const A = d0 - 2 * d1 + d2, B = 2 * (d1 - d0), C = d0;
|
|
79
|
+
if (Math.abs(A) <= 1e-12 * (Math.abs(B) + Math.abs(C))) {
|
|
80
|
+
if (B !== 0) keep(-C / B);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const disc = B * B - 4 * A * C;
|
|
84
|
+
if (disc < 0) continue;
|
|
85
|
+
const q = -(B + Math.sign(B || 1) * Math.sqrt(disc)) / 2;
|
|
86
|
+
keep(q / A);
|
|
87
|
+
if (q !== 0) keep(C / q);
|
|
88
|
+
}
|
|
89
|
+
out.sort((x, y) => x - y);
|
|
90
|
+
return out.filter((t, i) => i === 0 || t !== out[i - 1]);
|
|
91
|
+
}
|
|
92
|
+
function panelLength(c, dim, p0, p1, size, beside) {
|
|
93
|
+
if (!(p1 > p0)) return 0;
|
|
94
|
+
const g8 = rule(c, dim, p0, p1, GL_X, GL_W);
|
|
95
|
+
const settled = !beside && !(Math.abs(g8 - rule(c, dim, p0, p1, G4_X, G4_W)) > PANEL_AGREE * size);
|
|
96
|
+
return settled ? g8 : refined(c, dim, p0, p1, g8, SETTLE * size, 0);
|
|
97
|
+
}
|
|
98
|
+
function segmentLength(coords, dim, a = 0, b = 1) {
|
|
99
|
+
if (!finite(coords)) return NaN;
|
|
100
|
+
if (coords.length === 2 * dim) return speed(coords, dim, 0) * (b - a);
|
|
101
|
+
const size = hullLength(coords, dim);
|
|
102
|
+
return lengthOver(coords, dim, a, b, size, speedDips(coords, dim));
|
|
103
|
+
}
|
|
104
|
+
function bend(c, dim, t) {
|
|
105
|
+
const n = c.length / dim - 1;
|
|
106
|
+
let sum = 0;
|
|
107
|
+
for (let k = 0; k < dim; k++) {
|
|
108
|
+
const e0 = c[2 * dim + k] - 2 * c[dim + k] + c[k];
|
|
109
|
+
const v = n === 2 ? 2 * e0 : 6 * ((1 - t) * e0 + t * (c[3 * dim + k] - 2 * c[2 * dim + k] + c[dim + k]));
|
|
110
|
+
sum += v * v;
|
|
111
|
+
}
|
|
112
|
+
return Math.sqrt(sum);
|
|
113
|
+
}
|
|
114
|
+
function speedDips(c, dim) {
|
|
115
|
+
return derivativeRoots(c, dim, 0, 1).map((t) => {
|
|
116
|
+
const b = bend(c, dim, t);
|
|
117
|
+
return { t, width: b > 0 ? speed(c, dim, t) / b : Infinity };
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function dipsFor(dips, h) {
|
|
121
|
+
const out = [];
|
|
122
|
+
for (const d of dips) if (d.width < DIP_PANELS * h) out.push(d.t);
|
|
123
|
+
return out;
|
|
124
|
+
}
|
|
125
|
+
function lengthOver(c, dim, a, b, size, dips, panels = 8) {
|
|
126
|
+
const h = (b - a) / panels;
|
|
127
|
+
const last = panels - 1;
|
|
128
|
+
let sum = 0;
|
|
129
|
+
const roots = dipsFor(dips, h);
|
|
130
|
+
if (roots.length === 0) {
|
|
131
|
+
for (let k = 0; k < panels; k++) sum += panelLength(c, dim, a + k * h, k === last ? b : a + (k + 1) * h, size, false);
|
|
132
|
+
return sum;
|
|
133
|
+
}
|
|
134
|
+
const near = (t) => roots.some((r2) => Math.abs(r2 - t) <= EDGE_NEAR * h);
|
|
135
|
+
let r = 0;
|
|
136
|
+
while (r < roots.length && roots[r] <= a) r++;
|
|
137
|
+
for (let k = 0; k < panels; k++) {
|
|
138
|
+
const p0 = a + k * h, p1 = k === last ? b : p0 + h;
|
|
139
|
+
let from = p0;
|
|
140
|
+
while (r < roots.length && roots[r] < p1) {
|
|
141
|
+
sum += panelLength(c, dim, from, roots[r], size, true);
|
|
142
|
+
from = roots[r++];
|
|
143
|
+
}
|
|
144
|
+
sum += panelLength(c, dim, from, p1, size, near(from) || near(p1));
|
|
145
|
+
}
|
|
146
|
+
return sum;
|
|
147
|
+
}
|
|
148
|
+
function segmentTAtLength(coords, dim, length, total = segmentLength(coords, dim)) {
|
|
149
|
+
if (length <= 0 || !(total > 0) || !Number.isFinite(total)) return 0;
|
|
150
|
+
if (length >= total) return 1;
|
|
151
|
+
if (coords.length === 2 * dim) return length / total;
|
|
152
|
+
const size = hullLength(coords, dim);
|
|
153
|
+
const dips = speedDips(coords, dim);
|
|
154
|
+
let lo = 0, hi = 1, t = length / total;
|
|
155
|
+
for (let i = 0; i < 30; i++) {
|
|
156
|
+
const err = lengthOver(coords, dim, 0, t, size, dips) - length;
|
|
157
|
+
if (Math.abs(err) < 1e-10 * total) break;
|
|
158
|
+
if (err > 0) hi = t;
|
|
159
|
+
else lo = t;
|
|
160
|
+
const v = speed(coords, dim, t);
|
|
161
|
+
let next = v > 0 ? t - err / v : NaN;
|
|
162
|
+
if (!(next > lo && next < hi)) next = (lo + hi) / 2;
|
|
163
|
+
t = next;
|
|
164
|
+
}
|
|
165
|
+
return t;
|
|
166
|
+
}
|
|
167
|
+
var STEPS = 16;
|
|
168
|
+
function arcLookup(coords, dim) {
|
|
169
|
+
const size = hullLength(coords, dim);
|
|
170
|
+
const dips = finite(coords) ? speedDips(coords, dim) : [];
|
|
171
|
+
const s = new Float64Array(STEPS + 1);
|
|
172
|
+
for (let k = 0; k < STEPS; k++) s[k + 1] = s[k] + lengthOver(coords, dim, k / STEPS, (k + 1) / STEPS, size, dips, 1);
|
|
173
|
+
return { s, size, dips };
|
|
174
|
+
}
|
|
175
|
+
function lookupLength(coords, dim, lk, t) {
|
|
176
|
+
const f = Math.min(Math.max(t, 0), 1);
|
|
177
|
+
const k = Math.min(Math.floor(f * STEPS), STEPS - 1);
|
|
178
|
+
return lk.s[k] + lengthOver(coords, dim, k / STEPS, f, lk.size, lk.dips, 1);
|
|
179
|
+
}
|
|
180
|
+
function lookupT(coords, dim, lk, length) {
|
|
181
|
+
const { s } = lk;
|
|
182
|
+
const total = s[STEPS];
|
|
183
|
+
if (length <= 0 || !(total > 0) || !Number.isFinite(total)) return 0;
|
|
184
|
+
if (length >= total) return 1;
|
|
185
|
+
let k = 0;
|
|
186
|
+
let hi = STEPS - 1;
|
|
187
|
+
while (k < hi) {
|
|
188
|
+
const mid = k + hi + 1 >> 1;
|
|
189
|
+
if (s[mid] <= length) k = mid;
|
|
190
|
+
else hi = mid - 1;
|
|
191
|
+
}
|
|
192
|
+
const a = k / STEPS;
|
|
193
|
+
let lo = a, top = (k + 1) / STEPS;
|
|
194
|
+
const step = s[k + 1] - s[k];
|
|
195
|
+
let t = step > 0 ? a + (length - s[k]) / step / STEPS : a;
|
|
196
|
+
for (let i = 0; i < 30; i++) {
|
|
197
|
+
const err = s[k] + lengthOver(coords, dim, a, t, lk.size, lk.dips, 1) - length;
|
|
198
|
+
if (Math.abs(err) < 1e-10 * total) break;
|
|
199
|
+
if (err > 0) top = t;
|
|
200
|
+
else lo = t;
|
|
201
|
+
const v = speed(coords, dim, t);
|
|
202
|
+
let next = v > 0 ? t - err / v : NaN;
|
|
203
|
+
if (!(next > lo && next < top)) next = (lo + top) / 2;
|
|
204
|
+
t = next;
|
|
205
|
+
}
|
|
206
|
+
return t;
|
|
207
|
+
}
|
|
208
|
+
var flatPoints = (pts) => pts.flatMap((p) => [p.x, p.y]);
|
|
209
|
+
|
|
210
|
+
export { arcLookup, flatPoints, lookupLength, lookupT, segmentLength, segmentTAtLength };
|
|
211
|
+
//# sourceMappingURL=chunk-IOD2NFHQ.js.map
|
|
212
|
+
//# sourceMappingURL=chunk-IOD2NFHQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/paths/segmentLength.ts"],"names":["r"],"mappings":"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","file":"chunk-IOD2NFHQ.js","sourcesContent":["/** Measuring one Bézier segment by arc length, and finding where a run of it ends. */\n\nconst GL_X = [-0.9602898564975363, -0.7966664774136267, -0.5255324099163290, -0.1834346424956498,\n 0.1834346424956498, 0.5255324099163290, 0.7966664774136267, 0.9602898564975363];\nconst GL_W = [0.1012285362903763, 0.2223810344533745, 0.3137066458778873, 0.3626837833783620,\n 0.3626837833783620, 0.3137066458778873, 0.2223810344533745, 0.1012285362903763];\n\nconst G4_X = [-0.8611363115940526, -0.3399810435848563, 0.3399810435848563, 0.8611363115940526];\nconst G4_W = [0.3478548451374538, 0.6521451548625461, 0.6521451548625461, 0.3478548451374538];\n\n/** How far the eight-point rule may sit from the four-point one on a panel, as a share of the\n * segment's size, before the panel is refined. */\nconst PANEL_AGREE = 1e-9;\n/** A derivative root is a cusp or a dip in speed when the dip is narrower than this many panel\n * widths: its speed over the curvature of its path there, `|B′| / |B″|`, a width in `t`. */\nconst DIP_PANELS = 1;\n/** A dip this share of a panel from its edge marks the panel across the edge too: its shoulder\n * sits in the gap before the edge's nearest Gauss node. */\nconst EDGE_NEAR = 0.05;\n/** How closely a refined panel's halves must agree, as a share of the segment's size. */\nconst SETTLE = 1e-13;\n\n/** The speed of the segment at `t`: the length of its derivative. */\nfunction speed(c: ArrayLike<number>, dim: number, t: number): number {\n const n = c.length / dim - 1;\n const u = 1 - t;\n let sum = 0;\n for (let k = 0; k < dim; k++) {\n const d0 = c[dim + k] - c[k];\n const v = n === 1 ? d0\n : n === 2 ? 2 * (u * d0 + t * (c[2 * dim + k] - c[dim + k]))\n : 3 * (u * u * d0 + 2 * u * t * (c[2 * dim + k] - c[dim + k]) + t * t * (c[3 * dim + k] - c[2 * dim + k]));\n sum += v * v;\n }\n return Math.sqrt(sum);\n}\n\nfunction rule(c: ArrayLike<number>, dim: number, a: number, b: number, xs: readonly number[], ws: readonly number[]): number {\n const mid = (a + b) / 2, half = (b - a) / 2;\n let sum = 0;\n for (let i = 0; i < xs.length; i++) sum += ws[i] * speed(c, dim, mid + xs[i] * half);\n return sum * half;\n}\n\n/** `whole`, the eight-point length over `a..b`, refined by halves until they agree within `tol`.\n * A difference that is not a number counts as settled. */\nfunction refined(c: ArrayLike<number>, dim: number, a: number, b: number, whole: number, tol: number, depth: number): number {\n const m = (a + b) / 2;\n const l = rule(c, dim, a, m, GL_X, GL_W), r = rule(c, dim, m, b, GL_X, GL_W);\n if (depth >= 20 || !(Math.abs(l + r - whole) > tol)) return l + r;\n return refined(c, dim, a, m, l, tol, depth + 1) + refined(c, dim, m, b, r, tol, depth + 1);\n}\n\n/** The length of the control polygon: the segment's own size, which tolerances scale by. */\nfunction hullLength(c: ArrayLike<number>, dim: number): number {\n let sum = 0;\n for (let i = dim; i < c.length; i += dim) {\n let d2 = 0;\n for (let k = 0; k < dim; k++) d2 += (c[i + k] - c[i - dim + k]) ** 2;\n sum += Math.sqrt(d2);\n }\n return sum;\n}\n\nfunction finite(c: ArrayLike<number>): boolean {\n for (let i = 0; i < c.length; i++) if (!Number.isFinite(c[i])) return false;\n return true;\n}\n\n/** Where a component of the segment's derivative is zero, strictly inside `a..b`, ascending:\n * the only places a cusp or a dip in speed can sit, which an error estimate can step over. */\nfunction derivativeRoots(c: ArrayLike<number>, dim: number, a: number, b: number): number[] {\n const n = c.length / dim - 1;\n const out: number[] = [];\n const keep = (t: number) => { if (t > a && t < b) out.push(t); };\n for (let k = 0; k < dim; k++) {\n const d0 = c[dim + k] - c[k];\n const d1 = c[2 * dim + k] - c[dim + k];\n if (n === 2) {\n if (d0 !== d1) keep(d0 / (d0 - d1));\n continue;\n }\n // Bernstein (d0, d1, d2) as A t² + B t + C.\n const d2 = c[3 * dim + k] - c[2 * dim + k];\n const A = d0 - 2 * d1 + d2, B = 2 * (d1 - d0), C = d0;\n if (Math.abs(A) <= 1e-12 * (Math.abs(B) + Math.abs(C))) {\n if (B !== 0) keep(-C / B);\n continue;\n }\n const disc = B * B - 4 * A * C;\n if (disc < 0) continue;\n // The stable pair: one root from the sum that cannot cancel, the other from the product.\n const q = -(B + Math.sign(B || 1) * Math.sqrt(disc)) / 2;\n keep(q / A);\n if (q !== 0) keep(C / q);\n }\n out.sort((x, y) => x - y);\n return out.filter((t, i) => i === 0 || t !== out[i - 1]);\n}\n\n/** The eight-point length over `p0..p1`, refined when it sits beside a slow root or its\n * four-point rule disagrees. */\nfunction panelLength(c: ArrayLike<number>, dim: number, p0: number, p1: number, size: number, beside: boolean): number {\n if (!(p1 > p0)) return 0;\n const g8 = rule(c, dim, p0, p1, GL_X, GL_W);\n const settled = !beside && !(Math.abs(g8 - rule(c, dim, p0, p1, G4_X, G4_W)) > PANEL_AGREE * size);\n return settled ? g8 : refined(c, dim, p0, p1, g8, SETTLE * size, 0);\n}\n\n/**\n * Length of a Bézier segment between parameters `a` and `b`, by Gauss–Legendre\n * over eight panels, split where a component of its derivative is zero and\n * the speed dips there within a panel's width. The panels beside such a root\n * are halved until they settle, and so is any other where the eight- and\n * four-point rules disagree. `coords` holds its control\n * points flat, `dim` components each: two points for a line, three for a\n * quadratic, four for a cubic. NaN when a coordinate is not finite.\n */\nexport function segmentLength(coords: ArrayLike<number>, dim: 2 | 3, a = 0, b = 1): number {\n if (!finite(coords)) return NaN;\n if (coords.length === 2 * dim) return speed(coords, dim, 0) * (b - a);\n const size = hullLength(coords, dim);\n return lengthOver(coords, dim, a, b, size, speedDips(coords, dim));\n}\n\n/** The length of the segment's second derivative at `t`. */\nfunction bend(c: ArrayLike<number>, dim: number, t: number): number {\n const n = c.length / dim - 1;\n let sum = 0;\n for (let k = 0; k < dim; k++) {\n const e0 = c[2 * dim + k] - 2 * c[dim + k] + c[k];\n const v = n === 2 ? 2 * e0 : 6 * ((1 - t) * e0 + t * (c[3 * dim + k] - 2 * c[2 * dim + k] + c[dim + k]));\n sum += v * v;\n }\n return Math.sqrt(sum);\n}\n\n/** A derivative root inside 0..1, and how wide its dip in speed is, in `t`. */\ninterface Dip { t: number; width: number }\n\n/** @internal The derivative roots inside 0..1, each with the width of its dip. */\nexport function speedDips(c: ArrayLike<number>, dim: number): Dip[] {\n return derivativeRoots(c, dim, 0, 1).map((t) => {\n const b = bend(c, dim, t);\n return { t, width: b > 0 ? speed(c, dim, t) / b : Infinity };\n });\n}\n\n/** @internal The dips a panel `h` wide cannot be trusted to see: narrower than {@link DIP_PANELS} panels. */\nexport function dipsFor(dips: readonly Dip[], h: number): number[] {\n const out: number[] = [];\n for (const d of dips) if (d.width < DIP_PANELS * h) out.push(d.t);\n return out;\n}\n\n/** {@link segmentLength} over `a..b` in `panels` panels, given the segment's size and its dips. */\nfunction lengthOver(\n c: ArrayLike<number>, dim: number, a: number, b: number, size: number, dips: readonly Dip[], panels = 8,\n): number {\n const h = (b - a) / panels;\n const last = panels - 1;\n let sum = 0;\n const roots = dipsFor(dips, h);\n if (roots.length === 0) {\n for (let k = 0; k < panels; k++) sum += panelLength(c, dim, a + k * h, k === last ? b : a + (k + 1) * h, size, false);\n return sum;\n }\n const near = (t: number): boolean => roots.some((r) => Math.abs(r - t) <= EDGE_NEAR * h);\n let r = 0;\n while (r < roots.length && roots[r] <= a) r++;\n for (let k = 0; k < panels; k++) {\n const p0 = a + k * h, p1 = k === last ? b : p0 + h;\n let from = p0;\n // A dip splits its panel, and every piece that touches one, or comes near, is refined.\n while (r < roots.length && roots[r] < p1) {\n sum += panelLength(c, dim, from, roots[r], size, true);\n from = roots[r++];\n }\n sum += panelLength(c, dim, from, p1, size, near(from) || near(p1));\n }\n return sum;\n}\n\n/**\n * The parameter at which the segment {@link segmentLength} reads has run\n * `length` from its start, clamped to 0..1: Newton steps on the arc length,\n * held inside a shrinking bracket. `total` is its whole length, when the\n * caller has it; it is trusted, not checked, and a wrong one misplaces the\n * clamp and the first guess. 0 when a coordinate is not finite, as for a\n * segment of no length.\n */\nexport function segmentTAtLength(\n coords: ArrayLike<number>, dim: 2 | 3, length: number, total = segmentLength(coords, dim),\n): number {\n if (length <= 0 || !(total > 0) || !Number.isFinite(total)) return 0;\n if (length >= total) return 1;\n if (coords.length === 2 * dim) return length / total;\n const size = hullLength(coords, dim);\n const dips = speedDips(coords, dim);\n let lo = 0, hi = 1, t = length / total;\n for (let i = 0; i < 30; i++) {\n const err = lengthOver(coords, dim, 0, t, size, dips) - length;\n if (Math.abs(err) < 1e-10 * total) break;\n if (err > 0) hi = t; else lo = t;\n const v = speed(coords, dim, t);\n let next = v > 0 ? t - err / v : NaN;\n if (!(next > lo && next < hi)) next = (lo + hi) / 2;\n t = next;\n }\n return t;\n}\n\nconst STEPS = 16;\n\n/** A curved segment's exact arc length at evenly spaced parameters: what repeated length queries on one segment start from. */\nexport interface ArcLookup {\n /** The length from the start to parameter `k / 16`, `k` = 0..16. */\n readonly s: Float64Array;\n readonly size: number;\n readonly dips: readonly Dip[];\n}\n\n/** @internal The {@link ArcLookup} of curved segment `coords`, each step measured as one panel of {@link segmentLength}'s rule. */\nexport function arcLookup(coords: ArrayLike<number>, dim: 2 | 3): ArcLookup {\n const size = hullLength(coords, dim);\n const dips = finite(coords) ? speedDips(coords, dim) : [];\n const s = new Float64Array(STEPS + 1);\n for (let k = 0; k < STEPS; k++) s[k + 1] = s[k] + lengthOver(coords, dim, k / STEPS, (k + 1) / STEPS, size, dips, 1);\n return { s, size, dips };\n}\n\n/** @internal The length from the start of `coords` to parameter `t`, read from its lookup `lk`. */\nexport function lookupLength(coords: ArrayLike<number>, dim: 2 | 3, lk: ArcLookup, t: number): number {\n const f = Math.min(Math.max(t, 0), 1);\n const k = Math.min(Math.floor(f * STEPS), STEPS - 1);\n return lk.s[k] + lengthOver(coords, dim, k / STEPS, f, lk.size, lk.dips, 1);\n}\n\n/**\n * @internal {@link segmentTAtLength} from a lookup: the step holding `length`\n * gives the first guess and the bracket, and Newton steps on one panel's\n * length finish it, so a query costs a few panels rather than a whole-segment solve.\n */\nexport function lookupT(coords: ArrayLike<number>, dim: 2 | 3, lk: ArcLookup, length: number): number {\n const { s } = lk;\n const total = s[STEPS];\n if (length <= 0 || !(total > 0) || !Number.isFinite(total)) return 0;\n if (length >= total) return 1;\n let k = 0;\n let hi = STEPS - 1;\n while (k < hi) {\n const mid = (k + hi + 1) >> 1;\n if (s[mid] <= length) k = mid;\n else hi = mid - 1;\n }\n const a = k / STEPS;\n let lo = a, top = (k + 1) / STEPS;\n const step = s[k + 1] - s[k];\n let t = step > 0 ? a + ((length - s[k]) / step) / STEPS : a;\n for (let i = 0; i < 30; i++) {\n const err = s[k] + lengthOver(coords, dim, a, t, lk.size, lk.dips, 1) - length;\n if (Math.abs(err) < 1e-10 * total) break;\n if (err > 0) top = t; else lo = t;\n const v = speed(coords, dim, t);\n let next = v > 0 ? t - err / v : NaN;\n if (!(next > lo && next < top)) next = (lo + top) / 2;\n t = next;\n }\n return t;\n}\n\n/** `pts` as the flat 2D coords {@link segmentLength} reads. */\nexport const flatPoints = (pts: readonly { x: number; y: number }[]): number[] => pts.flatMap((p) => [p.x, p.y]);\n"]}
|