vehicle-path2 2.4.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +234 -113
- package/dist/core/algorithms/acceleration.d.ts +75 -0
- package/dist/core/engine.d.ts +7 -7
- package/dist/core/index.d.ts +2 -1
- package/dist/core/snapshot.d.ts +4 -26
- package/dist/core/types/vehicle.d.ts +12 -2
- package/dist/core.cjs +1 -1
- package/dist/core.js +144 -80
- package/dist/index-C4FckUel.cjs +1 -0
- package/dist/{index-wjEuFiRl.js → index-C7pH7jZo.js} +281 -277
- package/dist/vehicle-path.cjs +1 -1
- package/dist/vehicle-path.js +5 -5
- package/package.json +1 -1
- package/dist/index-BUYdltrL.cjs +0 -1
package/dist/core.js
CHANGED
|
@@ -1,107 +1,171 @@
|
|
|
1
|
-
import { g as
|
|
2
|
-
import { P as
|
|
3
|
-
function
|
|
1
|
+
import { g as u, m as x, a as p } from "./index-C7pH7jZo.js";
|
|
2
|
+
import { P as T, b, c as j, d as q, e as C, f as N, h as B, i as V, j as J, k as F, l as R, n as k, o as G, p as W, q as X, r as Y, s as H, t as K, u as Q, v as U, w as Z, x as _, y as $, z as ee, A as te, B as ne, C as ae, D as se, E as re } from "./index-C7pH7jZo.js";
|
|
3
|
+
function P(n, e) {
|
|
4
4
|
const a = {
|
|
5
|
-
lines:
|
|
6
|
-
curves: e.map((
|
|
7
|
-
id:
|
|
8
|
-
fromLineId:
|
|
9
|
-
toLineId:
|
|
10
|
-
fromOffset:
|
|
11
|
-
fromIsPercentage:
|
|
12
|
-
toOffset:
|
|
13
|
-
toIsPercentage:
|
|
14
|
-
})),
|
|
15
|
-
vehicles: t.map((s) => ({
|
|
16
|
-
id: s.id,
|
|
17
|
-
lineId: s.axles[0].lineId,
|
|
18
|
-
axles: s.axles.map((n) => ({ offset: n.offset })),
|
|
19
|
-
axleSpacings: s.axleSpacings,
|
|
20
|
-
isPercentage: s.isPercentage ?? !1
|
|
5
|
+
lines: n,
|
|
6
|
+
curves: e.map((t) => ({
|
|
7
|
+
id: t.id,
|
|
8
|
+
fromLineId: t.fromLineId,
|
|
9
|
+
toLineId: t.toLineId,
|
|
10
|
+
fromOffset: t.fromOffset,
|
|
11
|
+
fromIsPercentage: t.fromIsPercentage ?? !1,
|
|
12
|
+
toOffset: t.toOffset,
|
|
13
|
+
toIsPercentage: t.toIsPercentage ?? !1
|
|
21
14
|
}))
|
|
22
15
|
};
|
|
23
16
|
return JSON.stringify(a, null, 2);
|
|
24
17
|
}
|
|
25
|
-
function
|
|
18
|
+
function M(n) {
|
|
26
19
|
let e;
|
|
27
20
|
try {
|
|
28
|
-
e = JSON.parse(
|
|
21
|
+
e = JSON.parse(n);
|
|
29
22
|
} catch {
|
|
30
23
|
throw new Error("deserializeScene: invalid JSON");
|
|
31
24
|
}
|
|
32
25
|
if (!e || typeof e != "object" || Array.isArray(e))
|
|
33
26
|
throw new Error("deserializeScene: expected a JSON object");
|
|
34
|
-
const
|
|
35
|
-
if (!Array.isArray(
|
|
36
|
-
if (!Array.isArray(
|
|
37
|
-
if (!Array.isArray(t.vehicles)) throw new Error('deserializeScene: missing "vehicles"');
|
|
27
|
+
const a = e;
|
|
28
|
+
if (!Array.isArray(a.lines)) throw new Error('deserializeScene: missing "lines"');
|
|
29
|
+
if (!Array.isArray(a.curves)) throw new Error('deserializeScene: missing "curves"');
|
|
38
30
|
return {
|
|
39
|
-
lines:
|
|
40
|
-
curves:
|
|
41
|
-
vehicles: t.vehicles
|
|
31
|
+
lines: a.lines,
|
|
32
|
+
curves: a.curves
|
|
42
33
|
};
|
|
43
34
|
}
|
|
44
|
-
function
|
|
45
|
-
const
|
|
35
|
+
function v(n) {
|
|
36
|
+
const e = n.axleExecutions[n.axleExecutions.length - 1], a = u(
|
|
37
|
+
n.path,
|
|
38
|
+
e.segmentIndex,
|
|
39
|
+
e.segmentDistance
|
|
40
|
+
);
|
|
41
|
+
return Math.max(0, n.path.totalDistance - a);
|
|
42
|
+
}
|
|
43
|
+
function S(n) {
|
|
44
|
+
const e = n.axleExecutions[0], a = u(
|
|
45
|
+
n.path,
|
|
46
|
+
e.segmentIndex,
|
|
47
|
+
e.segmentDistance
|
|
48
|
+
);
|
|
49
|
+
let t = 0;
|
|
50
|
+
for (let s = 0; s < n.path.segments.length; s++) {
|
|
51
|
+
const i = n.path.segments[s];
|
|
52
|
+
if (s >= e.segmentIndex && i.type === "curve")
|
|
53
|
+
return Math.max(0, t - a);
|
|
54
|
+
t += i.length;
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
function L(n, e, a) {
|
|
59
|
+
let t = a.maxSpeed;
|
|
60
|
+
const s = Math.sqrt(2 * a.deceleration * Math.max(0, n));
|
|
61
|
+
if (t = Math.min(t, s), e !== null) {
|
|
62
|
+
const i = Math.sqrt(
|
|
63
|
+
a.minCurveSpeed ** 2 + 2 * a.deceleration * e
|
|
64
|
+
);
|
|
65
|
+
t = Math.min(t, i);
|
|
66
|
+
}
|
|
67
|
+
return Math.max(0, t);
|
|
68
|
+
}
|
|
69
|
+
function O(n, e, a, t, s) {
|
|
70
|
+
return n < e ? Math.min(e, n + a * s) : n > e ? Math.max(e, n - t * s) : n;
|
|
71
|
+
}
|
|
72
|
+
function y(n, e, a, t, s, i) {
|
|
73
|
+
const o = v(e), c = S(e), l = L(o, c, t), f = O(
|
|
74
|
+
a.currentSpeed,
|
|
75
|
+
l,
|
|
76
|
+
t.acceleration,
|
|
77
|
+
t.deceleration,
|
|
78
|
+
s
|
|
79
|
+
), d = f * s, h = n.axles.map((r) => ({
|
|
80
|
+
lineId: r.lineId,
|
|
81
|
+
position: r.position,
|
|
82
|
+
absoluteOffset: r.offset
|
|
83
|
+
})), g = e.axleExecutions.map((r) => ({
|
|
84
|
+
currentSegmentIndex: r.segmentIndex,
|
|
85
|
+
segmentDistance: r.segmentDistance
|
|
86
|
+
})), m = x(h, g, e.path, d, i, e.curveDataMap);
|
|
87
|
+
return {
|
|
88
|
+
state: {
|
|
89
|
+
axles: m.axles.map((r) => ({ lineId: r.lineId, offset: r.absoluteOffset, position: r.position })),
|
|
90
|
+
axleSpacings: n.axleSpacings
|
|
91
|
+
},
|
|
92
|
+
execution: {
|
|
93
|
+
...e,
|
|
94
|
+
axleExecutions: m.axleExecutions.map((r) => ({
|
|
95
|
+
segmentIndex: r.currentSegmentIndex,
|
|
96
|
+
segmentDistance: r.segmentDistance
|
|
97
|
+
}))
|
|
98
|
+
},
|
|
99
|
+
accelState: { currentSpeed: f },
|
|
100
|
+
arrived: m.arrived
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function A(n, e) {
|
|
104
|
+
const a = e.end.x - e.start.x, t = e.end.y - e.start.y, s = a * a + t * t;
|
|
46
105
|
if (s === 0)
|
|
47
106
|
return { offset: 0, distance: Math.sqrt(
|
|
48
|
-
(
|
|
107
|
+
(n.x - e.start.x) ** 2 + (n.y - e.start.y) ** 2
|
|
49
108
|
) };
|
|
50
|
-
const
|
|
109
|
+
const i = Math.max(
|
|
51
110
|
0,
|
|
52
111
|
Math.min(
|
|
53
112
|
1,
|
|
54
|
-
((
|
|
113
|
+
((n.x - e.start.x) * a + (n.y - e.start.y) * t) / s
|
|
55
114
|
)
|
|
56
|
-
),
|
|
57
|
-
return { offset:
|
|
115
|
+
), o = e.start.x + i * a, c = e.start.y + i * t, l = Math.sqrt((n.x - o) ** 2 + (n.y - c) ** 2);
|
|
116
|
+
return { offset: i * Math.sqrt(s), distance: l };
|
|
58
117
|
}
|
|
59
|
-
function
|
|
60
|
-
const
|
|
61
|
-
return [0, Math.max(0,
|
|
118
|
+
function E(n, e) {
|
|
119
|
+
const a = p(n), t = e.reduce((i, o) => i + o, 0);
|
|
120
|
+
return [0, Math.max(0, a - t)];
|
|
62
121
|
}
|
|
63
|
-
function
|
|
64
|
-
let
|
|
65
|
-
for (const
|
|
66
|
-
|
|
67
|
-
return
|
|
122
|
+
function z(n, e) {
|
|
123
|
+
let a = 0;
|
|
124
|
+
for (const t of e)
|
|
125
|
+
t.fromLineId === n && !t.fromIsPercentage && t.fromOffset !== void 0 && (a = Math.max(a, t.fromOffset)), t.toLineId === n && !t.toIsPercentage && t.toOffset !== void 0 && (a = Math.max(a, t.toOffset));
|
|
126
|
+
return a;
|
|
68
127
|
}
|
|
69
128
|
export {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
129
|
+
T as PathEngine,
|
|
130
|
+
O as approachSpeed,
|
|
131
|
+
b as arcLengthToSegmentPosition,
|
|
132
|
+
j as buildArcLengthTable,
|
|
133
|
+
q as buildGraph,
|
|
134
|
+
C as calculateBezierArcLength,
|
|
135
|
+
N as calculateFrontAxlePosition,
|
|
136
|
+
B as calculateInitialAxlePositions,
|
|
137
|
+
V as calculatePositionOnCurve,
|
|
138
|
+
J as calculatePositionOnLine,
|
|
139
|
+
F as calculateTangentLength,
|
|
140
|
+
S as computeDistToNextCurve,
|
|
141
|
+
z as computeMinLineLength,
|
|
142
|
+
v as computeRemainingToArrival,
|
|
143
|
+
L as computeTargetSpeed,
|
|
144
|
+
R as createBezierCurve,
|
|
145
|
+
k as createInitialMovementState,
|
|
146
|
+
M as deserializeScene,
|
|
147
|
+
G as distance,
|
|
148
|
+
W as distanceToT,
|
|
149
|
+
X as findPath,
|
|
150
|
+
Y as getArcLength,
|
|
151
|
+
u as getCumulativeArcLength,
|
|
152
|
+
p as getLineLength,
|
|
153
|
+
H as getPointOnBezier,
|
|
154
|
+
K as getPointOnLine,
|
|
155
|
+
Q as getPointOnLineByOffset,
|
|
156
|
+
U as getPositionFromOffset,
|
|
157
|
+
E as getValidRearOffsetRange,
|
|
158
|
+
Z as handleArrival,
|
|
159
|
+
_ as initializeAllVehicles,
|
|
160
|
+
$ as initializeMovingVehicle,
|
|
161
|
+
ee as isPointNearPoint,
|
|
162
|
+
x as moveVehicle,
|
|
163
|
+
y as moveVehicleWithAcceleration,
|
|
164
|
+
te as normalize,
|
|
165
|
+
ne as prepareCommandPath,
|
|
166
|
+
A as projectPointOnLine,
|
|
167
|
+
ae as resolveFromLineOffset,
|
|
168
|
+
se as resolveToLineOffset,
|
|
169
|
+
P as serializeScene,
|
|
170
|
+
re as updateAxlePosition
|
|
107
171
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function L(t,e){const n=e.x-t.x,s=e.y-t.y;return Math.sqrt(n*n+s*s)}function D(t,e){const n=e.x-t.x,s=e.y-t.y,i=Math.sqrt(n*n+s*s);return i===0?{x:0,y:0}:{x:n/i,y:s/i}}function q(t,e){return e*(t==="proportional-40"?.4:.5522)}function V(t,e,n,s=!1,i){const{maxWheelbase:o,tangentMode:c}=n;let r;i?.fromOffset!==void 0?r=b(t,i.fromOffset,i.fromIsPercentage??!1):r=t.end;let u;i?.toOffset!==void 0?u=b(e,i.toOffset,i.toIsPercentage??!1):u=e.start;const l=D(t.start,t.end),a=s?{x:r.x-l.x*o,y:r.y-l.y*o}:r,g=D(t.start,t.end),d=D(e.start,e.end),h=L(a,u),p=q(c,h),f=s?{x:a.x-g.x*p,y:a.y-g.y*p}:{x:a.x+g.x*p,y:a.y+g.y*p},v={x:u.x-d.x*p,y:u.y-d.y*p};return{p0:a,p1:f,p2:v,p3:u}}function F(t,e){return{x:t.start.x+(t.end.x-t.start.x)*e,y:t.start.y+(t.end.y-t.start.y)*e}}function b(t,e,n){const s=L(t.start,t.end);let i;return n?i=e:i=s>0?e/s:0,i=Math.max(0,Math.min(1,i)),F(t,i)}function w(t,e){const{p0:n,p1:s,p2:i,p3:o}=t,c=1-e,r=c*c,u=r*c,l=e*e,a=l*e;return{x:u*n.x+3*r*e*s.x+3*c*l*i.x+a*o.x,y:u*n.y+3*r*e*s.y+3*c*l*i.y+a*o.y}}function ee(t,e,n=10){return L(t,e)<=n}function N(t,e=100){const n=[{t:0,distance:0}];let s=t.p0,i=0;for(let o=1;o<=e;o++){const c=o/e,r=w(t,c);i+=L(s,r),n.push({t:c,distance:i}),s=r}return n}function $(t,e){if(e<=0)return 0;const n=t[t.length-1].distance;if(e>=n)return 1;let s=0,i=t.length-1;for(;s<i-1;){const a=Math.floor((s+i)/2);t[a].distance<e?s=a:i=a}const o=t[s].distance,c=t[i].distance,r=t[s].t,u=t[i].t;if(c===o)return r;const l=(e-o)/(c-o);return r+l*(u-r)}function te(t){return t[t.length-1].distance}function j(t,e=100){let n=0,s=t.p0;for(let i=1;i<=e;i++){const o=i/e,c=w(t,o);n+=L(s,c),s=c}return n}function z(t,e,n,s,i){const o=L(t.start,t.end);return e===void 0?s*o:n?Math.max(0,Math.min(e,1))*o:Math.max(0,Math.min(e,o))}function W(t,e,n,s,i){const o=L(t.start,t.end);return e===void 0?s*o:n?Math.max(0,Math.min(e,1))*o:Math.max(0,Math.min(e,o))}function x(t,e,n){const s=new Map,i=new Map,o=new Map;for(const c of t)i.set(c.id,c),o.set(c.id,L(c.start,c.end)),s.set(c.id,[]);for(let c=0;c<e.length;c++){const r=e[c],u=i.get(r.fromLineId),l=i.get(r.toLineId);if(!u||!l)continue;const a=z(u,r.fromOffset,r.fromIsPercentage,1,n.maxWheelbase),g=W(l,r.toOffset,r.toIsPercentage,0,n.maxWheelbase),d=V(u,l,n,!1,{fromOffset:a,fromIsPercentage:!1,toOffset:g,toIsPercentage:!1}),h=j(d),p={curveIndex:c,fromLineId:r.fromLineId,toLineId:r.toLineId,fromOffset:a,toOffset:g,curveLength:h};s.get(r.fromLineId).push(p)}return{adjacency:s,lines:i,lineLengths:o}}function E(t,e){return t.curveCount!==e.curveCount?t.curveCount-e.curveCount:t.totalDistance-e.totalDistance}function K(t,e,n,s,i=!1){const{adjacency:o,lines:c,lineLengths:r}=t;if(!c.get(n))return null;const l=r.get(n),a=i?s/100*l:s,g=[],d=new Map,h=(f,v)=>`${f}:${Math.round(v)}`;if(e.lineId===n&&a>=e.offset){const f=a-e.offset;return{segments:[{type:"line",lineId:e.lineId,startOffset:e.offset,endOffset:a,length:f}],totalDistance:f,curveCount:0}}const p=o.get(e.lineId)||[];for(const f of p){if(f.fromOffset<e.offset)continue;const v=f.fromOffset-e.offset,I=v+f.curveLength,O={type:"line",lineId:e.lineId,startOffset:e.offset,endOffset:f.fromOffset,length:v},m={type:"curve",curveIndex:f.curveIndex,startOffset:0,endOffset:f.curveLength,length:f.curveLength};g.push({lineId:f.toLineId,entryOffset:f.toOffset,totalDistance:I,curveCount:1,path:[O,m]})}for(g.sort(E);g.length>0;){const f=g.shift(),v=h(f.lineId,f.entryOffset),I=d.get(v);if(I!==void 0&&(I.curveCount<f.curveCount||I.curveCount===f.curveCount&&I.distance<=f.totalDistance))continue;if(d.set(v,{curveCount:f.curveCount,distance:f.totalDistance}),f.lineId===n){const m=Math.abs(a-f.entryOffset);if(a>=f.entryOffset){const P={type:"line",lineId:n,startOffset:f.entryOffset,endOffset:a,length:m};return{segments:[...f.path,P],totalDistance:f.totalDistance+m,curveCount:f.curveCount}}}const O=o.get(f.lineId)||[];for(const m of O){if(m.fromOffset<f.entryOffset)continue;const P=m.fromOffset-f.entryOffset,B=f.totalDistance+P+m.curveLength,T=f.curveCount+1,X=h(m.toLineId,m.toOffset),C=d.get(X);if(C!==void 0&&(C.curveCount<T||C.curveCount===T&&C.distance<=B))continue;const Y={type:"line",lineId:f.lineId,startOffset:f.entryOffset,endOffset:m.fromOffset,length:P},Z={type:"curve",curveIndex:m.curveIndex,startOffset:0,endOffset:m.curveLength,length:m.curveLength};g.push({lineId:m.toLineId,entryOffset:m.toOffset,totalDistance:B,curveCount:T,path:[...f.path,Y,Z]})}g.sort(E)}return null}function A(t,e){const n=Math.sqrt(Math.pow(t.end.x-t.start.x,2)+Math.pow(t.end.y-t.start.y,2)),s=n>0?e/n:0;return{x:t.start.x+(t.end.x-t.start.x)*Math.min(1,Math.max(0,s)),y:t.start.y+(t.end.y-t.start.y)*Math.min(1,Math.max(0,s))}}function M(t){return Math.sqrt(Math.pow(t.end.x-t.start.x,2)+Math.pow(t.end.y-t.start.y,2))}function _(t,e,n){let s=0;for(let i=0;i<e;i++)s+=t.segments[i].length;return s+=n,s}function k(t,e){let n=0;for(let s=0;s<t.segments.length;s++){const i=t.segments[s],o=n+i.length;if(e<o)return{segmentIndex:s,segmentDistance:e-n};if(e===o)return s+1<t.segments.length?{segmentIndex:s+1,segmentDistance:0}:{segmentIndex:s,segmentDistance:i.length};n+=i.length}return null}function ne(t,e,n,s){const o=_(t,e,n)+s;return k(t,o)}function G(t,e,n,s){const i=M(s),o=n.length+1,c=new Array(o);c[o-1]={lineId:t,absoluteOffset:e,position:A(s,e)};let r=e;for(let u=o-2;u>=0;u--)r=Math.min(r+n[u],i),c[u]={lineId:t,absoluteOffset:r,position:A(s,r)};return c}function Q(t,e){return{...t,state:"idle"}}function R(t){return{vehicle:t,execution:null}}function se(t,e){const n=[],s=new Map;for(const i of t){if(!e.get(i.lineId))continue;const c=Q(i);n.push(c);const r=R(c);s.set(i.id,r)}return{movingVehicles:n,stateMap:s}}function y(t,e){return{position:A(t,e),lineId:t.id,absoluteOffset:e}}function S(t,e){const n=$(t.arcLengthTable,e);return{position:w(t.bezier,n)}}function H(t,e,n,s,i,o,c){const r=n.segments[e.currentSegmentIndex],u=e.segmentDistance+s;if(u>=r.length){const a=u-r.length,g=e.currentSegmentIndex+1;if(g>=n.segments.length){if(c!==void 0&&r.type==="line"){const f=i.get(r.lineId),v=r.startOffset+u;if(v<=c){const O=y(f,v);return{axleState:{...t,...O},execution:{...e,segmentDistance:u},completed:!1}}const I=y(f,c);return{axleState:{...t,...I},execution:{...e,segmentDistance:c-r.startOffset},completed:!0}}const p=r.type==="line"?y(i.get(r.lineId),r.endOffset):S(o.get(r.curveIndex),r.length);return{axleState:{...t,...p},execution:{...e,segmentDistance:r.length},completed:!0}}const d=n.segments[g],h=d.type==="line"?y(i.get(d.lineId),d.startOffset+a):S(o.get(d.curveIndex),a);return{axleState:{...t,...h},execution:{currentSegmentIndex:g,segmentDistance:a},completed:!1}}const l=r.type==="line"?y(i.get(r.lineId),r.startOffset+u):S(o.get(r.curveIndex),u);return{axleState:{...t,...l},execution:{...e,segmentDistance:u},completed:!1}}function ie(t,e,n,s){const i=new Map;for(const o of t.segments)if(o.type==="curve"&&o.curveIndex!==void 0){const c=e[o.curveIndex];if(c){const r=n.get(c.fromLineId),u=n.get(c.toLineId);if(r&&u){const l=z(r,c.fromOffset,c.fromIsPercentage,1,s.maxWheelbase),a=W(u,c.toOffset,c.toIsPercentage,0,s.maxWheelbase),g=V(r,u,s,!1,{fromOffset:l,fromIsPercentage:!1,toOffset:a,toIsPercentage:!1}),d=N(g);i.set(o.curveIndex,{bezier:g,arcLengthTable:d})}}}return i}function J(t,e,n){const{graph:s,linesMap:i,curves:o,config:c}=n,r=i.get(e.targetLineId);if(!r)return null;const u=t.axleSpacings.reduce((f,v)=>f+v,0),a=M(r)-u;if(a<=0)return null;const g=e.isPercentage?e.targetOffset*a:Math.min(e.targetOffset,a),d=t.axles[t.axles.length-1],h=K(s,{lineId:d.lineId,offset:d.absoluteOffset},e.targetLineId,g,!1);if(!h)return null;const p=ie(h,o,i,c);return{path:h,curveDataMap:p}}function re(t,e){const n=t.execution,i=e.vehicleQueues.get(t.vehicle.id)?.[n.currentCommandIndex];return i&&e.onCommandComplete&&e.onCommandComplete({vehicleId:t.vehicle.id,command:i,finalPosition:{lineId:t.vehicle.axles[t.vehicle.axles.length-1].lineId,absoluteOffset:t.vehicle.axles[t.vehicle.axles.length-1].absoluteOffset,position:t.vehicle.axles[t.vehicle.axles.length-1].position},payload:i.payload}),{handled:!0,vehicle:{...t.vehicle,state:"waiting"},newExecution:n,isWaiting:!0}}function U(t,e,n,s,i,o){let c;const r=e[0];if(r.currentSegmentIndex<n.segments.length){const l=n.segments[r.currentSegmentIndex];if(l.type==="line"){const a=i.get(l.lineId);a&&(c=M(a))}}const u=t.map((l,a)=>{const g=a===0?c:void 0;return H(l,e[a],n,s,i,o,g)});return{axles:u.map(l=>l.axleState),axleExecutions:u.map(l=>l.execution),arrived:u[u.length-1].completed}}class oe{graph=null;linesMap=new Map;curves=[];config;constructor(e){this.config={maxWheelbase:e.maxWheelbase,tangentMode:e.tangentMode}}get movementConfig(){return this.config}get lines(){return Array.from(this.linesMap.values())}getCurves(){return this.curves}setScene(e,n){this.linesMap.clear();for(const s of e)this.linesMap.set(s.id,s);this.curves=n,this.graph=x(e,n,this.config)}addLine(e){return this.linesMap.has(e.id)?!1:(this.linesMap.set(e.id,e),this.graph=x(Array.from(this.linesMap.values()),this.curves,this.config),!0)}updateLine(e,n){const s=this.linesMap.get(e);return s?(n.start&&(s.start=n.start),n.end&&(s.end=n.end),this.graph=x(Array.from(this.linesMap.values()),this.curves,this.config),!0):!1}updateLineEndpoint(e,n,s){return this.updateLine(e,{[n]:s})}renameLine(e,n){const s=n.trim();if(!s)return{success:!1,error:"Name cannot be empty"};if(s===e)return{success:!0};if(this.linesMap.has(s))return{success:!1,error:`"${s}" already exists`};const i=this.linesMap.get(e);if(!i)return{success:!1,error:`Line "${e}" not found`};i.id=s,this.linesMap.delete(e),this.linesMap.set(s,i);for(const o of this.curves)o.fromLineId===e&&(o.fromLineId=s),o.toLineId===e&&(o.toLineId=s);return this.graph=x(Array.from(this.linesMap.values()),this.curves,this.config),{success:!0}}removeLine(e){return this.linesMap.has(e)?(this.linesMap.delete(e),this.curves=this.curves.filter(n=>n.fromLineId!==e&&n.toLineId!==e),this.graph=x(Array.from(this.linesMap.values()),this.curves,this.config),!0):!1}addCurve(e){this.curves.push(e),this.graph=x(Array.from(this.linesMap.values()),this.curves,this.config)}updateCurve(e,n){return e<0||e>=this.curves.length?!1:(this.curves[e]={...this.curves[e],...n},this.graph=x(Array.from(this.linesMap.values()),this.curves,this.config),!0)}removeCurve(e){return e<0||e>=this.curves.length?!1:(this.curves.splice(e,1),this.graph=x(Array.from(this.linesMap.values()),this.curves,this.config),!0)}initializeVehicle(e,n,s){const i=this.linesMap.get(e);if(!i)return null;const{axleSpacings:o}=s;if(o.length===0)throw new Error("initializeVehicle: axleSpacings must have at least one entry (vehicle needs ≥2 axles)");const c=o.reduce((a,g)=>a+g,0),r=M(i),u=Math.min(n,r-c);return{axles:G(e,u,o,i).map(a=>({lineId:a.lineId,offset:a.absoluteOffset,position:a.position})),axleSpacings:o}}preparePath(e,n,s,i=!1){if(!this.graph)return null;const o=e.axleSpacings.reduce((h,p)=>h+p,0),c=e.axles[e.axles.length-1],r={lineId:c.lineId,offset:c.offset,axles:e.axles.map(h=>({lineId:h.lineId,position:h.position,absoluteOffset:h.offset})),axleSpacings:e.axleSpacings},u=J(r,{targetLineId:n,targetOffset:s,isPercentage:i},{graph:this.graph,linesMap:this.linesMap,curves:this.curves,config:this.config});if(!u)return null;let l=s;const a=this.linesMap.get(n);if(a){const h=Math.max(0,M(a)-o);l=i?s*h:Math.min(s,h)}let g=0;const d=[{segmentIndex:0,segmentDistance:o}];for(let h=0;h<e.axleSpacings.length;h++)g+=e.axleSpacings[h],d.push({segmentIndex:0,segmentDistance:o-g});return{path:u.path,curveDataMap:u.curveDataMap,axleExecutions:d,targetLineId:n,targetOffset:l}}moveVehicle(e,n,s){const i=e.axles.map(r=>({lineId:r.lineId,position:r.position,absoluteOffset:r.offset})),o=n.axleExecutions.map(r=>({currentSegmentIndex:r.segmentIndex,segmentDistance:r.segmentDistance})),c=U(i,o,n.path,s,this.linesMap,n.curveDataMap);return{state:{axles:c.axles.map(r=>({lineId:r.lineId,offset:r.absoluteOffset,position:r.position})),axleSpacings:e.axleSpacings},execution:{...n,axleExecutions:c.axleExecutions.map(r=>({segmentIndex:r.currentSegmentIndex,segmentDistance:r.segmentDistance}))},arrived:c.arrived}}}exports.PathEngine=oe;exports.arcLengthToSegmentPosition=k;exports.buildArcLengthTable=N;exports.buildGraph=x;exports.calculateBezierArcLength=j;exports.calculateFrontAxlePosition=ne;exports.calculateInitialAxlePositions=G;exports.calculatePositionOnCurve=S;exports.calculatePositionOnLine=y;exports.calculateTangentLength=q;exports.createBezierCurve=V;exports.createInitialMovementState=R;exports.distance=L;exports.distanceToT=$;exports.findPath=K;exports.getArcLength=te;exports.getCumulativeArcLength=_;exports.getLineLength=M;exports.getPointOnBezier=w;exports.getPointOnLine=F;exports.getPointOnLineByOffset=b;exports.getPositionFromOffset=A;exports.handleArrival=re;exports.initializeAllVehicles=se;exports.initializeMovingVehicle=Q;exports.isPointNearPoint=ee;exports.moveVehicle=U;exports.normalize=D;exports.prepareCommandPath=J;exports.resolveFromLineOffset=z;exports.resolveToLineOffset=W;exports.updateAxlePosition=H;
|