@oh-just-another/scene 0.57.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/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +72 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/a11y.d.ts +23 -0
- package/dist/a11y.d.ts.map +1 -0
- package/dist/a11y.js +37 -0
- package/dist/a11y.js.map +1 -0
- package/dist/anchors.d.ts +120 -0
- package/dist/anchors.d.ts.map +1 -0
- package/dist/anchors.js +322 -0
- package/dist/anchors.js.map +1 -0
- package/dist/annotation-geometry.d.ts +11 -0
- package/dist/annotation-geometry.d.ts.map +1 -0
- package/dist/annotation-geometry.js +19 -0
- package/dist/annotation-geometry.js.map +1 -0
- package/dist/annotation.d.ts +32 -0
- package/dist/annotation.d.ts.map +1 -0
- package/dist/annotation.js +2 -0
- package/dist/annotation.js.map +1 -0
- package/dist/constants.d.ts +186 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +186 -0
- package/dist/constants.js.map +1 -0
- package/dist/container.d.ts +112 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/container.js +227 -0
- package/dist/container.js.map +1 -0
- package/dist/diff.d.ts +22 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +18 -0
- package/dist/diff.js.map +1 -0
- package/dist/edge-curve.d.ts +37 -0
- package/dist/edge-curve.d.ts.map +1 -0
- package/dist/edge-curve.js +72 -0
- package/dist/edge-curve.js.map +1 -0
- package/dist/edge-geometry.d.ts +96 -0
- package/dist/edge-geometry.d.ts.map +1 -0
- package/dist/edge-geometry.js +467 -0
- package/dist/edge-geometry.js.map +1 -0
- package/dist/edge.d.ts +206 -0
- package/dist/edge.d.ts.map +1 -0
- package/dist/edge.js +2 -0
- package/dist/edge.js.map +1 -0
- package/dist/elbow-link.d.ts +23 -0
- package/dist/elbow-link.d.ts.map +1 -0
- package/dist/elbow-link.js +419 -0
- package/dist/elbow-link.js.map +1 -0
- package/dist/elbow-router.d.ts +20 -0
- package/dist/elbow-router.d.ts.map +1 -0
- package/dist/elbow-router.js +218 -0
- package/dist/elbow-router.js.map +1 -0
- package/dist/file.d.ts +41 -0
- package/dist/file.d.ts.map +1 -0
- package/dist/file.js +13 -0
- package/dist/file.js.map +1 -0
- package/dist/heading.d.ts +42 -0
- package/dist/heading.d.ts.map +1 -0
- package/dist/heading.js +77 -0
- package/dist/heading.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/layer.d.ts +18 -0
- package/dist/layer.d.ts.map +1 -0
- package/dist/layer.js +2 -0
- package/dist/layer.js.map +1 -0
- package/dist/layout-registry.d.ts +35 -0
- package/dist/layout-registry.d.ts.map +1 -0
- package/dist/layout-registry.js +13 -0
- package/dist/layout-registry.js.map +1 -0
- package/dist/layout.d.ts +128 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +453 -0
- package/dist/layout.js.map +1 -0
- package/dist/operations.d.ts +32 -0
- package/dist/operations.d.ts.map +1 -0
- package/dist/operations.js +105 -0
- package/dist/operations.js.map +1 -0
- package/dist/outline.d.ts +36 -0
- package/dist/outline.d.ts.map +1 -0
- package/dist/outline.js +129 -0
- package/dist/outline.js.map +1 -0
- package/dist/patch.d.ts +57 -0
- package/dist/patch.d.ts.map +1 -0
- package/dist/patch.js +47 -0
- package/dist/patch.js.map +1 -0
- package/dist/queries.d.ts +115 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +403 -0
- package/dist/queries.js.map +1 -0
- package/dist/render-bounds.d.ts +36 -0
- package/dist/render-bounds.d.ts.map +1 -0
- package/dist/render-bounds.js +36 -0
- package/dist/render-bounds.js.map +1 -0
- package/dist/scene.d.ts +80 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +129 -0
- package/dist/scene.js.map +1 -0
- package/dist/shape.d.ts +306 -0
- package/dist/shape.d.ts.map +1 -0
- package/dist/shape.js +192 -0
- package/dist/shape.js.map +1 -0
- package/dist/snap.d.ts +88 -0
- package/dist/snap.d.ts.map +1 -0
- package/dist/snap.js +128 -0
- package/dist/snap.js.map +1 -0
- package/dist/spatial.d.ts +38 -0
- package/dist/spatial.d.ts.map +1 -0
- package/dist/spatial.js +95 -0
- package/dist/spatial.js.map +1 -0
- package/dist/style.d.ts +87 -0
- package/dist/style.d.ts.map +1 -0
- package/dist/style.js +43 -0
- package/dist/style.js.map +1 -0
- package/dist/text-measure.d.ts +29 -0
- package/dist/text-measure.d.ts.map +1 -0
- package/dist/text-measure.js +8 -0
- package/dist/text-measure.js.map +1 -0
- package/dist/three-way-merge.d.ts +59 -0
- package/dist/three-way-merge.d.ts.map +1 -0
- package/dist/three-way-merge.js +108 -0
- package/dist/three-way-merge.js.map +1 -0
- package/dist/viewport.d.ts +78 -0
- package/dist/viewport.d.ts.map +1 -0
- package/dist/viewport.js +62 -0
- package/dist/viewport.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import { ELBOW_AVOID_MAX_OBSTACLES, ELBOW_CROSS_SAMPLE_STEP, ELBOW_OBSTACLE_CLEARANCE, ELBOW_OBSTACLE_MARGIN, ELBOW_TERMINAL_BUFFER, ELBOW_WRAP_HYSTERESIS, } from "./constants.js";
|
|
2
|
+
import { getLinkEndpointWorld } from "./edge-geometry.js";
|
|
3
|
+
import { elbowRoute } from "./elbow-router.js";
|
|
4
|
+
import { HEADING_DOWN, HEADING_LEFT, HEADING_RIGHT, HEADING_UP, headingForEdgePoint, headingForPoint, headingForPointFromElement, headingIsHorizontal, } from "./heading.js";
|
|
5
|
+
import { getElement } from "./queries.js";
|
|
6
|
+
import { getElementWorldBounds } from "./shape.js";
|
|
7
|
+
const req = (v) => {
|
|
8
|
+
if (v === undefined)
|
|
9
|
+
throw new Error("packages/scene: index out of range");
|
|
10
|
+
return v;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Compute the orthogonal (elbow) route for a link: the corner points
|
|
14
|
+
* between `from` and `to` (exclusive). This is what the editor stores on
|
|
15
|
+
* `Link.routedPoints` and `getLinkPath` renders as `[from, ...points, to]`.
|
|
16
|
+
*
|
|
17
|
+
* standard model: each end exits perpendicular to its shape (a "dongle"
|
|
18
|
+
* pushed out by `ELBOW_TERMINAL_BUFFER` along the end's heading), the A* router
|
|
19
|
+
* routes between the dongles around the two bound shapes, and the whole
|
|
20
|
+
* chain is collapsed to corner points. The result is always axis-aligned.
|
|
21
|
+
*/
|
|
22
|
+
export const routeElbowLink = (scene, edge) => {
|
|
23
|
+
const fromP = getLinkEndpointWorld(scene, edge.from);
|
|
24
|
+
const toP = getLinkEndpointWorld(scene, edge.to);
|
|
25
|
+
if (!fromP || !toP)
|
|
26
|
+
return [];
|
|
27
|
+
const from = edge.from.kind === "floating" ? (getLinkEndpointWorld(scene, edge.from, toP) ?? fromP) : fromP;
|
|
28
|
+
const to = edge.to.kind === "floating" ? (getLinkEndpointWorld(scene, edge.to, fromP) ?? toP) : toP;
|
|
29
|
+
if (from.x === to.x && from.y === to.y)
|
|
30
|
+
return [];
|
|
31
|
+
const a = endInfo(scene, edge.from, from, to);
|
|
32
|
+
const b = endInfo(scene, edge.to, to, from);
|
|
33
|
+
// The route is structured as a fixed outward BUFFER stub at each end plus a
|
|
34
|
+
// movable middle between the two stub joints (bufA / bufB). `routeMiddle`
|
|
35
|
+
// returns [bufA, ...corners..., bufB]; the buffers themselves are the
|
|
36
|
+
// from→bufA / bufB→to segments that `getLinkPath` adds when it wraps
|
|
37
|
+
// routedPoints with from/to — they're never collapsed, so an aligned elbow
|
|
38
|
+
// still has 3 segments (buffer + movable + buffer) and reads as one line.
|
|
39
|
+
// "Avoid obstacles" mode: route around EVERY scene shape, not just the two
|
|
40
|
+
// bound ends. Collect the rest of the scene as obstacles and let A* find a
|
|
41
|
+
// clear orthogonal path (the analytic mid-S / C-wrap only know the two bound
|
|
42
|
+
// boxes, so they're skipped in this mode).
|
|
43
|
+
const avoidList = edge.avoidObstacles === true ? collectAvoidObstacles(scene, edge) : undefined;
|
|
44
|
+
// Perf gate: above the cap, skip whole-scene avoidance (too many obstacle
|
|
45
|
+
// corners to A* every frame) and fall back to the cheap two-box elbow.
|
|
46
|
+
const avoid = avoidList && avoidList.length <= ELBOW_AVOID_MAX_OBSTACLES ? avoidList : undefined;
|
|
47
|
+
// Pass the previously routed path as a side-hint so the C-wrap stays on
|
|
48
|
+
// the same side under a small drag (hysteresis — see wrapRoute). This is
|
|
49
|
+
// the only history the elbow router consults; the A* core stays pure.
|
|
50
|
+
let middle = routeMiddle(from, to, a, b, edge.routedPoints, avoid);
|
|
51
|
+
middle = applyFixedSegments(middle, edge.fixedSegments);
|
|
52
|
+
return middle;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* World bboxes of every scene element EXCEPT the link's own two bound shapes
|
|
56
|
+
* (those are handled by the headings/dongles). Used by "avoid obstacles" mode.
|
|
57
|
+
*/
|
|
58
|
+
const collectAvoidObstacles = (scene, edge) => {
|
|
59
|
+
const skip = new Set();
|
|
60
|
+
for (const ep of [edge.from, edge.to])
|
|
61
|
+
if (ep.kind !== "point")
|
|
62
|
+
skip.add(ep.elementId);
|
|
63
|
+
const out = [];
|
|
64
|
+
for (const el of scene.elements.values()) {
|
|
65
|
+
if (skip.has(el.id))
|
|
66
|
+
continue;
|
|
67
|
+
out.push(getElementWorldBounds(el));
|
|
68
|
+
}
|
|
69
|
+
return out;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Live elbow path for a connector being drawn (preview): full
|
|
73
|
+
* `[from, ...corners, to]`. `fromElementId` / `toElementId` give each end
|
|
74
|
+
* its exit heading + obstacle (null for a free end — heading then points at
|
|
75
|
+
* the other end). Mirrors {@link routeElbowLink} so the dashed preview
|
|
76
|
+
* matches the committed elbow.
|
|
77
|
+
*/
|
|
78
|
+
export const routeElbowPreview = (scene, fromElementId, from, toElementId, to) => {
|
|
79
|
+
if (from.x === to.x && from.y === to.y)
|
|
80
|
+
return [from, to];
|
|
81
|
+
const a = pointEndInfo(scene, fromElementId, from, to);
|
|
82
|
+
const b = pointEndInfo(scene, toElementId, to, from);
|
|
83
|
+
return [from, ...routeMiddle(from, to, a, b), to];
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Movable middle of an elbow: the path between the two outward BUFFER stub
|
|
87
|
+
* joints (`bufA` = from pushed out along its heading, `bufB` = to pushed out
|
|
88
|
+
* along its). Returns `[bufA, ...corners..., bufB]`. The from→bufA / bufB→to
|
|
89
|
+
* stubs are added by the caller (getLinkPath / preview) and are the fixed,
|
|
90
|
+
* non-movable terminal segments. On very short links the buffer is clamped so
|
|
91
|
+
* the two stubs don't overrun each other.
|
|
92
|
+
*/
|
|
93
|
+
const routeMiddle = (from, to, a, b, prev, avoid) => {
|
|
94
|
+
// FIXED buffer: every terminal stub is exactly ELBOW_TERMINAL_BUFFER — one
|
|
95
|
+
// constant length, never shrunk. bufA / bufB are the stub joints.
|
|
96
|
+
const buf = ELBOW_TERMINAL_BUFFER;
|
|
97
|
+
const bufA = { x: from.x + a.heading.x * buf, y: from.y + a.heading.y * buf };
|
|
98
|
+
const bufB = { x: to.x + b.heading.x * buf, y: to.y + b.heading.y * buf };
|
|
99
|
+
const obstacles = [];
|
|
100
|
+
if (a.obstacle)
|
|
101
|
+
obstacles.push(a.obstacle);
|
|
102
|
+
if (b.obstacle)
|
|
103
|
+
obstacles.push(b.obstacle);
|
|
104
|
+
// Avoid-obstacles mode: route around the whole scene via A* (the analytic
|
|
105
|
+
// mid-S / C-wrap only reason about the two bound boxes). Include the bound
|
|
106
|
+
// boxes too so the route still keeps clear of its own ends.
|
|
107
|
+
if (avoid) {
|
|
108
|
+
const all = [...obstacles, ...avoid];
|
|
109
|
+
const routed = elbowRoute(bufA, bufB, all, { startHeading: a.heading, endHeading: b.heading });
|
|
110
|
+
const mid = routed && routed.length >= 2 ? routed : [bufA, fallbackCorner(bufA, bufB, a.heading), bufB];
|
|
111
|
+
return collapseColinear(mid);
|
|
112
|
+
}
|
|
113
|
+
// Collinear-opposite stubs (top↔bottom, left↔right): build a clean,
|
|
114
|
+
// deterministic centred S/Z whose crossover sits in the MIDDLE between the
|
|
115
|
+
// two stub joints — same rule whether the shapes overlap or are separated, so
|
|
116
|
+
// dragging never makes the crossover jump (A* would snap it to a grid line).
|
|
117
|
+
// Fall back to A* only if that path would clip a bound shape.
|
|
118
|
+
const midS = midS_(from, to, a, b, bufA, bufB);
|
|
119
|
+
if (midS && !pathCrossesObstacle(midS, obstacles))
|
|
120
|
+
return collapseColinear(midS);
|
|
121
|
+
// The centred crossover would clip a shape (collinear-opposite ends whose
|
|
122
|
+
// boxes overlap on the cross axis — e.g. lower.left → upper.right when the
|
|
123
|
+
// boxes overlap vertically). Wrap deterministically around the union of the
|
|
124
|
+
// obstacles on ONE consistently-chosen side instead of letting A* flip-flop
|
|
125
|
+
// between routing over the top and under the bottom as the shape is dragged.
|
|
126
|
+
const wrap = wrapRoute(from, to, a, b, bufA, bufB, obstacles, prev);
|
|
127
|
+
if (wrap && !pathCrossesObstacle(wrap, obstacles))
|
|
128
|
+
return collapseColinear(wrap);
|
|
129
|
+
const routed = elbowRoute(bufA, bufB, obstacles, {
|
|
130
|
+
startHeading: a.heading,
|
|
131
|
+
endHeading: b.heading,
|
|
132
|
+
});
|
|
133
|
+
const mid = routed && routed.length >= 2 ? routed : [bufA, fallbackCorner(bufA, bufB, a.heading), bufB];
|
|
134
|
+
// Collapse only the interior corners — collapseColinear keeps the bufA / bufB
|
|
135
|
+
// endpoints, so the stub joints survive even when colinear with the middle.
|
|
136
|
+
return collapseColinear(mid);
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* For two COLLINEAR-OPPOSITE stubs (top↔bottom or left↔right — the two exit
|
|
140
|
+
* headings point along the same axis in opposite directions), return a 4-point
|
|
141
|
+
* S/Z `[bufA, c1, c2, bufB]` whose crossover sits at the midpoint between the
|
|
142
|
+
* joints. One deterministic rule covers the whole drag:
|
|
143
|
+
* - OVERLAP (the joints have crossed along the exit axis, e.g. tight gap or
|
|
144
|
+
* the boxes overlap vertically): the crossover is the SHORT cross-axis step,
|
|
145
|
+
* placed at the cross-axis midpoint (mx / my) — a smooth mid-bend.
|
|
146
|
+
* - SEPARATED (the joints haven't crossed): the crossover is the long
|
|
147
|
+
* cross-run, placed at the exit-axis midpoint between the two buffers.
|
|
148
|
+
* Both forms degenerate to the same straight segment at the boundary (gap =
|
|
149
|
+
* 2×buffer), so the route is continuous as the shape is dragged — no jump to a
|
|
150
|
+
* grid line the way A* does. Returns null for non-collinear pairs (L-shapes,
|
|
151
|
+
* same-side), where A* is the right tool. `pathCrossesObstacle` rejects the
|
|
152
|
+
* result if the centred path would clip a bound shape (then A* takes over).
|
|
153
|
+
*/
|
|
154
|
+
const midS_ = (from, to, a, b, bufA, bufB) => {
|
|
155
|
+
// Vertical pair (e.g. bottom→top): stubs run along Y.
|
|
156
|
+
if (a.heading.y !== 0 && b.heading.y === -a.heading.y) {
|
|
157
|
+
const overlap = Math.sign(bufA.y - bufB.y) === Math.sign(a.heading.y);
|
|
158
|
+
if (overlap) {
|
|
159
|
+
// Joints crossed: short vertical step at the horizontal midpoint.
|
|
160
|
+
const mx = (from.x + to.x) / 2;
|
|
161
|
+
return [bufA, { x: mx, y: bufA.y }, { x: mx, y: bufB.y }, bufB];
|
|
162
|
+
}
|
|
163
|
+
// Separated: horizontal cross-run at the vertical midpoint between buffers.
|
|
164
|
+
const my = (bufA.y + bufB.y) / 2;
|
|
165
|
+
return [bufA, { x: bufA.x, y: my }, { x: bufB.x, y: my }, bufB];
|
|
166
|
+
}
|
|
167
|
+
// Horizontal pair (e.g. right→left): stubs run along X.
|
|
168
|
+
if (a.heading.x !== 0 && b.heading.x === -a.heading.x) {
|
|
169
|
+
const overlap = Math.sign(bufA.x - bufB.x) === Math.sign(a.heading.x);
|
|
170
|
+
if (overlap) {
|
|
171
|
+
// Joints crossed: short horizontal step at the vertical midpoint.
|
|
172
|
+
const my = (from.y + to.y) / 2;
|
|
173
|
+
return [bufA, { x: bufA.x, y: my }, { x: bufB.x, y: my }, bufB];
|
|
174
|
+
}
|
|
175
|
+
// Separated: vertical cross-run at the horizontal midpoint between buffers.
|
|
176
|
+
const mx = (bufA.x + bufB.x) / 2;
|
|
177
|
+
return [bufA, { x: mx, y: bufA.y }, { x: mx, y: bufB.y }, bufB];
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Pick one of two outside-the-union crossover coordinates (`lo` = top/left,
|
|
183
|
+
* `hi` = bottom/right) with HYSTERESIS so a small drag doesn't flip the side.
|
|
184
|
+
*
|
|
185
|
+
* `mid` is the endpoints' midpoint along the cross axis; `centre` the union
|
|
186
|
+
* centre. The natural (shortest) side is whichever the midpoint leans toward.
|
|
187
|
+
* But near the centre — exactly where a diagonal-overlap configuration rests —
|
|
188
|
+
* a bare threshold flips top↔bottom every frame under a drag (jitter). So
|
|
189
|
+
* within `ELBOW_WRAP_HYSTERESIS` of the centre we KEEP the previous side
|
|
190
|
+
* (`prevLo`: was the last route on the `lo` side?); the side only switches once
|
|
191
|
+
* the midpoint moves past the centre by the band. This is the only history the
|
|
192
|
+
* elbow router consults — the A* core stays pure.
|
|
193
|
+
*/
|
|
194
|
+
const pickWrapSide = (mid, centre, lo, hi, prevLo) => {
|
|
195
|
+
const naturalLo = mid <= centre;
|
|
196
|
+
if (prevLo !== null && Math.abs(mid - centre) < ELBOW_WRAP_HYSTERESIS) {
|
|
197
|
+
return prevLo ? lo : hi;
|
|
198
|
+
}
|
|
199
|
+
return naturalLo ? lo : hi;
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* Deterministic C-wrap for a collinear-opposite pair whose centred crossover
|
|
203
|
+
* (the {@link midS_} thread) would clip a shape — i.e. the two boxes overlap on
|
|
204
|
+
* the cross axis, so there's no gap to thread. Route the crossover run just
|
|
205
|
+
* OUTSIDE the union of the obstacles, on one side (top/bottom for a horizontal
|
|
206
|
+
* pair, left/right for a vertical pair). The side is chosen by
|
|
207
|
+
* {@link pickWrapSide} with hysteresis off the previous route (`prev`) so a
|
|
208
|
+
* small drag near the union centre no longer flips the route ("jitter").
|
|
209
|
+
*/
|
|
210
|
+
const wrapRoute = (from, to, a, b, bufA, bufB, obstacles, prev) => {
|
|
211
|
+
if (obstacles.length === 0)
|
|
212
|
+
return null;
|
|
213
|
+
let minX = Infinity;
|
|
214
|
+
let minY = Infinity;
|
|
215
|
+
let maxX = -Infinity;
|
|
216
|
+
let maxY = -Infinity;
|
|
217
|
+
for (const o of obstacles) {
|
|
218
|
+
minX = Math.min(minX, o.x);
|
|
219
|
+
minY = Math.min(minY, o.y);
|
|
220
|
+
maxX = Math.max(maxX, o.x + o.width);
|
|
221
|
+
maxY = Math.max(maxY, o.y + o.height);
|
|
222
|
+
}
|
|
223
|
+
const m = ELBOW_OBSTACLE_MARGIN;
|
|
224
|
+
minX -= m;
|
|
225
|
+
minY -= m;
|
|
226
|
+
maxX += m;
|
|
227
|
+
maxY += m;
|
|
228
|
+
// Horizontal pair (ends exit ±x): the crossover is a horizontal run; place it
|
|
229
|
+
// just above or below the union.
|
|
230
|
+
if (a.heading.y === 0 && b.heading.y === 0 && a.heading.x !== 0 && b.heading.x === -a.heading.x) {
|
|
231
|
+
const my = (from.y + to.y) / 2;
|
|
232
|
+
const yPick = pickWrapSide(my, (minY + maxY) / 2, minY, maxY, prevWrapLo(prev, "y"));
|
|
233
|
+
return [bufA, { x: bufA.x, y: yPick }, { x: bufB.x, y: yPick }, bufB];
|
|
234
|
+
}
|
|
235
|
+
// Vertical pair (ends exit ±y): the crossover is a vertical run; place it just
|
|
236
|
+
// left or right of the union.
|
|
237
|
+
if (a.heading.x === 0 && b.heading.x === 0 && a.heading.y !== 0 && b.heading.y === -a.heading.y) {
|
|
238
|
+
const mx = (from.x + to.x) / 2;
|
|
239
|
+
const xPick = pickWrapSide(mx, (minX + maxX) / 2, minX, maxX, prevWrapLo(prev, "x"));
|
|
240
|
+
return [bufA, { x: xPick, y: bufA.y }, { x: xPick, y: bufB.y }, bufB];
|
|
241
|
+
}
|
|
242
|
+
return null;
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* Which side did the previous wrap take? The crossover run sits OUTSIDE the
|
|
246
|
+
* union, beyond the two endpoints (`prev[0]` / `prev[last]` = the stub joints).
|
|
247
|
+
* So a `lo`-side wrap dips the path's minimum BELOW the endpoints' band, and a
|
|
248
|
+
* `hi`-side wrap pushes the maximum ABOVE it. Compare those overshoots. Returns
|
|
249
|
+
* `null` when there's no usable previous path (first route, degenerate, or no
|
|
250
|
+
* overshoot either way) — the caller then uses the natural side.
|
|
251
|
+
*/
|
|
252
|
+
const prevWrapLo = (prev, axis) => {
|
|
253
|
+
if (!prev || prev.length < 3)
|
|
254
|
+
return null;
|
|
255
|
+
const at = (p) => (axis === "y" ? p.y : p.x);
|
|
256
|
+
const first = at(req(prev[0]));
|
|
257
|
+
const last = at(req(prev[prev.length - 1]));
|
|
258
|
+
const endLo = Math.min(first, last);
|
|
259
|
+
const endHi = Math.max(first, last);
|
|
260
|
+
let lo = Infinity;
|
|
261
|
+
let hi = -Infinity;
|
|
262
|
+
for (const p of prev) {
|
|
263
|
+
const v = at(p);
|
|
264
|
+
if (v < lo)
|
|
265
|
+
lo = v;
|
|
266
|
+
if (v > hi)
|
|
267
|
+
hi = v;
|
|
268
|
+
}
|
|
269
|
+
const overLo = endLo - lo; // how far the path dips below the endpoints
|
|
270
|
+
const overHi = hi - endHi; // how far it rises above them
|
|
271
|
+
if (overLo <= 0 && overHi <= 0)
|
|
272
|
+
return null; // no crossover overshoot → no hint
|
|
273
|
+
return overLo >= overHi;
|
|
274
|
+
};
|
|
275
|
+
/** True if any axis-aligned segment of `path` passes through an obstacle's
|
|
276
|
+
* interior (sampled; a margin keeps the line off the very edge). */
|
|
277
|
+
const pathCrossesObstacle = (path, obstacles) => {
|
|
278
|
+
const m = ELBOW_OBSTACLE_CLEARANCE; // inset so edge-touching isn't a "cross"
|
|
279
|
+
for (let i = 1; i < path.length; i++) {
|
|
280
|
+
const p = req(path[i - 1]);
|
|
281
|
+
const q = req(path[i]);
|
|
282
|
+
for (let t = 0; t <= 1; t += ELBOW_CROSS_SAMPLE_STEP) {
|
|
283
|
+
const x = p.x + (q.x - p.x) * t;
|
|
284
|
+
const y = p.y + (q.y - p.y) * t;
|
|
285
|
+
for (const o of obstacles) {
|
|
286
|
+
if (x > o.x + m && x < o.x + o.width - m && y > o.y + m && y < o.y + o.height - m)
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return false;
|
|
292
|
+
};
|
|
293
|
+
/** EndInfo for a raw point that may sit on a shape (preview). */
|
|
294
|
+
const pointEndInfo = (scene, elId, self, other) => {
|
|
295
|
+
if (!elId)
|
|
296
|
+
return { heading: headingForPoint(other, self), obstacle: null };
|
|
297
|
+
const shape = getElement(scene, elId);
|
|
298
|
+
if (!shape)
|
|
299
|
+
return { heading: headingForPoint(other, self), obstacle: null };
|
|
300
|
+
return {
|
|
301
|
+
heading: headingForPointFromElement(shape, self),
|
|
302
|
+
obstacle: getElementWorldBounds(shape),
|
|
303
|
+
};
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Pin user-dragged interior segments to their stored perpendicular
|
|
307
|
+
* coordinate. Moving a segment along its perpendicular only stretches the
|
|
308
|
+
* (perpendicular) neighbour segments — orientation is preserved — so this is
|
|
309
|
+
* a direct coordinate override, no propagation needed. Terminal segments
|
|
310
|
+
* (touching `from`/`to`) are skipped: their endpoint can't move.
|
|
311
|
+
*/
|
|
312
|
+
const applyFixedSegments = (full, fixed) => {
|
|
313
|
+
if (!fixed || fixed.length === 0)
|
|
314
|
+
return full;
|
|
315
|
+
let out = full.map((p) => ({ ...p }));
|
|
316
|
+
for (const pin of fixed) {
|
|
317
|
+
const lastSeg = out.length - 2; // index of the last segment's start point
|
|
318
|
+
// Re-identify the pinned segment in the fresh route: the interior segment
|
|
319
|
+
// with the same axis whose centre is closest to the stored `at`. Robust to
|
|
320
|
+
// index / topology changes that a raw index can't survive.
|
|
321
|
+
let bestK = -1;
|
|
322
|
+
let bestD = Infinity;
|
|
323
|
+
for (let k = 1; k < lastSeg; k++) {
|
|
324
|
+
const a = req(out[k]);
|
|
325
|
+
const b = req(out[k + 1]);
|
|
326
|
+
const isH = Math.abs(a.y - b.y) < 1e-6;
|
|
327
|
+
const isV = Math.abs(a.x - b.x) < 1e-6;
|
|
328
|
+
if ((pin.axis === "h") !== isH || (pin.axis === "v") !== isV)
|
|
329
|
+
continue;
|
|
330
|
+
const centre = pin.axis === "h" ? (a.x + b.x) / 2 : (a.y + b.y) / 2;
|
|
331
|
+
const d = Math.abs(centre - pin.at);
|
|
332
|
+
if (d < bestD) {
|
|
333
|
+
bestD = d;
|
|
334
|
+
bestK = k;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (bestK >= 0) {
|
|
338
|
+
// Slide an existing interior segment to its pinned coordinate.
|
|
339
|
+
const a = req(out[bestK]);
|
|
340
|
+
const b = req(out[bestK + 1]);
|
|
341
|
+
if (pin.axis === "h") {
|
|
342
|
+
a.y = pin.pos;
|
|
343
|
+
b.y = pin.pos;
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
a.x = pin.pos;
|
|
347
|
+
b.x = pin.pos;
|
|
348
|
+
}
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
// No strict-interior match — the user dragged a segment adjacent to a
|
|
352
|
+
// buffer joint (or the single middle segment of an aligned elbow).
|
|
353
|
+
// Reconstruct the middle as a "staple" between the FIXED buffer joints
|
|
354
|
+
// (out[0] = bufA, out[last] = bufB) so a segment of the pinned axis sits at
|
|
355
|
+
// `pos` while the terminal buffers stay put (standard terminal-drag).
|
|
356
|
+
const j0 = req(out[0]);
|
|
357
|
+
const j1 = req(out[out.length - 1]);
|
|
358
|
+
out =
|
|
359
|
+
pin.axis === "h"
|
|
360
|
+
? [j0, { x: j0.x, y: pin.pos }, { x: j1.x, y: pin.pos }, j1]
|
|
361
|
+
: [j0, { x: pin.pos, y: j0.y }, { x: pin.pos, y: j1.y }, j1];
|
|
362
|
+
}
|
|
363
|
+
return collapseColinear(out);
|
|
364
|
+
};
|
|
365
|
+
const namedHeading = (name) => {
|
|
366
|
+
switch (name) {
|
|
367
|
+
case "top":
|
|
368
|
+
return HEADING_UP;
|
|
369
|
+
case "bottom":
|
|
370
|
+
return HEADING_DOWN;
|
|
371
|
+
case "left":
|
|
372
|
+
return HEADING_LEFT;
|
|
373
|
+
case "right":
|
|
374
|
+
return HEADING_RIGHT;
|
|
375
|
+
default:
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
/** Heading (exit side) + obstacle bbox for one endpoint. */
|
|
380
|
+
const endInfo = (scene, ep, self, other) => {
|
|
381
|
+
if (ep.kind === "point")
|
|
382
|
+
return { heading: headingForPoint(other, self), obstacle: null };
|
|
383
|
+
const shape = getElement(scene, ep.elementId);
|
|
384
|
+
if (!shape)
|
|
385
|
+
return { heading: headingForPoint(other, self), obstacle: null };
|
|
386
|
+
const obstacle = getElementWorldBounds(shape);
|
|
387
|
+
if (ep.kind === "anchor" && ep.anchor.kind === "named") {
|
|
388
|
+
const h = namedHeading(ep.anchor.name);
|
|
389
|
+
if (h)
|
|
390
|
+
return { heading: h, obstacle };
|
|
391
|
+
}
|
|
392
|
+
// floating / outline / ratio anchors: `self` is already the resolved point
|
|
393
|
+
// ON the outline, so exit perpendicular to the edge it sits on. Nearest-edge
|
|
394
|
+
// (not the centre cone test) keeps the exit outward even near corners.
|
|
395
|
+
return { heading: headingForEdgePoint(shape, self), obstacle };
|
|
396
|
+
};
|
|
397
|
+
/** Single-bend L corner between two dongles (router-failure fallback). */
|
|
398
|
+
const fallbackCorner = (a, b, headingA) => headingIsHorizontal(headingA) ? { x: b.x, y: a.y } : { x: a.x, y: b.y };
|
|
399
|
+
/** Drop colinear midpoints from an axis-aligned polyline (tolerant). */
|
|
400
|
+
const collapseColinear = (points) => {
|
|
401
|
+
if (points.length <= 2)
|
|
402
|
+
return [...points];
|
|
403
|
+
const out = [req(points[0])];
|
|
404
|
+
for (let i = 1; i < points.length - 1; i++) {
|
|
405
|
+
const prev = req(out[out.length - 1]);
|
|
406
|
+
const cur = req(points[i]);
|
|
407
|
+
const next = req(points[i + 1]);
|
|
408
|
+
const eps = 1e-6;
|
|
409
|
+
const horizontal = Math.abs(prev.y - cur.y) < eps && Math.abs(cur.y - next.y) < eps;
|
|
410
|
+
const vertical = Math.abs(prev.x - cur.x) < eps && Math.abs(cur.x - next.x) < eps;
|
|
411
|
+
const coincident = Math.abs(prev.x - cur.x) < eps && Math.abs(prev.y - cur.y) < eps;
|
|
412
|
+
if (horizontal || vertical || coincident)
|
|
413
|
+
continue;
|
|
414
|
+
out.push(cur);
|
|
415
|
+
}
|
|
416
|
+
out.push(req(points[points.length - 1]));
|
|
417
|
+
return out;
|
|
418
|
+
};
|
|
419
|
+
//# sourceMappingURL=elbow-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elbow-link.js","sourceRoot":"","sources":["../src/elbow-link.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Bounds, Vec2 } from "@oh-just-another/types";
|
|
2
|
+
export interface ElbowRouteOptions {
|
|
3
|
+
/** Pad obstacles by this many world units. Defaults to package constant. */
|
|
4
|
+
readonly margin?: number;
|
|
5
|
+
/**
|
|
6
|
+
* Outward exit heading at `from` (the buffer direction). When set, the
|
|
7
|
+
* router's FIRST move may not go in the opposite direction — so the route
|
|
8
|
+
* never immediately reverses (retraces) the terminal buffer stub.
|
|
9
|
+
*/
|
|
10
|
+
readonly startHeading?: Vec2;
|
|
11
|
+
/**
|
|
12
|
+
* Outward heading at `to` (the buffer direction). When set, the route may
|
|
13
|
+
* not ARRIVE at the goal travelling in this direction — which would force
|
|
14
|
+
* `bufB → to` to reverse it. Keeps the connector from doubling back at the
|
|
15
|
+
* arrival end.
|
|
16
|
+
*/
|
|
17
|
+
readonly endHeading?: Vec2;
|
|
18
|
+
}
|
|
19
|
+
export declare const elbowRoute: (from: Vec2, to: Vec2, obstacles: readonly Bounds[], options?: ElbowRouteOptions) => readonly Vec2[] | null;
|
|
20
|
+
//# sourceMappingURL=elbow-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elbow-router.d.ts","sourceRoot":"","sources":["../src/elbow-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AA0C3D,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC;CAC5B;AAED,eAAO,MAAM,UAAU,GACrB,MAAM,IAAI,EACV,IAAI,IAAI,EACR,WAAW,SAAS,MAAM,EAAE,EAC5B,UAAS,iBAAsB,KAC9B,SAAS,IAAI,EAAE,GAAG,IAgHpB,CAAC"}
|