@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,64 @@
|
|
|
1
|
+
/** One subpath of a path in pen order: points joined by straight segments, or by curves where `controls` gives them. */
|
|
2
|
+
interface LengthRun {
|
|
3
|
+
/** `dim` components per point. A closed run does not repeat its first point. */
|
|
4
|
+
points: ArrayLike<number>;
|
|
5
|
+
/** Whether a closing edge runs from the last point back to the first. */
|
|
6
|
+
closed: boolean;
|
|
7
|
+
/** Per point, the anchor before it, the anchor after it, and the arc-length
|
|
8
|
+
* fraction between them, as `Polyline` carries them. Absent, every point is
|
|
9
|
+
* an anchor, numbered on from the previous run's. */
|
|
10
|
+
anchorA?: ArrayLike<number>;
|
|
11
|
+
anchorB?: ArrayLike<number>;
|
|
12
|
+
anchorT?: ArrayLike<number>;
|
|
13
|
+
/** A closed run's last anchor when it sat on the first point and was dropped, as `Polyline` carries it. */
|
|
14
|
+
closeAnchor?: number;
|
|
15
|
+
/** Per segment, from point `i` to the next (a closed run's closing edge last), the control
|
|
16
|
+
* points of the curve between them, `dim` components each; empty, null or absent where
|
|
17
|
+
* the segment is straight. A curved segment is measured by its exact arc length. */
|
|
18
|
+
controls?: readonly (ArrayLike<number> | null | undefined)[];
|
|
19
|
+
}
|
|
20
|
+
/** A stretch of a path between two pen-order lengths, `from` before `to`. */
|
|
21
|
+
interface LengthSpan {
|
|
22
|
+
from: number;
|
|
23
|
+
to: number;
|
|
24
|
+
}
|
|
25
|
+
/** A path's arc length in pen order: subpaths in order, the lift between them covering no distance. */
|
|
26
|
+
interface LengthTable {
|
|
27
|
+
readonly dim: 2 | 3;
|
|
28
|
+
readonly runs: readonly LengthRun[];
|
|
29
|
+
/** Pen-order length, closing edges included. */
|
|
30
|
+
readonly total: number;
|
|
31
|
+
/** Where each run starts, `runs.length + 1` entries; the last is `total`. */
|
|
32
|
+
readonly runStart: Float64Array;
|
|
33
|
+
/** The anchor range: per subpath, the segments between its anchors, a closed one's closing edge included. */
|
|
34
|
+
readonly segments: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The length table of `runs`, in `dim` components per point. `anchorSources`
|
|
38
|
+
* (from `resolveCornersWithSources`) maps the anchors of a corner-expanded path
|
|
39
|
+
* back to the authored ones, so anchor queries answer in authored numbering:
|
|
40
|
+
* an anchor rounded into an arc sits at the arc's midpoint.
|
|
41
|
+
*/
|
|
42
|
+
declare function lengthTable(runs: readonly LengthRun[], dim: 2 | 3, anchorSources?: Uint32Array | null): LengthTable;
|
|
43
|
+
/** The pen-order length at authored anchor position `anchor`; `3.5` is halfway
|
|
44
|
+
* along the segment from anchor 3 by length. Clamps to the path. */
|
|
45
|
+
declare function lengthAtAnchor(t: LengthTable, anchor: number): number;
|
|
46
|
+
/** The authored anchor position at pen length `s`: the inverse of
|
|
47
|
+
* {@link lengthAtAnchor}. Where a pen lift puts two anchors at one length,
|
|
48
|
+
* the later. Clamps to the path. */
|
|
49
|
+
declare function anchorAtLength(t: LengthTable, s: number): number;
|
|
50
|
+
/** The pen-order length at the start of subpath `subpath`; a fractional part
|
|
51
|
+
* goes that share of the way along it by length. Clamps to the path. */
|
|
52
|
+
declare function lengthAtSubpath(t: LengthTable, subpath: number): number;
|
|
53
|
+
/** The pen-order length at fraction `f` of the anchor range: each segment an
|
|
54
|
+
* equal share, a pen lift none. Clamps to the path. */
|
|
55
|
+
declare function lengthAtSegmentFraction(t: LengthTable, f: number): number;
|
|
56
|
+
/**
|
|
57
|
+
* The anchor a closed run's closing edge ends at when that anchor was dropped
|
|
58
|
+
* as a duplicate of the first point: `closeAnchor`, else the anchor the last
|
|
59
|
+
* point is heading toward. `undefined` when none was dropped, so the edge
|
|
60
|
+
* ends at the run's first anchor. `dim` is the run's components per point.
|
|
61
|
+
*/
|
|
62
|
+
declare function closingAnchor(run: LengthRun, dim?: 2 | 3): number | undefined;
|
|
63
|
+
|
|
64
|
+
export { type LengthTable as L, type LengthSpan as a, type LengthRun as b, anchorAtLength as c, closingAnchor as d, lengthAtSegmentFraction as e, lengthAtSubpath as f, lengthTable as g, lengthAtAnchor as l };
|
package/dist/nd/index.d.ts
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
export { P as PORT_REACH, c as cubicAt, p as portControls, a as portCurvePoints } from '../portCurve-C5HDWuuV.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Points and segments over plain number arrays, in any dimension: how far
|
|
5
|
+
* apart two points are, the point part of the way between them, and the
|
|
6
|
+
* nearest point of a segment.
|
|
7
|
+
*
|
|
8
|
+
* Published as is from `./nd`. The 2D barrel states the same rules over loose
|
|
9
|
+
* scalars in `./points2` (they run per pointermove and per vertex, so they
|
|
10
|
+
* must not allocate), and `./3d` wraps these in `Vec3`. Both use the scalar
|
|
11
|
+
* `lerp` and `segmentTFrom` below, so the tiers return the same numbers.
|
|
12
|
+
*/
|
|
13
|
+
/** Squared distance between two points. Compare with this and skip the root. */
|
|
14
|
+
declare function distance2(a: readonly number[], b: readonly number[]): number;
|
|
15
|
+
/** Euclidean distance between two points. */
|
|
16
|
+
declare function distance(a: readonly number[], b: readonly number[]): number;
|
|
17
|
+
/** The point `t` of the way from `a` to `b`; `t` outside [0, 1] extrapolates. */
|
|
18
|
+
declare function lerp(a: readonly number[], b: readonly number[], t: number): number[];
|
|
19
|
+
/** The parameter, 0 to 1, of the point of segment `a`–`b` nearest `p`. A
|
|
20
|
+
* zero-length segment answers 0. */
|
|
21
|
+
declare function segmentT(p: readonly number[], a: readonly number[], b: readonly number[]): number;
|
|
22
|
+
/** The point of segment `a`–`b` nearest `p`. At `t = 1` it is `b` exactly,
|
|
23
|
+
* not `a + (b - a)`, which can miss it by rounding. */
|
|
24
|
+
declare function closestPointOnSegment(p: readonly number[], a: readonly number[], b: readonly number[]): number[];
|
|
25
|
+
/** Squared distance from `p` to segment `a`–`b`. */
|
|
26
|
+
declare function pointSegmentDist2(p: readonly number[], a: readonly number[], b: readonly number[]): number;
|
|
27
|
+
/** Distance from `p` to segment `a`–`b`. */
|
|
28
|
+
declare function pointSegmentDist(p: readonly number[], a: readonly number[], b: readonly number[]): number;
|
|
29
|
+
|
|
3
30
|
/** Affine subspaces ("flats") over plain number arrays, in any dimension:
|
|
4
31
|
* the points, lines and planes a snap resolves against. */
|
|
5
32
|
type Vec = readonly number[];
|
|
@@ -159,4 +186,4 @@ interface SettledCacheOptions {
|
|
|
159
186
|
/** A {@link SettledCache} that builds on the `reads`-th read in a row at one key. */
|
|
160
187
|
declare function createSettledCache<T>({ reads }?: SettledCacheOptions): SettledCache<T>;
|
|
161
188
|
|
|
162
|
-
export { type BoxN, type Bvh, type Flat, type HalfSpace, type ProbeRole, type SettledCache, type SettledCacheOptions, type SnapCandidate, type SnapProbe, type SnapProblem, type SnapResolution, type SnapTier, type Vec, closestBetweenFlats, closestOnFlat, createBvh, createSettledCache, flatDim, intersectFlats, resolveSnap, stepLine };
|
|
189
|
+
export { type BoxN, type Bvh, type Flat, type HalfSpace, type ProbeRole, type SettledCache, type SettledCacheOptions, type SnapCandidate, type SnapProbe, type SnapProblem, type SnapResolution, type SnapTier, type Vec, closestBetweenFlats, closestOnFlat, closestPointOnSegment, createBvh, createSettledCache, distance, distance2, flatDim, intersectFlats, lerp, pointSegmentDist, pointSegmentDist2, resolveSnap, segmentT, stepLine };
|
package/dist/nd/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { createBvh } from '../chunk-XXNK4N7Z.js';
|
|
2
2
|
export { PORT_REACH, cubicAt, portControls, portCurvePoints } from '../chunk-YQADYJJ7.js';
|
|
3
|
+
import { distance } from '../chunk-DNX24KBT.js';
|
|
4
|
+
export { closestPointOnSegment, distance, distance2, lerp2 as lerp, pointSegmentDist, pointSegmentDist2, segmentT } from '../chunk-DNX24KBT.js';
|
|
3
5
|
|
|
4
6
|
// src/snap/flat.ts
|
|
5
7
|
var RANK_TOL = 1e-6;
|
|
@@ -109,11 +111,6 @@ var SAME_PX = 1e-9;
|
|
|
109
111
|
var plus = (a, b) => a.map((v, i) => v + b[i]);
|
|
110
112
|
var minus = (a, b) => a.map((v, i) => v - b[i]);
|
|
111
113
|
var isFiniteVec2 = (a) => a.every(Number.isFinite);
|
|
112
|
-
function distance(a, b) {
|
|
113
|
-
let s = 0;
|
|
114
|
-
for (let i = 0; i < a.length; i++) s += (a[i] - b[i]) ** 2;
|
|
115
|
-
return Math.sqrt(s);
|
|
116
|
-
}
|
|
117
114
|
function makeMeasure(problem, base, eps) {
|
|
118
115
|
const home = /* @__PURE__ */ new Map();
|
|
119
116
|
return {
|
package/dist/nd/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/snap/flat.ts","../../src/snap/resolve.ts","../../src/snap/stepLine.ts","../../src/bvh/settledCache.ts"],"names":["isFiniteVec"],"mappings":"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","file":"index.js","sourcesContent":["/** Affine subspaces (\"flats\") over plain number arrays, in any dimension:\n * the points, lines and planes a snap resolves against. */\n\nexport type Vec = readonly number[];\n\n/** The affine subspace `at + span(dirs)`. `dirs` need not be orthonormal or\n * independent; a zero or repeated direction adds nothing. */\nexport interface Flat {\n at: Vec;\n dirs: readonly Vec[];\n}\n\n/** A direction left with less than this fraction of its length after the\n * ones before it are taken out counts as dependent on them. The solve's\n * pivots are those leftover lengths squared, so it shares this one value.\n * Squaring loses angles below about 1e-8 rad to rounding; at 1e-8 the two\n * verdicts part, so this sits two decades clear. */\nconst RANK_TOL = 1e-6;\n\nfunction dotv(a: Vec, b: Vec): number {\n let s = 0;\n for (let i = 0; i < a.length; i++) s += a[i] * b[i];\n return s;\n}\n\nfunction normv(a: Vec): number {\n return Math.sqrt(dotv(a, a));\n}\n\nfunction isFiniteVec(a: Vec): boolean {\n return a.every(Number.isFinite);\n}\n\n/** An orthonormal basis of `span(vecs)`, built by Gram-Schmidt with a second\n * pass for stability. Non-finite and dependent vectors are dropped. */\nexport function orthonormalize(vecs: readonly Vec[], start: readonly Vec[] = []): number[][] {\n const basis: number[][] = start.map((q) => q.slice());\n const out: number[][] = [];\n for (const d of vecs) {\n const n0 = normv(d);\n if (!(n0 > 0) || !isFiniteVec(d)) continue;\n const v = d.slice();\n for (let pass = 0; pass < 2; pass++) {\n for (const q of basis) {\n const k = dotv(v, q);\n for (let i = 0; i < v.length; i++) v[i] -= k * q[i];\n }\n }\n const n = normv(v);\n if (n <= RANK_TOL * n0) continue;\n for (let i = 0; i < v.length; i++) v[i] /= n;\n basis.push(v);\n out.push(v);\n }\n return out;\n}\n\n/** An orthonormal basis of the orthogonal complement of the orthonormal `basis` in R^n. */\nfunction complement(basis: readonly Vec[], n: number): number[][] {\n const axes: number[][] = [];\n for (let i = 0; i < n; i++) axes.push(Array.from({ length: n }, (_, j) => (i === j ? 1 : 0)));\n return orthonormalize(axes, basis);\n}\n\n/** The flat's dimension: the rank of its directions. */\nexport function flatDim(f: Flat): number {\n return orthonormalize(f.dirs).length;\n}\n\n/** The point of `f` nearest `p`. */\nexport function closestOnFlat(f: Flat, p: Vec): Vec {\n const out = f.at.slice();\n for (const q of orthonormalize(f.dirs)) {\n let k = 0;\n for (let i = 0; i < q.length; i++) k += q[i] * (p[i] - f.at[i]);\n for (let i = 0; i < out.length; i++) out[i] += k * q[i];\n }\n return out;\n}\n\n/**\n * The `x` minimizing `|Σ x_j cols_j − rhs|`, through the normal equations.\n * A column within `RANK_TOL` of the span of the kept ones before it is\n * dropped, the same verdict `orthonormalize` reaches, and its unknown is zero.\n */\nexport function solveLeastSquares(cols: readonly Vec[], rhs: Vec): number[] {\n const k = cols.length;\n const m = cols.map((a) => [...cols.map((b) => dotv(a, b)), dotv(a, rhs)]);\n const len2 = m.map((r, i) => r[i]);\n const kept: number[] = [];\n for (let col = 0; col < k; col++) {\n if (!(m[col][col] > RANK_TOL * RANK_TOL * len2[col])) continue;\n for (let r = col + 1; r < k; r++) {\n const f = m[r][col] / m[col][col];\n for (let c = col; c <= k; c++) m[r][c] -= f * m[col][c];\n }\n kept.push(col);\n }\n const x = new Array<number>(k).fill(0);\n for (let p = kept.length - 1; p >= 0; p--) {\n const col = kept[p];\n let s = m[col][k];\n for (let c = col + 1; c < k; c++) s -= m[col][c] * x[c];\n x[col] = s / m[col][col];\n }\n return x;\n}\n\n/** The nearest pair of points, one on each flat. Parallel flats have many\n * such pairs; this returns one of them. */\nexport function closestBetweenFlats(a: Flat, b: Flat): { onA: Vec; onB: Vec } {\n const qa = orthonormalize(a.dirs);\n const qb = orthonormalize(b.dirs);\n const d = b.at.map((v, i) => v - a.at[i]);\n const x = solveLeastSquares([...qa, ...qb.map((q) => q.map((v) => -v))], d);\n const onA = a.at.slice();\n const onB = b.at.slice();\n qa.forEach((q, j) => q.forEach((v, i) => { onA[i] += x[j] * v; }));\n qb.forEach((q, j) => q.forEach((v, i) => { onB[i] += x[qa.length + j] * v; }));\n return { onA, onB };\n}\n\n/** `a ∩ b`, or null when they miss each other by more than `eps`. */\nexport function intersectFlats(a: Flat, b: Flat, eps = 1e-6): Flat | null {\n const { onA, onB } = closestBetweenFlats(a, b);\n let gap2 = 0;\n for (let i = 0; i < onA.length; i++) gap2 += (onA[i] - onB[i]) ** 2;\n if (!(Math.sqrt(gap2) <= eps) || !isFiniteVec(onA)) return null;\n const n = a.at.length;\n const normals = orthonormalize([\n ...complement(orthonormalize(a.dirs), n),\n ...complement(orthonormalize(b.dirs), n),\n ]);\n return { at: onA, dirs: complement(normals, n) };\n}\n","/** The snap resolver: every gesture's snap, in any dimension, as one search\n * over affine constraints on the move `δ`. */\n\nimport { closestOnFlat, flatDim, intersectFlats, solveLeastSquares, type Flat, type Vec } from './flat';\n\n/** A `fallback` candidate holds only the axes no `target` claims. */\nexport type SnapTier = 'target' | 'fallback';\n/** What a probe stands for on the subject; sources match probes by role.\n * `'anchor'` is a point a node declares in its own box frame. */\nexport type ProbeRole = 'origin' | 'box' | 'geometry' | 'pointer' | 'anchor';\n\n/** A point on the subject that should land on a locus. `role` says which\n * sources may match it. */\nexport interface SnapProbe {\n id: string;\n at: Vec;\n role: ProbeRole;\n}\n\n/** One probe paired with one locus. `M` is the mark payload, opaque here. */\nexport interface SnapCandidate<M> {\n /** `SnapProbe.id`. */\n probe: string;\n locus: Flat;\n /** One interval per locus dir, in multiples of that dir. A solution\n * outside it fails the candidate. */\n span?: readonly (readonly [number, number])[];\n source: string;\n /** Stable tiebreak: lower wins when everything else is equal. */\n order: number;\n tier: SnapTier;\n reachPx: number;\n /** When any required candidate exists, the result includes one of them,\n * whatever its reach. */\n required?: boolean;\n mark?: M;\n}\n\n/** One frame's snap: the probes, the input subspace, the raw move, and the candidates. */\nexport interface SnapProblem<M> {\n probes: readonly SnapProbe[];\n /** `H`, the subspace of δ-space the result stays inside. */\n input: Flat;\n /** The unsnapped move. */\n delta0: Vec;\n candidates: readonly SnapCandidate<M>[];\n /** World to screen pixels. A non-finite result puts that position out of reach. */\n toScreen(world: Vec): Vec;\n /** Candidates kept per probe, nearest first, besides the required ones,\n * which are all kept. Default 24. */\n poolSize?: number;\n /** World-space tolerance for \"on the locus\". Default 1e-6. */\n eps?: number;\n}\n\n/** The move `resolveSnap` chose and the candidates it meets. */\nexport interface SnapResolution<M> {\n /** `closestOnFlat(input, delta0)` when nothing snaps. */\n delta: Vec;\n members: readonly SnapCandidate<M>[];\n /** Every in-reach candidate the result meets: the ones whose marks show. */\n satisfied: readonly SnapCandidate<M>[];\n /** How many dimensions of `H` the result pins. */\n codim: number;\n}\n\n/** A candidate that can be met on its own: its probe, and `H ∩ C` in δ-space. */\ninterface Live<M> {\n c: SnapCandidate<M>;\n probe: Vec;\n within: Flat;\n px: number;\n}\n\ninterface Combo<M> {\n members: Live<M>[];\n flat: Flat;\n dim: number;\n targetFlat: Flat;\n delta: Vec;\n codim: number;\n targetCodim: number;\n px: number;\n}\n\nconst DEFAULT_POOL = 24;\nconst DEFAULT_EPS = 1e-6;\n/** Screen displacements closer than this rank as equal, so order decides. */\nconst SAME_PX = 1e-9;\n\nconst plus = (a: Vec, b: Vec): Vec => a.map((v, i) => v + b[i]);\nconst minus = (a: Vec, b: Vec): Vec => a.map((v, i) => v - b[i]);\nconst isFiniteVec = (a: Vec): boolean => a.every(Number.isFinite);\n\nfunction distance(a: Vec, b: Vec): number {\n let s = 0;\n for (let i = 0; i < a.length; i++) s += (a[i] - b[i]) ** 2;\n return Math.sqrt(s);\n}\n\n/** What the resolver needs to measure a candidate against a trial δ. */\ninterface Measure {\n /** Screen pixels the probe moves going from δ0 (projected into `H`) to\n * `delta`; NaN when either end has no finite screen position. */\n move(probeId: string, probe: Vec, delta: Vec): number;\n eps: number;\n}\n\nfunction makeMeasure<M>(problem: SnapProblem<M>, base: Vec, eps: number): Measure {\n const home = new Map<string, Vec>();\n return {\n eps,\n move(probeId, probe, delta) {\n let h = home.get(probeId);\n if (!h) home.set(probeId, (h = problem.toScreen(plus(probe, base))));\n const d = distance(problem.toScreen(plus(probe, delta)), h);\n return Number.isFinite(d) ? d : NaN;\n },\n };\n}\n\nfunction spanHolds<M>(c: SnapCandidate<M>, world: Vec, eps: number): boolean {\n if (!c.span) return true;\n const u = solveLeastSquares(c.locus.dirs, minus(world, c.locus.at));\n return c.span.every(([lo, hi], i) => u[i] >= lo - eps && u[i] <= hi + eps);\n}\n\n/** The probe's screen move under `delta`, or null when it is out of reach or off the span. */\nfunction meets<M>(m: Measure, c: SnapCandidate<M>, probe: Vec, delta: Vec): number | null {\n const measured = m.move(c.probe, probe, delta);\n if (!c.required && (Number.isNaN(measured) || !(measured <= c.reachPx))) return null;\n const px = Number.isNaN(measured) ? Infinity : measured;\n return spanHolds(c, plus(probe, delta), m.eps) ? px : null;\n}\n\nfunction liveCandidates<M>(problem: SnapProblem<M>, m: Measure): Live<M>[] {\n const probes = new Map(problem.probes.map((p) => [p.id, p.at]));\n const live: Live<M>[] = [];\n for (const c of problem.candidates) {\n const probe = probes.get(c.probe);\n if (!probe || !isFiniteVec(probe) || !isFiniteVec(c.locus.at) || !c.locus.dirs.every(isFiniteVec)) continue;\n const within = intersectFlats(problem.input, { at: minus(c.locus.at, probe), dirs: c.locus.dirs }, m.eps);\n if (!within) continue;\n const px = meets(m, c, probe, closestOnFlat(within, problem.delta0));\n if (px !== null) live.push({ c, probe, within, px });\n }\n return live;\n}\n\nfunction pool<M>(live: Live<M>[], size: number): Live<M>[] {\n const byProbe = new Map<string, Live<M>[]>();\n for (const l of live) {\n const list = byProbe.get(l.c.probe) ?? [];\n list.push(l);\n byProbe.set(l.c.probe, list);\n }\n const out: Live<M>[] = [];\n for (const list of byProbe.values()) {\n list.sort((a, b) => (Math.abs(a.px - b.px) > SAME_PX ? a.px - b.px : a.c.order - b.c.order));\n out.push(...list.filter((l, i) => i < size || l.c.required));\n }\n return out;\n}\n\nfunction compareOrders<M>(a: Live<M>[], b: Live<M>[]): number {\n const oa = a.map((l) => l.c.order).sort((x, y) => x - y);\n const ob = b.map((l) => l.c.order).sort((x, y) => x - y);\n for (let i = 0; i < Math.min(oa.length, ob.length); i++) if (oa[i] !== ob[i]) return oa[i] - ob[i];\n return oa.length - ob.length;\n}\n\n/** Negative when `a` ranks ahead of `b`. */\nfunction compareCombos<M>(a: Combo<M>, b: Combo<M>): number {\n if (a.codim !== b.codim) return b.codim - a.codim;\n if (a.targetCodim !== b.targetCodim) return b.targetCodim - a.targetCodim;\n if (Math.abs(a.px - b.px) > SAME_PX) return a.px - b.px;\n return compareOrders(a.members, b.members);\n}\n\n/** `parent` plus `l`, or null when `l` adds no constraint or breaks a member's reach or span. */\nfunction extend<M>(parent: Combo<M>, l: Live<M>, input: Flat, delta0: Vec, m: Measure): Combo<M> | null {\n const hDim = flatDim(input);\n const flat = intersectFlats(parent.flat, l.within, m.eps);\n if (!flat) return null;\n const dim = flatDim(flat);\n if (dim >= parent.dim) return null;\n const delta = closestOnFlat(flat, delta0);\n if (!isFiniteVec(delta)) return null;\n const members = [...parent.members, l];\n for (const mem of members) if (meets(m, mem.c, mem.probe, delta) === null) return null;\n const targetFlat = l.c.tier === 'target'\n ? intersectFlats(parent.targetFlat, l.within, m.eps) ?? flat\n : parent.targetFlat;\n const kept = prune(members, input, dim, flatDim(targetFlat), m.eps);\n let px = 0;\n for (const mem of kept) {\n const p = meets(m, mem.c, mem.probe, delta);\n if (p === null) return null;\n px = Math.max(px, p);\n }\n return {\n members: kept, flat, dim, targetFlat, delta, px,\n codim: hDim - dim,\n targetCodim: hDim - flatDim(targetFlat),\n };\n}\n\n/** The flat `members` pin inside `input`, and the one their target-tier members pin. */\nfunction flatsOf<M>(members: readonly Live<M>[], input: Flat, eps: number): { dim: number; targetDim: number } | null {\n let flat: Flat | null = input;\n let target: Flat = input;\n for (const mem of members) {\n flat = intersectFlats(flat, mem.within, eps);\n if (!flat) return null;\n if (mem.c.tier === 'target') target = intersectFlats(target, mem.within, eps) ?? flat;\n }\n return { dim: flatDim(flat), targetDim: flatDim(target) };\n}\n\n/** `members` less every one the rest already imply, oldest first, so a\n * redundant member neither shows in `members` nor decides a tie on order. */\nfunction prune<M>(members: Live<M>[], input: Flat, dim: number, targetDim: number, eps: number): Live<M>[] {\n let kept = members;\n for (let i = 0; i < kept.length && kept.length > 1;) {\n const rest = kept.filter((_, j) => j !== i);\n const f = flatsOf(rest, input, eps);\n if (f && f.dim === dim && f.targetDim === targetDim) kept = rest;\n else i++;\n }\n return kept;\n}\n\n/** The best combination; when any can include a required candidate, the best of those. */\nfunction search<M>(candidates: Live<M>[], root: Combo<M>, delta0: Vec, m: Measure): Combo<M> {\n const best: { any: Combo<M>; required: Combo<M> | null } = { any: root, required: null };\n const consider = (c: Combo<M>) => {\n if (compareCombos(c, best.any) < 0) best.any = c;\n if (c.members.some((l) => l.c.required) && (!best.required || compareCombos(c, best.required) < 0)) {\n best.required = c;\n }\n };\n const visit = (start: number, parent: Combo<M>) => {\n for (let i = start; i < candidates.length; i++) {\n const next = extend(parent, candidates[i], root.flat, delta0, m);\n if (!next) continue;\n consider(next);\n if (next.dim > 0) visit(i + 1, next);\n }\n };\n visit(0, root);\n return best.required ?? best.any;\n}\n\nfunction satisfiedBy<M>(problem: SnapProblem<M>, delta: Vec, m: Measure): SnapCandidate<M>[] {\n const probes = new Map(problem.probes.map((p) => [p.id, p.at]));\n return problem.candidates.filter((c) => {\n const probe = probes.get(c.probe);\n if (!probe) return false;\n const world = plus(probe, delta);\n if (!(distance(closestOnFlat(c.locus, world), world) <= m.eps)) return false;\n return meets(m, c, probe, delta) !== null;\n });\n}\n\n/** The move nearest `delta0` within `H` that meets the best-ranked set of\n * candidates in reach, or `delta0` projected into `H` when none is. */\nexport function resolveSnap<M>(problem: SnapProblem<M>): SnapResolution<M> {\n const { input, delta0 } = problem;\n let base = closestOnFlat(input, delta0);\n if (!isFiniteVec(base)) base = isFiniteVec(input.at) ? input.at : input.at.map(() => 0);\n const m = makeMeasure(problem, base, problem.eps ?? DEFAULT_EPS);\n const hDim = flatDim(input);\n const root: Combo<M> = {\n members: [], flat: input, dim: hDim, targetFlat: input, delta: base, codim: 0, targetCodim: 0, px: 0,\n };\n const live = pool(liveCandidates(problem, m), problem.poolSize ?? DEFAULT_POOL);\n const win = search(live, root, delta0, m);\n return {\n delta: win.delta,\n members: win.members.map((l) => l.c),\n satisfied: satisfiedBy(problem, win.delta, m),\n codim: win.codim,\n };\n}\n","import type { Flat, Vec } from './flat';\n\n/**\n * The line through `about` whose direction, measured in the plane `basis`\n * spans (as an angle from `basis[0]` toward `basis[1]`), is the multiple of\n * `step` nearest the direction from `about` to `toward`: a constrained\n * gesture's input subspace, in any dimension. `basis` is orthonormal.\n */\nexport function stepLine(about: Vec, toward: Vec, basis: readonly [Vec, Vec], step: number): Flat {\n const [u, v] = basis;\n let a = 0;\n let b = 0;\n for (let i = 0; i < about.length; i++) {\n const d = toward[i] - about[i];\n a += d * u[i];\n b += d * v[i];\n }\n const theta = a === 0 && b === 0 ? 0 : Math.round(Math.atan2(b, a) / step) * step;\n const c = Math.cos(theta);\n const s = Math.sin(theta);\n return { at: about, dirs: [u.map((x, i) => x * c + v[i] * s)] };\n}\n","/**\n * A value built from a source only once the source has held still. Each read\n * passes the source's key, a tuple of whatever its value is a function of\n * (versions, generations, the identity of an input). A read at a key that\n * differs from the last one records it and answers null, so the caller works\n * without the value; the `reads`-th read in a row at one key builds it, and\n * later reads at that key return the same value. A source whose key changes\n * before every read never pays for a build.\n *\n * Keys match element by element under `Object.is`.\n */\nexport interface SettledCache<T> {\n /** The value for `key`, built by `build` on the read that settles it; null before that. */\n read(key: readonly unknown[], build: () => T): T | null;\n /** Forget the recorded key and any value, as if never read. */\n clear(): void;\n}\n\n/** Options for {@link createSettledCache}. */\nexport interface SettledCacheOptions {\n /** Which read in a row at one key builds the value. Default 2: a source must\n * be read once unchanged before it is worth building over. 1 builds on the\n * first read, which makes the cache a plain memo keyed the same way. */\n reads?: number;\n}\n\nfunction sameKey(a: readonly unknown[], b: readonly unknown[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return false;\n return true;\n}\n\n/** A {@link SettledCache} that builds on the `reads`-th read in a row at one key. */\nexport function createSettledCache<T>({ reads = 2 }: SettledCacheOptions = {}): SettledCache<T> {\n if (!(reads >= 1) || !Number.isInteger(reads)) throw new RangeError(`createSettledCache: reads must be a positive integer, got ${reads}`);\n let seen: readonly unknown[] | undefined;\n let count = 0;\n let built: { value: T } | null = null;\n return {\n read(key, build) {\n if (seen === undefined || !sameKey(seen, key)) {\n seen = key.slice();\n count = 0;\n built = null;\n }\n if (built !== null) return built.value;\n if (++count < reads) return null;\n built = { value: build() };\n return built.value;\n },\n clear() {\n seen = undefined;\n count = 0;\n built = null;\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/snap/flat.ts","../../src/snap/resolve.ts","../../src/snap/stepLine.ts","../../src/bvh/settledCache.ts"],"names":["isFiniteVec"],"mappings":"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","file":"index.js","sourcesContent":["/** Affine subspaces (\"flats\") over plain number arrays, in any dimension:\n * the points, lines and planes a snap resolves against. */\n\nexport type Vec = readonly number[];\n\n/** The affine subspace `at + span(dirs)`. `dirs` need not be orthonormal or\n * independent; a zero or repeated direction adds nothing. */\nexport interface Flat {\n at: Vec;\n dirs: readonly Vec[];\n}\n\n/** A direction left with less than this fraction of its length after the\n * ones before it are taken out counts as dependent on them. The solve's\n * pivots are those leftover lengths squared, so it shares this one value.\n * Squaring loses angles below about 1e-8 rad to rounding; at 1e-8 the two\n * verdicts part, so this sits two decades clear. */\nconst RANK_TOL = 1e-6;\n\nfunction dotv(a: Vec, b: Vec): number {\n let s = 0;\n for (let i = 0; i < a.length; i++) s += a[i] * b[i];\n return s;\n}\n\nfunction normv(a: Vec): number {\n return Math.sqrt(dotv(a, a));\n}\n\nfunction isFiniteVec(a: Vec): boolean {\n return a.every(Number.isFinite);\n}\n\n/** An orthonormal basis of `span(vecs)`, built by Gram-Schmidt with a second\n * pass for stability. Non-finite and dependent vectors are dropped. */\nexport function orthonormalize(vecs: readonly Vec[], start: readonly Vec[] = []): number[][] {\n const basis: number[][] = start.map((q) => q.slice());\n const out: number[][] = [];\n for (const d of vecs) {\n const n0 = normv(d);\n if (!(n0 > 0) || !isFiniteVec(d)) continue;\n const v = d.slice();\n for (let pass = 0; pass < 2; pass++) {\n for (const q of basis) {\n const k = dotv(v, q);\n for (let i = 0; i < v.length; i++) v[i] -= k * q[i];\n }\n }\n const n = normv(v);\n if (n <= RANK_TOL * n0) continue;\n for (let i = 0; i < v.length; i++) v[i] /= n;\n basis.push(v);\n out.push(v);\n }\n return out;\n}\n\n/** An orthonormal basis of the orthogonal complement of the orthonormal `basis` in R^n. */\nfunction complement(basis: readonly Vec[], n: number): number[][] {\n const axes: number[][] = [];\n for (let i = 0; i < n; i++) axes.push(Array.from({ length: n }, (_, j) => (i === j ? 1 : 0)));\n return orthonormalize(axes, basis);\n}\n\n/** The flat's dimension: the rank of its directions. */\nexport function flatDim(f: Flat): number {\n return orthonormalize(f.dirs).length;\n}\n\n/** The point of `f` nearest `p`. */\nexport function closestOnFlat(f: Flat, p: Vec): Vec {\n const out = f.at.slice();\n for (const q of orthonormalize(f.dirs)) {\n let k = 0;\n for (let i = 0; i < q.length; i++) k += q[i] * (p[i] - f.at[i]);\n for (let i = 0; i < out.length; i++) out[i] += k * q[i];\n }\n return out;\n}\n\n/**\n * The `x` minimizing `|Σ x_j cols_j − rhs|`, through the normal equations.\n * A column within `RANK_TOL` of the span of the kept ones before it is\n * dropped, the same verdict `orthonormalize` reaches, and its unknown is zero.\n */\nexport function solveLeastSquares(cols: readonly Vec[], rhs: Vec): number[] {\n const k = cols.length;\n const m = cols.map((a) => [...cols.map((b) => dotv(a, b)), dotv(a, rhs)]);\n const len2 = m.map((r, i) => r[i]);\n const kept: number[] = [];\n for (let col = 0; col < k; col++) {\n if (!(m[col][col] > RANK_TOL * RANK_TOL * len2[col])) continue;\n for (let r = col + 1; r < k; r++) {\n const f = m[r][col] / m[col][col];\n for (let c = col; c <= k; c++) m[r][c] -= f * m[col][c];\n }\n kept.push(col);\n }\n const x = new Array<number>(k).fill(0);\n for (let p = kept.length - 1; p >= 0; p--) {\n const col = kept[p];\n let s = m[col][k];\n for (let c = col + 1; c < k; c++) s -= m[col][c] * x[c];\n x[col] = s / m[col][col];\n }\n return x;\n}\n\n/** The nearest pair of points, one on each flat. Parallel flats have many\n * such pairs; this returns one of them. */\nexport function closestBetweenFlats(a: Flat, b: Flat): { onA: Vec; onB: Vec } {\n const qa = orthonormalize(a.dirs);\n const qb = orthonormalize(b.dirs);\n const d = b.at.map((v, i) => v - a.at[i]);\n const x = solveLeastSquares([...qa, ...qb.map((q) => q.map((v) => -v))], d);\n const onA = a.at.slice();\n const onB = b.at.slice();\n qa.forEach((q, j) => q.forEach((v, i) => { onA[i] += x[j] * v; }));\n qb.forEach((q, j) => q.forEach((v, i) => { onB[i] += x[qa.length + j] * v; }));\n return { onA, onB };\n}\n\n/** `a ∩ b`, or null when they miss each other by more than `eps`. */\nexport function intersectFlats(a: Flat, b: Flat, eps = 1e-6): Flat | null {\n const { onA, onB } = closestBetweenFlats(a, b);\n let gap2 = 0;\n for (let i = 0; i < onA.length; i++) gap2 += (onA[i] - onB[i]) ** 2;\n if (!(Math.sqrt(gap2) <= eps) || !isFiniteVec(onA)) return null;\n const n = a.at.length;\n const normals = orthonormalize([\n ...complement(orthonormalize(a.dirs), n),\n ...complement(orthonormalize(b.dirs), n),\n ]);\n return { at: onA, dirs: complement(normals, n) };\n}\n","/** The snap resolver: every gesture's snap, in any dimension, as one search\n * over affine constraints on the move `δ`. */\n\nimport { closestOnFlat, flatDim, intersectFlats, solveLeastSquares, type Flat, type Vec } from './flat';\nimport { distance } from '../points';\n\n/** A `fallback` candidate holds only the axes no `target` claims. */\nexport type SnapTier = 'target' | 'fallback';\n/** What a probe stands for on the subject; sources match probes by role.\n * `'anchor'` is a point a node declares in its own box frame. */\nexport type ProbeRole = 'origin' | 'box' | 'geometry' | 'pointer' | 'anchor';\n\n/** A point on the subject that should land on a locus. `role` says which\n * sources may match it. */\nexport interface SnapProbe {\n id: string;\n at: Vec;\n role: ProbeRole;\n}\n\n/** One probe paired with one locus. `M` is the mark payload, opaque here. */\nexport interface SnapCandidate<M> {\n /** `SnapProbe.id`. */\n probe: string;\n locus: Flat;\n /** One interval per locus dir, in multiples of that dir. A solution\n * outside it fails the candidate. */\n span?: readonly (readonly [number, number])[];\n source: string;\n /** Stable tiebreak: lower wins when everything else is equal. */\n order: number;\n tier: SnapTier;\n reachPx: number;\n /** When any required candidate exists, the result includes one of them,\n * whatever its reach. */\n required?: boolean;\n mark?: M;\n}\n\n/** One frame's snap: the probes, the input subspace, the raw move, and the candidates. */\nexport interface SnapProblem<M> {\n probes: readonly SnapProbe[];\n /** `H`, the subspace of δ-space the result stays inside. */\n input: Flat;\n /** The unsnapped move. */\n delta0: Vec;\n candidates: readonly SnapCandidate<M>[];\n /** World to screen pixels. A non-finite result puts that position out of reach. */\n toScreen(world: Vec): Vec;\n /** Candidates kept per probe, nearest first, besides the required ones,\n * which are all kept. Default 24. */\n poolSize?: number;\n /** World-space tolerance for \"on the locus\". Default 1e-6. */\n eps?: number;\n}\n\n/** The move `resolveSnap` chose and the candidates it meets. */\nexport interface SnapResolution<M> {\n /** `closestOnFlat(input, delta0)` when nothing snaps. */\n delta: Vec;\n members: readonly SnapCandidate<M>[];\n /** Every in-reach candidate the result meets: the ones whose marks show. */\n satisfied: readonly SnapCandidate<M>[];\n /** How many dimensions of `H` the result pins. */\n codim: number;\n}\n\n/** A candidate that can be met on its own: its probe, and `H ∩ C` in δ-space. */\ninterface Live<M> {\n c: SnapCandidate<M>;\n probe: Vec;\n within: Flat;\n px: number;\n}\n\ninterface Combo<M> {\n members: Live<M>[];\n flat: Flat;\n dim: number;\n targetFlat: Flat;\n delta: Vec;\n codim: number;\n targetCodim: number;\n px: number;\n}\n\nconst DEFAULT_POOL = 24;\nconst DEFAULT_EPS = 1e-6;\n/** Screen displacements closer than this rank as equal, so order decides. */\nconst SAME_PX = 1e-9;\n\nconst plus = (a: Vec, b: Vec): Vec => a.map((v, i) => v + b[i]);\nconst minus = (a: Vec, b: Vec): Vec => a.map((v, i) => v - b[i]);\nconst isFiniteVec = (a: Vec): boolean => a.every(Number.isFinite);\n\n/** What the resolver needs to measure a candidate against a trial δ. */\ninterface Measure {\n /** Screen pixels the probe moves going from δ0 (projected into `H`) to\n * `delta`; NaN when either end has no finite screen position. */\n move(probeId: string, probe: Vec, delta: Vec): number;\n eps: number;\n}\n\nfunction makeMeasure<M>(problem: SnapProblem<M>, base: Vec, eps: number): Measure {\n const home = new Map<string, Vec>();\n return {\n eps,\n move(probeId, probe, delta) {\n let h = home.get(probeId);\n if (!h) home.set(probeId, (h = problem.toScreen(plus(probe, base))));\n const d = distance(problem.toScreen(plus(probe, delta)), h);\n return Number.isFinite(d) ? d : NaN;\n },\n };\n}\n\nfunction spanHolds<M>(c: SnapCandidate<M>, world: Vec, eps: number): boolean {\n if (!c.span) return true;\n const u = solveLeastSquares(c.locus.dirs, minus(world, c.locus.at));\n return c.span.every(([lo, hi], i) => u[i] >= lo - eps && u[i] <= hi + eps);\n}\n\n/** The probe's screen move under `delta`, or null when it is out of reach or off the span. */\nfunction meets<M>(m: Measure, c: SnapCandidate<M>, probe: Vec, delta: Vec): number | null {\n const measured = m.move(c.probe, probe, delta);\n if (!c.required && (Number.isNaN(measured) || !(measured <= c.reachPx))) return null;\n const px = Number.isNaN(measured) ? Infinity : measured;\n return spanHolds(c, plus(probe, delta), m.eps) ? px : null;\n}\n\nfunction liveCandidates<M>(problem: SnapProblem<M>, m: Measure): Live<M>[] {\n const probes = new Map(problem.probes.map((p) => [p.id, p.at]));\n const live: Live<M>[] = [];\n for (const c of problem.candidates) {\n const probe = probes.get(c.probe);\n if (!probe || !isFiniteVec(probe) || !isFiniteVec(c.locus.at) || !c.locus.dirs.every(isFiniteVec)) continue;\n const within = intersectFlats(problem.input, { at: minus(c.locus.at, probe), dirs: c.locus.dirs }, m.eps);\n if (!within) continue;\n const px = meets(m, c, probe, closestOnFlat(within, problem.delta0));\n if (px !== null) live.push({ c, probe, within, px });\n }\n return live;\n}\n\nfunction pool<M>(live: Live<M>[], size: number): Live<M>[] {\n const byProbe = new Map<string, Live<M>[]>();\n for (const l of live) {\n const list = byProbe.get(l.c.probe) ?? [];\n list.push(l);\n byProbe.set(l.c.probe, list);\n }\n const out: Live<M>[] = [];\n for (const list of byProbe.values()) {\n list.sort((a, b) => (Math.abs(a.px - b.px) > SAME_PX ? a.px - b.px : a.c.order - b.c.order));\n out.push(...list.filter((l, i) => i < size || l.c.required));\n }\n return out;\n}\n\nfunction compareOrders<M>(a: Live<M>[], b: Live<M>[]): number {\n const oa = a.map((l) => l.c.order).sort((x, y) => x - y);\n const ob = b.map((l) => l.c.order).sort((x, y) => x - y);\n for (let i = 0; i < Math.min(oa.length, ob.length); i++) if (oa[i] !== ob[i]) return oa[i] - ob[i];\n return oa.length - ob.length;\n}\n\n/** Negative when `a` ranks ahead of `b`. */\nfunction compareCombos<M>(a: Combo<M>, b: Combo<M>): number {\n if (a.codim !== b.codim) return b.codim - a.codim;\n if (a.targetCodim !== b.targetCodim) return b.targetCodim - a.targetCodim;\n if (Math.abs(a.px - b.px) > SAME_PX) return a.px - b.px;\n return compareOrders(a.members, b.members);\n}\n\n/** `parent` plus `l`, or null when `l` adds no constraint or breaks a member's reach or span. */\nfunction extend<M>(parent: Combo<M>, l: Live<M>, input: Flat, delta0: Vec, m: Measure): Combo<M> | null {\n const hDim = flatDim(input);\n const flat = intersectFlats(parent.flat, l.within, m.eps);\n if (!flat) return null;\n const dim = flatDim(flat);\n if (dim >= parent.dim) return null;\n const delta = closestOnFlat(flat, delta0);\n if (!isFiniteVec(delta)) return null;\n const members = [...parent.members, l];\n for (const mem of members) if (meets(m, mem.c, mem.probe, delta) === null) return null;\n const targetFlat = l.c.tier === 'target'\n ? intersectFlats(parent.targetFlat, l.within, m.eps) ?? flat\n : parent.targetFlat;\n const kept = prune(members, input, dim, flatDim(targetFlat), m.eps);\n let px = 0;\n for (const mem of kept) {\n const p = meets(m, mem.c, mem.probe, delta);\n if (p === null) return null;\n px = Math.max(px, p);\n }\n return {\n members: kept, flat, dim, targetFlat, delta, px,\n codim: hDim - dim,\n targetCodim: hDim - flatDim(targetFlat),\n };\n}\n\n/** The flat `members` pin inside `input`, and the one their target-tier members pin. */\nfunction flatsOf<M>(members: readonly Live<M>[], input: Flat, eps: number): { dim: number; targetDim: number } | null {\n let flat: Flat | null = input;\n let target: Flat = input;\n for (const mem of members) {\n flat = intersectFlats(flat, mem.within, eps);\n if (!flat) return null;\n if (mem.c.tier === 'target') target = intersectFlats(target, mem.within, eps) ?? flat;\n }\n return { dim: flatDim(flat), targetDim: flatDim(target) };\n}\n\n/** `members` less every one the rest already imply, oldest first, so a\n * redundant member neither shows in `members` nor decides a tie on order. */\nfunction prune<M>(members: Live<M>[], input: Flat, dim: number, targetDim: number, eps: number): Live<M>[] {\n let kept = members;\n for (let i = 0; i < kept.length && kept.length > 1;) {\n const rest = kept.filter((_, j) => j !== i);\n const f = flatsOf(rest, input, eps);\n if (f && f.dim === dim && f.targetDim === targetDim) kept = rest;\n else i++;\n }\n return kept;\n}\n\n/** The best combination; when any can include a required candidate, the best of those. */\nfunction search<M>(candidates: Live<M>[], root: Combo<M>, delta0: Vec, m: Measure): Combo<M> {\n const best: { any: Combo<M>; required: Combo<M> | null } = { any: root, required: null };\n const consider = (c: Combo<M>) => {\n if (compareCombos(c, best.any) < 0) best.any = c;\n if (c.members.some((l) => l.c.required) && (!best.required || compareCombos(c, best.required) < 0)) {\n best.required = c;\n }\n };\n const visit = (start: number, parent: Combo<M>) => {\n for (let i = start; i < candidates.length; i++) {\n const next = extend(parent, candidates[i], root.flat, delta0, m);\n if (!next) continue;\n consider(next);\n if (next.dim > 0) visit(i + 1, next);\n }\n };\n visit(0, root);\n return best.required ?? best.any;\n}\n\nfunction satisfiedBy<M>(problem: SnapProblem<M>, delta: Vec, m: Measure): SnapCandidate<M>[] {\n const probes = new Map(problem.probes.map((p) => [p.id, p.at]));\n return problem.candidates.filter((c) => {\n const probe = probes.get(c.probe);\n if (!probe) return false;\n const world = plus(probe, delta);\n if (!(distance(closestOnFlat(c.locus, world), world) <= m.eps)) return false;\n return meets(m, c, probe, delta) !== null;\n });\n}\n\n/** The move nearest `delta0` within `H` that meets the best-ranked set of\n * candidates in reach, or `delta0` projected into `H` when none is. */\nexport function resolveSnap<M>(problem: SnapProblem<M>): SnapResolution<M> {\n const { input, delta0 } = problem;\n let base = closestOnFlat(input, delta0);\n if (!isFiniteVec(base)) base = isFiniteVec(input.at) ? input.at : input.at.map(() => 0);\n const m = makeMeasure(problem, base, problem.eps ?? DEFAULT_EPS);\n const hDim = flatDim(input);\n const root: Combo<M> = {\n members: [], flat: input, dim: hDim, targetFlat: input, delta: base, codim: 0, targetCodim: 0, px: 0,\n };\n const live = pool(liveCandidates(problem, m), problem.poolSize ?? DEFAULT_POOL);\n const win = search(live, root, delta0, m);\n return {\n delta: win.delta,\n members: win.members.map((l) => l.c),\n satisfied: satisfiedBy(problem, win.delta, m),\n codim: win.codim,\n };\n}\n","import type { Flat, Vec } from './flat';\n\n/**\n * The line through `about` whose direction, measured in the plane `basis`\n * spans (as an angle from `basis[0]` toward `basis[1]`), is the multiple of\n * `step` nearest the direction from `about` to `toward`: a constrained\n * gesture's input subspace, in any dimension. `basis` is orthonormal.\n */\nexport function stepLine(about: Vec, toward: Vec, basis: readonly [Vec, Vec], step: number): Flat {\n const [u, v] = basis;\n let a = 0;\n let b = 0;\n for (let i = 0; i < about.length; i++) {\n const d = toward[i] - about[i];\n a += d * u[i];\n b += d * v[i];\n }\n const theta = a === 0 && b === 0 ? 0 : Math.round(Math.atan2(b, a) / step) * step;\n const c = Math.cos(theta);\n const s = Math.sin(theta);\n return { at: about, dirs: [u.map((x, i) => x * c + v[i] * s)] };\n}\n","/**\n * A value built from a source only once the source has held still. Each read\n * passes the source's key, a tuple of whatever its value is a function of\n * (versions, generations, the identity of an input). A read at a key that\n * differs from the last one records it and answers null, so the caller works\n * without the value; the `reads`-th read in a row at one key builds it, and\n * later reads at that key return the same value. A source whose key changes\n * before every read never pays for a build.\n *\n * Keys match element by element under `Object.is`.\n */\nexport interface SettledCache<T> {\n /** The value for `key`, built by `build` on the read that settles it; null before that. */\n read(key: readonly unknown[], build: () => T): T | null;\n /** Forget the recorded key and any value, as if never read. */\n clear(): void;\n}\n\n/** Options for {@link createSettledCache}. */\nexport interface SettledCacheOptions {\n /** Which read in a row at one key builds the value. Default 2: a source must\n * be read once unchanged before it is worth building over. 1 builds on the\n * first read, which makes the cache a plain memo keyed the same way. */\n reads?: number;\n}\n\nfunction sameKey(a: readonly unknown[], b: readonly unknown[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return false;\n return true;\n}\n\n/** A {@link SettledCache} that builds on the `reads`-th read in a row at one key. */\nexport function createSettledCache<T>({ reads = 2 }: SettledCacheOptions = {}): SettledCache<T> {\n if (!(reads >= 1) || !Number.isInteger(reads)) throw new RangeError(`createSettledCache: reads must be a positive integer, got ${reads}`);\n let seen: readonly unknown[] | undefined;\n let count = 0;\n let built: { value: T } | null = null;\n return {\n read(key, build) {\n if (seen === undefined || !sameKey(seen, key)) {\n seen = key.slice();\n count = 0;\n built = null;\n }\n if (built !== null) return built.value;\n if (++count < reads) return null;\n built = { value: build() };\n return built.value;\n },\n clear() {\n seen = undefined;\n count = 0;\n built = null;\n },\n };\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { a as Path } from '../path-t80OoJnM.js';
|
|
2
|
+
import { b as LengthRun } from '../lengthTable-Cv3W6lsH.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* A tessellated representation of a Path, ready to upload to GL.
|
|
@@ -62,6 +63,9 @@ interface Polyline {
|
|
|
62
63
|
anchorB?: Uint32Array;
|
|
63
64
|
/** For each point, the arc-length fraction along (A, B). 0 at anchor A; for anchor-aligned, set to 0. */
|
|
64
65
|
anchorT?: Float32Array;
|
|
66
|
+
/** A closed contour's last anchor when it repeated the first point and was
|
|
67
|
+
* dropped for that; the closing edge ends at it. */
|
|
68
|
+
closeAnchor?: number;
|
|
65
69
|
/** Per-point stroke width, populated by the tessellator when the Stroke
|
|
66
70
|
* carries `vertexWidths`. Undefined means uniform `Stroke.width`. */
|
|
67
71
|
widths?: Float32Array;
|
|
@@ -102,6 +106,24 @@ declare function extractPolylines(path: Path, opts?: ExtractOptions): Polyline[]
|
|
|
102
106
|
*/
|
|
103
107
|
declare function trimPolyline(pl: Polyline, startInset: number, endInset: number): Polyline | null;
|
|
104
108
|
|
|
109
|
+
/** A curve position found on one flattening of its run. */
|
|
110
|
+
interface PolylinePlace {
|
|
111
|
+
/** How far from the polyline's first point it sits, along the polyline: the polyline's own measure. */
|
|
112
|
+
length: number;
|
|
113
|
+
/** The point itself, on the curve rather than on the chord beside it. */
|
|
114
|
+
x: number;
|
|
115
|
+
y: number;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Where curve position (`segment`, `t`) falls on `pl`, a flattening of `run`.
|
|
119
|
+
* Segment `k` runs from `pl`'s `k`-th anchor-aligned point to the next, a
|
|
120
|
+
* closed `pl`'s closing edge last, as `pathLengthTable` counts them; `run`
|
|
121
|
+
* gives each curve's control points, and without one every segment is
|
|
122
|
+
* straight. The ends come from `pl`, so a run of the same shape carried
|
|
123
|
+
* elsewhere (a rect shifted by alignment) places onto it too.
|
|
124
|
+
*/
|
|
125
|
+
declare function polylineAtCurve(pl: Polyline, segment: number, t: number, run?: LengthRun): PolylinePlace;
|
|
126
|
+
|
|
105
127
|
/**
|
|
106
128
|
* The anchor parameters `(A, B, t)` of a point a fraction `frac` of the way
|
|
107
129
|
* from one polyline point to the next: `t` interpolated when both lie between
|
|
@@ -109,4 +131,4 @@ declare function trimPolyline(pl: Polyline, startInset: number, endInset: number
|
|
|
109
131
|
*/
|
|
110
132
|
declare function anchorParamsBetween(a0: number, b0: number, t0: number, a1: number, b1: number, t1: number, frac: number): [number, number, number];
|
|
111
133
|
|
|
112
|
-
export { type ExtractOptions, MAX_EVENODD_RESOLVE_WORK, type Mesh, type Polyline, type TessellateOptions, anchorParamsBetween, extractPolylines, tessellate, trimPolyline };
|
|
134
|
+
export { type ExtractOptions, MAX_EVENODD_RESOLVE_WORK, type Mesh, type Polyline, type PolylinePlace, type TessellateOptions, anchorParamsBetween, extractPolylines, polylineAtCurve, tessellate, trimPolyline };
|
package/dist/tessellate/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
export { extractPolylines } from '../chunk-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import '../chunk-
|
|
5
|
-
import '../chunk-
|
|
1
|
+
export { extractPolylines, polylineAtCurve } from '../chunk-5W425HJA.js';
|
|
2
|
+
import '../chunk-QSVZO7QZ.js';
|
|
3
|
+
export { MAX_EVENODD_RESOLVE_WORK, tessellate } from '../chunk-VJG5ZWCR.js';
|
|
4
|
+
import '../chunk-TBS4NHGQ.js';
|
|
5
|
+
import '../chunk-IOD2NFHQ.js';
|
|
6
|
+
import '../chunk-346XYYMX.js';
|
|
7
|
+
import '../chunk-DNX24KBT.js';
|
|
6
8
|
|
|
7
9
|
// src/tessellate/anchorParams.ts
|
|
8
10
|
function anchorParamsBetween(a0, b0, t0, a1, b1, t1, frac) {
|
|
@@ -26,6 +28,11 @@ function sampleAt(pl, cum, A, B, T, W, O, dist, vertexFollows) {
|
|
|
26
28
|
const o = O ? O[i - 1] + (O[i] - O[i - 1]) * f : 0;
|
|
27
29
|
return { x: px + (qx - px) * f, y: py + (qy - py) * f, a, b, t, w, o, next: i };
|
|
28
30
|
}
|
|
31
|
+
var ROUNDING = 4 * 2 ** -23;
|
|
32
|
+
function nearVertex(pl, s, i) {
|
|
33
|
+
const x = pl.points[i * 2], y = pl.points[i * 2 + 1];
|
|
34
|
+
return Math.hypot(s.x - x, s.y - y) <= ROUNDING * Math.max(1, Math.abs(x), Math.abs(y));
|
|
35
|
+
}
|
|
29
36
|
function trimPolyline(pl, startInset, endInset) {
|
|
30
37
|
const from = Math.max(0, startInset);
|
|
31
38
|
const to = Math.max(0, endInset);
|
|
@@ -50,12 +57,24 @@ function trimPolyline(pl, startInset, endInset) {
|
|
|
50
57
|
if (cutB - cutA <= EPS) return null;
|
|
51
58
|
const head = sampleAt(pl, cum, A, B, T, W, O, cutA, true);
|
|
52
59
|
const tail = sampleAt(pl, cum, A, B, T, W, O, cutB, false);
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
const
|
|
60
|
+
const interior = tail.next - head.next;
|
|
61
|
+
const headOnVertex = interior > 0 && nearVertex(pl, head, head.next);
|
|
62
|
+
const tailOnVertex = interior > 0 && nearVertex(pl, tail, tail.next - 1) && interior + (headOnVertex ? 0 : 1) >= 2;
|
|
63
|
+
const points = [];
|
|
64
|
+
const aOut = [];
|
|
65
|
+
const bOut = [];
|
|
66
|
+
const tOut = [];
|
|
67
|
+
const wOut = W ? [] : void 0;
|
|
68
|
+
const oOut = O ? [] : void 0;
|
|
69
|
+
const push = (s) => {
|
|
70
|
+
points.push(s.x, s.y);
|
|
71
|
+
aOut.push(s.a);
|
|
72
|
+
bOut.push(s.b);
|
|
73
|
+
tOut.push(s.t);
|
|
74
|
+
if (wOut) wOut.push(s.w);
|
|
75
|
+
if (oOut) oOut.push(s.o);
|
|
76
|
+
};
|
|
77
|
+
if (!headOnVertex) push(head);
|
|
59
78
|
for (let i = head.next; i < tail.next; i++) {
|
|
60
79
|
points.push(pl.points[i * 2], pl.points[i * 2 + 1]);
|
|
61
80
|
aOut.push(A[i]);
|
|
@@ -64,12 +83,7 @@ function trimPolyline(pl, startInset, endInset) {
|
|
|
64
83
|
if (wOut) wOut.push(W[i]);
|
|
65
84
|
if (oOut) oOut.push(O[i]);
|
|
66
85
|
}
|
|
67
|
-
|
|
68
|
-
aOut.push(tail.a);
|
|
69
|
-
bOut.push(tail.b);
|
|
70
|
-
tOut.push(tail.t);
|
|
71
|
-
if (wOut) wOut.push(tail.w);
|
|
72
|
-
if (oOut) oOut.push(tail.o);
|
|
86
|
+
if (!tailOnVertex) push(tail);
|
|
73
87
|
return {
|
|
74
88
|
points,
|
|
75
89
|
closed: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/tessellate/anchorParams.ts","../../src/tessellate/trim.ts"],"names":[],"mappings":";;;;;;;AAKO,SAAS,oBACd,EAAA,EAAY,EAAA,EAAY,IACxB,EAAA,EAAY,EAAA,EAAY,IACxB,IAAA,EAC0B;AAC1B,EAAA,IAAI,EAAA,KAAO,EAAA,IAAM,EAAA,KAAO,EAAA,EAAI,OAAO,CAAC,EAAA,EAAI,EAAA,EAAI,EAAA,GAAA,CAAM,EAAA,GAAK,EAAA,IAAM,IAAI,CAAA;AACjE,EAAA,OAAO,IAAA,GAAO,GAAA,GAAM,CAAC,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA,GAAI,CAAC,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA;AAChD;;;ACAA,IAAM,GAAA,GAAM,IAAA;AAWZ,SAAS,QAAA,CACP,IAAc,GAAA,EACd,CAAA,EAAgB,GAAgB,CAAA,EAAiB,CAAA,EAA6B,CAAA,EAC9E,IAAA,EAGA,aAAA,EACQ;AACR,EAAA,MAAM,IAAI,GAAA,CAAI,MAAA;AACd,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,OAAO,CAAA,GAAI,CAAA,GAAI,CAAA,KAAM,aAAA,GAAgB,GAAA,CAAI,CAAC,CAAA,IAAK,IAAA,GAAO,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA,CAAA,EAAO,CAAA,EAAA;AACtE,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AAC1B,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,CAAC,CAAA,GAAI,QAAA;AACxB,EAAA,MAAM,CAAA,GAAI,MAAA,GAAS,GAAA,GAAA,CAAO,IAAA,GAAO,YAAY,MAAA,GAAS,CAAA;AAEtD,EAAA,MAAM,EAAA,GAAK,EAAA,CAAG,MAAA,CAAA,CAAQ,CAAA,GAAI,CAAA,IAAK,CAAC,CAAA,EAAG,EAAA,GAAK,EAAA,CAAG,MAAA,CAAA,CAAQ,CAAA,GAAI,CAAA,IAAK,IAAI,CAAC,CAAA;AACjE,EAAA,MAAM,EAAA,GAAK,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA,EAAG,EAAA,GAAK,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA;AAErD,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,mBAAA,CAAoB,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAC,CAAA;AAEvF,EAAA,MAAM,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,GAAA,CAAK,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAC,KAAK,CAAA,GAAI,CAAA;AACjD,EAAA,MAAM,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAC,CAAA,GAAA,CAAK,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAC,KAAK,CAAA,GAAI,CAAA;AACjD,EAAA,OAAO,EAAE,CAAA,EAAG,EAAA,GAAA,CAAM,EAAA,GAAK,EAAA,IAAM,GAAG,CAAA,EAAG,EAAA,GAAA,CAAM,EAAA,GAAK,EAAA,IAAM,GAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,MAAM,CAAA,EAAE;AAChF;AAUO,SAAS,YAAA,CACd,EAAA,EACA,UAAA,EACA,QAAA,EACiB;AACjB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,UAAU,CAAA;AACnC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAA;AAC/B,EAAA,IAAI,IAAA,IAAQ,CAAA,IAAK,EAAA,IAAM,CAAA,EAAG,OAAO,EAAA;AACjC,EAAA,IAAI,EAAA,CAAG,QAAQ,OAAO,EAAA;AAEtB,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,MAAA,CAAO,MAAA,GAAS,CAAA;AAC7B,EAAA,IAAI,CAAA,GAAI,GAAG,OAAO,IAAA;AAElB,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,OAAA,IAAW,IAAI,YAAY,CAAC,CAAA;AACzC,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,OAAA,IAAW,IAAI,YAAY,CAAC,CAAA;AACzC,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,OAAA,IAAW,IAAI,aAAa,CAAC,CAAA;AAC1C,EAAA,MAAM,IAAI,EAAA,CAAG,MAAA;AACb,EAAA,MAAM,IAAI,EAAA,CAAG,OAAA;AAEb,EAAA,MAAM,GAAA,GAAM,IAAI,YAAA,CAAa,CAAC,CAAA;AAC9B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,EAAA,GAAK,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAC,IAAI,EAAA,CAAG,MAAA,CAAA,CAAQ,CAAA,GAAI,CAAA,IAAK,CAAC,CAAA;AACnD,IAAA,MAAM,EAAA,GAAK,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,GAAI,EAAA,CAAG,MAAA,CAAA,CAAQ,CAAA,GAAI,CAAA,IAAK,CAAA,GAAI,CAAC,CAAA;AAC3D,IAAA,GAAA,CAAI,CAAC,IAAI,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA;AAAA,EACzC;AACA,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AACvB,EAAA,MAAM,IAAA,GAAO,IAAA;AACb,EAAA,MAAM,OAAO,KAAA,GAAQ,EAAA;AACrB,EAAA,IAAI,IAAA,GAAO,IAAA,IAAQ,GAAA,EAAK,OAAO,IAAA;AAE/B,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,EAAA,EAAI,GAAA,EAAK,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,IAAA,EAAM,IAAI,CAAA;AACxD,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,EAAA,EAAI,GAAA,EAAK,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,IAAA,EAAM,KAAK,CAAA;AAEzD,EAAA,MAAM,MAAA,GAAmB,CAAC,IAAA,CAAK,CAAA,EAAG,KAAK,CAAC,CAAA;AACxC,EAAA,MAAM,IAAA,GAAiB,CAAC,IAAA,CAAK,CAAC,CAAA;AAC9B,EAAA,MAAM,IAAA,GAAiB,CAAC,IAAA,CAAK,CAAC,CAAA;AAC9B,EAAA,MAAM,IAAA,GAAiB,CAAC,IAAA,CAAK,CAAC,CAAA;AAC9B,EAAA,MAAM,IAAA,GAA6B,CAAA,GAAI,CAAC,IAAA,CAAK,CAAC,CAAA,GAAI,MAAA;AAClD,EAAA,MAAM,IAAA,GAA6B,CAAA,GAAI,CAAC,IAAA,CAAK,CAAC,CAAA,GAAI,MAAA;AAElD,EAAA,KAAA,IAAS,IAAI,IAAA,CAAK,IAAA,EAAM,CAAA,GAAI,IAAA,CAAK,MAAM,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAA,CAAO,IAAA,CAAK,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA,EAAG,EAAA,CAAG,MAAA,CAAO,CAAA,GAAI,CAAA,GAAI,CAAC,CAAC,CAAA;AAClD,IAAA,IAAA,CAAK,IAAA,CAAK,CAAA,CAAE,CAAC,CAAC,CAAA;AAAG,IAAA,IAAA,CAAK,IAAA,CAAK,CAAA,CAAE,CAAC,CAAC,CAAA;AAAG,IAAA,IAAA,CAAK,IAAA,CAAK,CAAA,CAAE,CAAC,CAAC,CAAA;AAChD,IAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,CAAA,CAAG,CAAC,CAAC,CAAA;AACzB,IAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,CAAA,CAAG,CAAC,CAAC,CAAA;AAAA,EAC3B;AAEA,EAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA;AAC1B,EAAA,IAAA,CAAK,IAAA,CAAK,KAAK,CAAC,CAAA;AAAG,EAAA,IAAA,CAAK,IAAA,CAAK,KAAK,CAAC,CAAA;AAAG,EAAA,IAAA,CAAK,IAAA,CAAK,KAAK,CAAC,CAAA;AACtD,EAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAC1B,EAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAE1B,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,MAAA,EAAQ,KAAA;AAAA,IACR,OAAA,EAAS,IAAI,WAAA,CAAY,IAAI,CAAA;AAAA,IAC7B,OAAA,EAAS,IAAI,WAAA,CAAY,IAAI,CAAA;AAAA,IAC7B,OAAA,EAAS,IAAI,YAAA,CAAa,IAAI,CAAA;AAAA,IAC9B,GAAI,OAAO,EAAE,MAAA,EAAQ,IAAI,YAAA,CAAa,IAAI,CAAA,EAAE,GAAI,EAAC;AAAA,IACjD,GAAI,OAAO,EAAE,OAAA,EAAS,IAAI,YAAA,CAAa,IAAI,CAAA,EAAE,GAAI;AAAC,GACpD;AACF","file":"index.js","sourcesContent":["/**\n * The anchor parameters `(A, B, t)` of a point a fraction `frac` of the way\n * from one polyline point to the next: `t` interpolated when both lie between\n * the same two anchors, otherwise the nearer point's own.\n */\nexport function anchorParamsBetween(\n a0: number, b0: number, t0: number,\n a1: number, b1: number, t1: number,\n frac: number,\n): [number, number, number] {\n if (a0 === a1 && b0 === b1) return [a0, b0, t0 + (t1 - t0) * frac];\n return frac < 0.5 ? [a0, b0, t0] : [a1, b1, t1];\n}\n","/**\n * Shortening a flattened subpath so a filled marker is not speared by its own\n * line. SVG has no equivalent — it paints the marker over a full-length\n * stroke — so this is the one place our rendering deliberately differs.\n *\n * Runs before dash splitting, so a dash pattern fits the visible line rather\n * than running off under the head.\n */\n\nimport { anchorParamsBetween } from './anchorParams';\nimport type { Polyline } from './polyline';\n\nconst EPS = 1e-9;\n\ninterface Sample {\n x: number; y: number;\n a: number; b: number; t: number;\n w: number;\n o: number;\n /** Index of the first original point at or after this sample. */\n next: number;\n}\n\nfunction sampleAt(\n pl: Polyline, cum: Float64Array,\n A: Uint32Array, B: Uint32Array, T: Float32Array, W: Float32Array | undefined, O: Float32Array | undefined,\n dist: number,\n /** For a cut landing exactly on a vertex: whether the vertex belongs to the\n * run after the sample (a head) or before it (a tail), so it is kept once. */\n vertexFollows: boolean,\n): Sample {\n const n = cum.length;\n let i = 1;\n while (i < n - 1 && (vertexFollows ? cum[i] <= dist : cum[i] < dist)) i++;\n const segStart = cum[i - 1];\n const segLen = cum[i] - segStart;\n const f = segLen > EPS ? (dist - segStart) / segLen : 0;\n\n const px = pl.points[(i - 1) * 2], py = pl.points[(i - 1) * 2 + 1];\n const qx = pl.points[i * 2], qy = pl.points[i * 2 + 1];\n\n const [a, b, t] = anchorParamsBetween(A[i - 1], B[i - 1], T[i - 1], A[i], B[i], T[i], f);\n\n const w = W ? W[i - 1] + (W[i] - W[i - 1]) * f : 0;\n const o = O ? O[i - 1] + (O[i] - O[i - 1]) * f : 0;\n return { x: px + (qx - px) * f, y: py + (qy - py) * f, a, b, t, w, o, next: i };\n}\n\n/**\n * Shorten `pl` by `startInset` from its first point and `endInset` from its\n * last, both in the same world units as the points.\n *\n * Returns `pl` itself when there is nothing to do (both insets zero, or the\n * subpath is closed and so has no free ends), and `null` when the insets\n * consume the whole run — a caller should then draw no ribbon at all.\n */\nexport function trimPolyline(\n pl: Polyline,\n startInset: number,\n endInset: number,\n): Polyline | null {\n const from = Math.max(0, startInset);\n const to = Math.max(0, endInset);\n if (from <= 0 && to <= 0) return pl;\n if (pl.closed) return pl;\n\n const n = pl.points.length / 2;\n if (n < 2) return null;\n\n const A = pl.anchorA ?? new Uint32Array(n);\n const B = pl.anchorB ?? new Uint32Array(n);\n const T = pl.anchorT ?? new Float32Array(n);\n const W = pl.widths;\n const O = pl.offsets;\n\n const cum = new Float64Array(n);\n for (let i = 1; i < n; i++) {\n const dx = pl.points[i * 2] - pl.points[(i - 1) * 2];\n const dy = pl.points[i * 2 + 1] - pl.points[(i - 1) * 2 + 1];\n cum[i] = cum[i - 1] + Math.hypot(dx, dy);\n }\n const total = cum[n - 1];\n const cutA = from;\n const cutB = total - to;\n if (cutB - cutA <= EPS) return null;\n\n const head = sampleAt(pl, cum, A, B, T, W, O, cutA, true);\n const tail = sampleAt(pl, cum, A, B, T, W, O, cutB, false);\n\n const points: number[] = [head.x, head.y];\n const aOut: number[] = [head.a];\n const bOut: number[] = [head.b];\n const tOut: number[] = [head.t];\n const wOut: number[] | undefined = W ? [head.w] : undefined;\n const oOut: number[] | undefined = O ? [head.o] : undefined;\n\n for (let i = head.next; i < tail.next; i++) {\n points.push(pl.points[i * 2], pl.points[i * 2 + 1]);\n aOut.push(A[i]); bOut.push(B[i]); tOut.push(T[i]);\n if (wOut) wOut.push(W![i]);\n if (oOut) oOut.push(O![i]);\n }\n\n points.push(tail.x, tail.y);\n aOut.push(tail.a); bOut.push(tail.b); tOut.push(tail.t);\n if (wOut) wOut.push(tail.w);\n if (oOut) oOut.push(tail.o);\n\n return {\n points,\n closed: false,\n anchorA: new Uint32Array(aOut),\n anchorB: new Uint32Array(bOut),\n anchorT: new Float32Array(tOut),\n ...(wOut ? { widths: new Float32Array(wOut) } : {}),\n ...(oOut ? { offsets: new Float32Array(oOut) } : {}),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/tessellate/anchorParams.ts","../../src/tessellate/trim.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The anchor parameters `(A, B, t)` of a point a fraction `frac` of the way\n * from one polyline point to the next: `t` interpolated when both lie between\n * the same two anchors, otherwise the nearer point's own.\n */\nexport function anchorParamsBetween(\n a0: number, b0: number, t0: number,\n a1: number, b1: number, t1: number,\n frac: number,\n): [number, number, number] {\n if (a0 === a1 && b0 === b1) return [a0, b0, t0 + (t1 - t0) * frac];\n return frac < 0.5 ? [a0, b0, t0] : [a1, b1, t1];\n}\n","/**\n * Shortening a flattened subpath so a filled marker is not speared by its own\n * line. SVG has no equivalent — it paints the marker over a full-length\n * stroke — so this is the one place our rendering deliberately differs.\n *\n * Runs before dash splitting, so a dash pattern fits the visible line rather\n * than running off under the head.\n */\n\nimport { anchorParamsBetween } from './anchorParams';\nimport type { Polyline } from './polyline';\n\nconst EPS = 1e-9;\n\ninterface Sample {\n x: number; y: number;\n a: number; b: number; t: number;\n w: number;\n o: number;\n /** Index of the first original point at or after this sample. */\n next: number;\n}\n\nfunction sampleAt(\n pl: Polyline, cum: Float64Array,\n A: Uint32Array, B: Uint32Array, T: Float32Array, W: Float32Array | undefined, O: Float32Array | undefined,\n dist: number,\n /** For a cut landing exactly on a vertex: whether the vertex belongs to the\n * run after the sample (a head) or before it (a tail), so it is kept once. */\n vertexFollows: boolean,\n): Sample {\n const n = cum.length;\n let i = 1;\n while (i < n - 1 && (vertexFollows ? cum[i] <= dist : cum[i] < dist)) i++;\n const segStart = cum[i - 1];\n const segLen = cum[i] - segStart;\n const f = segLen > EPS ? (dist - segStart) / segLen : 0;\n\n const px = pl.points[(i - 1) * 2], py = pl.points[(i - 1) * 2 + 1];\n const qx = pl.points[i * 2], qy = pl.points[i * 2 + 1];\n\n const [a, b, t] = anchorParamsBetween(A[i - 1], B[i - 1], T[i - 1], A[i], B[i], T[i], f);\n\n const w = W ? W[i - 1] + (W[i] - W[i - 1]) * f : 0;\n const o = O ? O[i - 1] + (O[i] - O[i - 1]) * f : 0;\n return { x: px + (qx - px) * f, y: py + (qy - py) * f, a, b, t, w, o, next: i };\n}\n\n/** Float32 rounding at a coordinate's magnitude, with headroom: what points stored as\n * `Float32Array` and lengths summed in doubles can disagree by. */\nconst ROUNDING = 4 * 2 ** -23;\n\nfunction nearVertex(pl: Polyline, s: Sample, i: number): boolean {\n const x = pl.points[i * 2], y = pl.points[i * 2 + 1];\n return Math.hypot(s.x - x, s.y - y) <= ROUNDING * Math.max(1, Math.abs(x), Math.abs(y));\n}\n\n/**\n * Shorten `pl` by `startInset` from its first point and `endInset` from its\n * last, both in the same world units as the points.\n *\n * Returns `pl` itself when there is nothing to do (both insets zero, or the\n * subpath is closed and so has no free ends), and `null` when the insets\n * consume the whole run — a caller should then draw no ribbon at all.\n */\nexport function trimPolyline(\n pl: Polyline,\n startInset: number,\n endInset: number,\n): Polyline | null {\n const from = Math.max(0, startInset);\n const to = Math.max(0, endInset);\n if (from <= 0 && to <= 0) return pl;\n if (pl.closed) return pl;\n\n const n = pl.points.length / 2;\n if (n < 2) return null;\n\n const A = pl.anchorA ?? new Uint32Array(n);\n const B = pl.anchorB ?? new Uint32Array(n);\n const T = pl.anchorT ?? new Float32Array(n);\n const W = pl.widths;\n const O = pl.offsets;\n\n const cum = new Float64Array(n);\n for (let i = 1; i < n; i++) {\n const dx = pl.points[i * 2] - pl.points[(i - 1) * 2];\n const dy = pl.points[i * 2 + 1] - pl.points[(i - 1) * 2 + 1];\n cum[i] = cum[i - 1] + Math.hypot(dx, dy);\n }\n const total = cum[n - 1];\n const cutA = from;\n const cutB = total - to;\n if (cutB - cutA <= EPS) return null;\n\n const head = sampleAt(pl, cum, A, B, T, W, O, cutA, true);\n const tail = sampleAt(pl, cum, A, B, T, W, O, cutB, false);\n // A cut within float rounding of a kept vertex is that vertex: the sliver\n // between them has a direction made of noise, which skews a cap or a head.\n const interior = tail.next - head.next;\n const headOnVertex = interior > 0 && nearVertex(pl, head, head.next);\n const tailOnVertex = interior > 0 && nearVertex(pl, tail, tail.next - 1) && interior + (headOnVertex ? 0 : 1) >= 2;\n\n const points: number[] = [];\n const aOut: number[] = [];\n const bOut: number[] = [];\n const tOut: number[] = [];\n const wOut: number[] | undefined = W ? [] : undefined;\n const oOut: number[] | undefined = O ? [] : undefined;\n const push = (s: Sample) => {\n points.push(s.x, s.y);\n aOut.push(s.a); bOut.push(s.b); tOut.push(s.t);\n if (wOut) wOut.push(s.w);\n if (oOut) oOut.push(s.o);\n };\n\n if (!headOnVertex) push(head);\n for (let i = head.next; i < tail.next; i++) {\n points.push(pl.points[i * 2], pl.points[i * 2 + 1]);\n aOut.push(A[i]); bOut.push(B[i]); tOut.push(T[i]);\n if (wOut) wOut.push(W![i]);\n if (oOut) oOut.push(O![i]);\n }\n if (!tailOnVertex) push(tail);\n\n return {\n points,\n closed: false,\n anchorA: new Uint32Array(aOut),\n anchorB: new Uint32Array(bOut),\n anchorT: new Float32Array(tOut),\n ...(wOut ? { widths: new Float32Array(wOut) } : {}),\n ...(oOut ? { offsets: new Float32Array(oOut) } : {}),\n };\n}\n"]}
|
package/dist/warp/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { boundsOfPath, keepCorner, fitPointRun } from '../chunk-
|
|
2
|
-
import { pathToAnchors, anchorsToPath } from '../chunk-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import '../chunk-
|
|
7
|
-
import
|
|
1
|
+
import { boundsOfPath, keepCorner, fitPointRun } from '../chunk-ZV24QZ6X.js';
|
|
2
|
+
import { pathToAnchors, anchorsToPath } from '../chunk-HTT5AQIU.js';
|
|
3
|
+
import { nestRings, flattenPolygon, resolveCrossings } from '../chunk-VJG5ZWCR.js';
|
|
4
|
+
import { pointInPolygon } from '../chunk-TBS4NHGQ.js';
|
|
5
|
+
import '../chunk-IOD2NFHQ.js';
|
|
6
|
+
import { cubicPointAt, addOrigin, nearestOnLine, pointSegmentDist } from '../chunk-346XYYMX.js';
|
|
7
|
+
import '../chunk-DNX24KBT.js';
|
|
8
8
|
import earcut from 'earcut';
|
|
9
9
|
|
|
10
10
|
// src/warp/quad.ts
|
|
@@ -1265,10 +1265,7 @@ function nearestEdge(region, x, y) {
|
|
|
1265
1265
|
let best = { d: Infinity, ring: 0, edge: 0, t: 0 };
|
|
1266
1266
|
region.rings.forEach((ring, r) => ring.forEach((a, i) => {
|
|
1267
1267
|
const b = ring[(i + 1) % ring.length];
|
|
1268
|
-
const
|
|
1269
|
-
const len2 = dx * dx + dy * dy;
|
|
1270
|
-
const t = len2 > 0 ? Math.max(0, Math.min(1, ((x - a.x) * dx + (y - a.y) * dy) / len2)) : 0;
|
|
1271
|
-
const d = Math.hypot(a.x + dx * t - x, a.y + dy * t - y);
|
|
1268
|
+
const { t, dist: d } = nearestOnLine(x, y, a.x, a.y, b.x, b.y);
|
|
1272
1269
|
if (d < best.d) best = { d, ring: r, edge: i, t };
|
|
1273
1270
|
}));
|
|
1274
1271
|
return best;
|
|
@@ -1311,10 +1308,7 @@ function clearanceTest(rings, r) {
|
|
|
1311
1308
|
for (let i = ci - 1; i <= ci + 1; i++) {
|
|
1312
1309
|
for (let j = cj - 1; j <= cj + 1; j++) {
|
|
1313
1310
|
for (const [a, b] of cells.get(key(i, j)) ?? []) {
|
|
1314
|
-
|
|
1315
|
-
const len2 = dx * dx + dy * dy;
|
|
1316
|
-
const t = len2 > 0 ? Math.max(0, Math.min(1, ((x - a.x) * dx + (y - a.y) * dy) / len2)) : 0;
|
|
1317
|
-
if (Math.hypot(a.x + dx * t - x, a.y + dy * t - y) < r) return true;
|
|
1311
|
+
if (pointSegmentDist(x, y, a.x, a.y, b.x, b.y) < r) return true;
|
|
1318
1312
|
}
|
|
1319
1313
|
}
|
|
1320
1314
|
}
|