vehicle-path2 2.1.0 → 2.3.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/core/algorithms/pathFinding.d.ts +10 -10
- package/dist/core/algorithms/vehicleMovement.d.ts +6 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/snapshot.d.ts +16 -1
- package/dist/core.cjs +1 -1
- package/dist/core.js +63 -39
- package/dist/index-BUYdltrL.cjs +1 -0
- package/dist/{index-D8o0W80x.js → index-D-HctiIv.js} +213 -233
- package/dist/vehicle-path.cjs +1 -1
- package/dist/vehicle-path.js +1 -1
- package/package.json +1 -1
- package/dist/index-DfPg-M5u.cjs +0 -1
|
@@ -35,21 +35,21 @@ export interface VehiclePosition {
|
|
|
35
35
|
*/
|
|
36
36
|
export declare function calculateBezierArcLength(bezier: BezierCurve, segments?: number): number;
|
|
37
37
|
/**
|
|
38
|
-
* Resolve offset untuk FROM line (garis asal kurva)
|
|
39
|
-
*
|
|
40
|
-
* - 100% → lineLength (ujung garis)
|
|
38
|
+
* Resolve offset untuk FROM line (garis asal kurva).
|
|
39
|
+
* Kurva bisa ditempatkan di mana saja pada line: range [0, lineLength].
|
|
41
40
|
*
|
|
42
|
-
*
|
|
41
|
+
* Untuk absolute offset: clamp ke [0, lineLength].
|
|
42
|
+
* Untuk percentage (0-1): map ke [0, lineLength].
|
|
43
43
|
*/
|
|
44
|
-
export declare function resolveFromLineOffset(line: Line, offset: number | undefined, isPercentage: boolean | undefined, defaultPercentage: number,
|
|
44
|
+
export declare function resolveFromLineOffset(line: Line, offset: number | undefined, isPercentage: boolean | undefined, defaultPercentage: number, _maxWheelbase: number): number;
|
|
45
45
|
/**
|
|
46
|
-
* Resolve offset untuk TO line (garis tujuan kurva)
|
|
47
|
-
*
|
|
48
|
-
* - 100% → lineLength - wheelbase (untuk memberi ruang vehicle)
|
|
46
|
+
* Resolve offset untuk TO line (garis tujuan kurva).
|
|
47
|
+
* Kurva bisa ditempatkan di mana saja pada line: range [0, lineLength].
|
|
49
48
|
*
|
|
50
|
-
*
|
|
49
|
+
* Untuk absolute offset: clamp ke [0, lineLength].
|
|
50
|
+
* Untuk percentage (0-1): map ke [0, lineLength].
|
|
51
51
|
*/
|
|
52
|
-
export declare function resolveToLineOffset(line: Line, offset: number | undefined, isPercentage: boolean | undefined, defaultPercentage: number,
|
|
52
|
+
export declare function resolveToLineOffset(line: Line, offset: number | undefined, isPercentage: boolean | undefined, defaultPercentage: number, _maxWheelbase: number): number;
|
|
53
53
|
/**
|
|
54
54
|
* Membangun graph dari lines dan curves
|
|
55
55
|
*/
|
|
@@ -186,7 +186,12 @@ export type { VehicleMovementState as SegmentVehicleState };
|
|
|
186
186
|
* Advance semua axle vehicle oleh `distance` sepanjang path.
|
|
187
187
|
*
|
|
188
188
|
* Ini adalah low-level tick primitive. Update semua axle menggunakan
|
|
189
|
-
* arc-length parameterization. Arrival = axles[
|
|
189
|
+
* arc-length parameterization. Arrival = axles[N-1] (rearmost) mencapai ujung path.
|
|
190
|
+
*
|
|
191
|
+
* Semantik: path dibuat dari posisi rear axle ke targetOffset. Sehingga
|
|
192
|
+
* `arrived=true` berarti rear axle telah mencapai targetOffset — bukan
|
|
193
|
+
* front axle mencapai ujung segmennya. Front axle tetap bisa "hang over"
|
|
194
|
+
* di luar batas path (di ujung line) via maxOffset.
|
|
190
195
|
*
|
|
191
196
|
* @param axleStates - Array AxleState saat ini, axles[0] = terdepan
|
|
192
197
|
* @param axleExecutions - Array AxleExecutionState sesuai urutan axleStates
|
package/dist/core/index.d.ts
CHANGED
|
@@ -19,4 +19,4 @@ export { buildGraph, findPath, calculateBezierArcLength, resolveFromLineOffset,
|
|
|
19
19
|
export { initializeMovingVehicle, createInitialMovementState, initializeAllVehicles, calculateInitialAxlePositions, type InitializationResult, updateAxlePosition, calculatePositionOnLine, calculatePositionOnCurve, calculateFrontAxlePosition, getCumulativeArcLength, arcLengthToSegmentPosition, prepareCommandPath, type PreparedPath, handleArrival, type SegmentCompletionContext, type SegmentCompletionResult, type SegmentVehicleState, moveVehicle, getPositionFromOffset, getLineLength } from './algorithms/vehicleMovement';
|
|
20
20
|
export { PathEngine, type PathEngineConfig, type VehiclePathState, type PathExecution } from './engine';
|
|
21
21
|
export { distance, normalize, getPointOnLine, getPointOnLineByOffset, getPointOnBezier, createBezierCurve, buildArcLengthTable, distanceToT, getArcLength, calculateTangentLength, isPointNearPoint, type ArcLengthEntry, type CurveOffsetOptions } from './algorithms/math';
|
|
22
|
-
export { serializeScene, type SceneSnapshot } from './snapshot';
|
|
22
|
+
export { serializeScene, deserializeScene, type SceneSnapshot } from './snapshot';
|
package/dist/core/snapshot.d.ts
CHANGED
|
@@ -6,28 +6,37 @@ export interface SceneSnapshot {
|
|
|
6
6
|
fromLineId: string;
|
|
7
7
|
toLineId: string;
|
|
8
8
|
fromOffset: number;
|
|
9
|
+
fromIsPercentage: boolean;
|
|
9
10
|
toOffset: number;
|
|
11
|
+
toIsPercentage: boolean;
|
|
10
12
|
}>;
|
|
11
13
|
vehicles: Array<{
|
|
12
14
|
id: string;
|
|
15
|
+
lineId: string;
|
|
13
16
|
axles: Array<{
|
|
14
|
-
lineId: string;
|
|
15
17
|
offset: number;
|
|
16
18
|
}>;
|
|
17
19
|
axleSpacings: number[];
|
|
20
|
+
isPercentage: boolean;
|
|
18
21
|
}>;
|
|
19
22
|
}
|
|
20
23
|
/**
|
|
21
24
|
* Serialize scene state to a JSON string suitable for clipboard or storage.
|
|
22
25
|
* Strips derived fields (bezier curves, axle positions) — only source-of-truth
|
|
23
26
|
* data is included.
|
|
27
|
+
*
|
|
28
|
+
* Note: lineId is per-vehicle (not per-axle) because this snapshot captures
|
|
29
|
+
* static placement where all axles share the same line. For mid-movement state,
|
|
30
|
+
* use AxleState directly.
|
|
24
31
|
*/
|
|
25
32
|
export declare function serializeScene(lines: Line[], curves: Array<{
|
|
26
33
|
id: string;
|
|
27
34
|
fromLineId: string;
|
|
28
35
|
toLineId: string;
|
|
29
36
|
fromOffset: number;
|
|
37
|
+
fromIsPercentage?: boolean;
|
|
30
38
|
toOffset: number;
|
|
39
|
+
toIsPercentage?: boolean;
|
|
31
40
|
}>, vehicles: Array<{
|
|
32
41
|
id: string;
|
|
33
42
|
axles: Array<{
|
|
@@ -36,4 +45,10 @@ export declare function serializeScene(lines: Line[], curves: Array<{
|
|
|
36
45
|
[key: string]: unknown;
|
|
37
46
|
}>;
|
|
38
47
|
axleSpacings: number[];
|
|
48
|
+
isPercentage?: boolean;
|
|
39
49
|
}>): string;
|
|
50
|
+
/**
|
|
51
|
+
* Deserialize a JSON string back into a SceneSnapshot.
|
|
52
|
+
* Throws if the string is not valid JSON or missing required fields.
|
|
53
|
+
*/
|
|
54
|
+
export declare function deserializeScene(json: string): SceneSnapshot;
|
package/dist/core.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-BUYdltrL.cjs");function o(r,n,t){const a={lines:r,curves:n.map(i=>({id:i.id,fromLineId:i.fromLineId,toLineId:i.toLineId,fromOffset:i.fromOffset,fromIsPercentage:i.fromIsPercentage??!1,toOffset:i.toOffset,toIsPercentage:i.toIsPercentage??!1})),vehicles:t.map(i=>({id:i.id,lineId:i.axles[0].lineId,axles:i.axles.map(l=>({offset:l.offset})),axleSpacings:i.axleSpacings,isPercentage:i.isPercentage??!1}))};return JSON.stringify(a,null,2)}function s(r){let n;try{n=JSON.parse(r)}catch{throw new Error("deserializeScene: invalid JSON")}if(!n||typeof n!="object"||Array.isArray(n))throw new Error("deserializeScene: expected a JSON object");const t=n;if(!Array.isArray(t.lines))throw new Error('deserializeScene: missing "lines"');if(!Array.isArray(t.curves))throw new Error('deserializeScene: missing "curves"');if(!Array.isArray(t.vehicles))throw new Error('deserializeScene: missing "vehicles"');return{lines:t.lines,curves:t.curves,vehicles:t.vehicles}}exports.PathEngine=e.PathEngine;exports.arcLengthToSegmentPosition=e.arcLengthToSegmentPosition;exports.buildArcLengthTable=e.buildArcLengthTable;exports.buildGraph=e.buildGraph;exports.calculateBezierArcLength=e.calculateBezierArcLength;exports.calculateFrontAxlePosition=e.calculateFrontAxlePosition;exports.calculateInitialAxlePositions=e.calculateInitialAxlePositions;exports.calculatePositionOnCurve=e.calculatePositionOnCurve;exports.calculatePositionOnLine=e.calculatePositionOnLine;exports.calculateTangentLength=e.calculateTangentLength;exports.createBezierCurve=e.createBezierCurve;exports.createInitialMovementState=e.createInitialMovementState;exports.distance=e.distance;exports.distanceToT=e.distanceToT;exports.findPath=e.findPath;exports.getArcLength=e.getArcLength;exports.getCumulativeArcLength=e.getCumulativeArcLength;exports.getLineLength=e.getLineLength;exports.getPointOnBezier=e.getPointOnBezier;exports.getPointOnLine=e.getPointOnLine;exports.getPointOnLineByOffset=e.getPointOnLineByOffset;exports.getPositionFromOffset=e.getPositionFromOffset;exports.handleArrival=e.handleArrival;exports.initializeAllVehicles=e.initializeAllVehicles;exports.initializeMovingVehicle=e.initializeMovingVehicle;exports.isPointNearPoint=e.isPointNearPoint;exports.moveVehicle=e.moveVehicle;exports.normalize=e.normalize;exports.prepareCommandPath=e.prepareCommandPath;exports.resolveFromLineOffset=e.resolveFromLineOffset;exports.resolveToLineOffset=e.resolveToLineOffset;exports.updateAxlePosition=e.updateAxlePosition;exports.deserializeScene=s;exports.serializeScene=o;
|
package/dist/core.js
CHANGED
|
@@ -1,54 +1,78 @@
|
|
|
1
|
-
import { P as f, a as
|
|
2
|
-
function
|
|
3
|
-
const
|
|
4
|
-
lines:
|
|
5
|
-
curves:
|
|
1
|
+
import { P as f, a as g, b as h, c as d, d as u, e as m, f as P, g as A, h as v, i as L, j as O, k as p, l as S, m as z, n as y, o as w, p as x, q as I, r as b, s as E, t as T, u as B, v as C, w as N, x as j, y as J, z as F, A as V, B as M, C as k, D as q, E as D } from "./index-D-HctiIv.js";
|
|
2
|
+
function n(s, a, i) {
|
|
3
|
+
const r = {
|
|
4
|
+
lines: s,
|
|
5
|
+
curves: a.map((e) => ({
|
|
6
6
|
id: e.id,
|
|
7
7
|
fromLineId: e.fromLineId,
|
|
8
8
|
toLineId: e.toLineId,
|
|
9
9
|
fromOffset: e.fromOffset,
|
|
10
|
-
|
|
10
|
+
fromIsPercentage: e.fromIsPercentage ?? !1,
|
|
11
|
+
toOffset: e.toOffset,
|
|
12
|
+
toIsPercentage: e.toIsPercentage ?? !1
|
|
11
13
|
})),
|
|
12
|
-
vehicles:
|
|
14
|
+
vehicles: i.map((e) => ({
|
|
13
15
|
id: e.id,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
lineId: e.axles[0].lineId,
|
|
17
|
+
axles: e.axles.map((t) => ({ offset: t.offset })),
|
|
18
|
+
axleSpacings: e.axleSpacings,
|
|
19
|
+
isPercentage: e.isPercentage ?? !1
|
|
16
20
|
}))
|
|
17
21
|
};
|
|
18
|
-
return JSON.stringify(
|
|
22
|
+
return JSON.stringify(r, null, 2);
|
|
23
|
+
}
|
|
24
|
+
function o(s) {
|
|
25
|
+
let a;
|
|
26
|
+
try {
|
|
27
|
+
a = JSON.parse(s);
|
|
28
|
+
} catch {
|
|
29
|
+
throw new Error("deserializeScene: invalid JSON");
|
|
30
|
+
}
|
|
31
|
+
if (!a || typeof a != "object" || Array.isArray(a))
|
|
32
|
+
throw new Error("deserializeScene: expected a JSON object");
|
|
33
|
+
const i = a;
|
|
34
|
+
if (!Array.isArray(i.lines)) throw new Error('deserializeScene: missing "lines"');
|
|
35
|
+
if (!Array.isArray(i.curves)) throw new Error('deserializeScene: missing "curves"');
|
|
36
|
+
if (!Array.isArray(i.vehicles)) throw new Error('deserializeScene: missing "vehicles"');
|
|
37
|
+
return {
|
|
38
|
+
lines: i.lines,
|
|
39
|
+
curves: i.curves,
|
|
40
|
+
vehicles: i.vehicles
|
|
41
|
+
};
|
|
19
42
|
}
|
|
20
43
|
export {
|
|
21
44
|
f as PathEngine,
|
|
22
|
-
|
|
23
|
-
|
|
45
|
+
g as arcLengthToSegmentPosition,
|
|
46
|
+
h as buildArcLengthTable,
|
|
24
47
|
d as buildGraph,
|
|
25
|
-
|
|
48
|
+
u as calculateBezierArcLength,
|
|
26
49
|
m as calculateFrontAxlePosition,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
z as
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
P as calculateInitialAxlePositions,
|
|
51
|
+
A as calculatePositionOnCurve,
|
|
52
|
+
v as calculatePositionOnLine,
|
|
53
|
+
L as calculateTangentLength,
|
|
54
|
+
O as createBezierCurve,
|
|
55
|
+
p as createInitialMovementState,
|
|
56
|
+
o as deserializeScene,
|
|
57
|
+
S as distance,
|
|
58
|
+
z as distanceToT,
|
|
59
|
+
y as findPath,
|
|
60
|
+
w as getArcLength,
|
|
61
|
+
x as getCumulativeArcLength,
|
|
62
|
+
I as getLineLength,
|
|
63
|
+
b as getPointOnBezier,
|
|
64
|
+
E as getPointOnLine,
|
|
65
|
+
T as getPointOnLineByOffset,
|
|
66
|
+
B as getPositionFromOffset,
|
|
67
|
+
C as handleArrival,
|
|
68
|
+
N as initializeAllVehicles,
|
|
69
|
+
j as initializeMovingVehicle,
|
|
70
|
+
J as isPointNearPoint,
|
|
71
|
+
F as moveVehicle,
|
|
72
|
+
V as normalize,
|
|
73
|
+
M as prepareCommandPath,
|
|
74
|
+
k as resolveFromLineOffset,
|
|
75
|
+
q as resolveToLineOffset,
|
|
76
|
+
n as serializeScene,
|
|
53
77
|
D as updateAxlePosition
|
|
54
78
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function L(t,e){const s=e.x-t.x,n=e.y-t.y;return Math.sqrt(s*s+n*n)}function D(t,e){const s=e.x-t.x,n=e.y-t.y,i=Math.sqrt(s*s+n*n);return i===0?{x:0,y:0}:{x:s/i,y:n/i}}function E(t,e){return e*(t==="proportional-40"?.4:.5522)}function V(t,e,s,n=!1,i){const{maxWheelbase:o,tangentMode:c}=s;let r;i?.fromOffset!==void 0?r=b(t,i.fromOffset,i.fromIsPercentage??!1):r=t.end;let a;i?.toOffset!==void 0?a=b(e,i.toOffset,i.toIsPercentage??!1):a=e.start;const l=D(t.start,t.end),u=n?{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(u,a),p=E(c,h),f=n?{x:u.x-g.x*p,y:u.y-g.y*p}:{x:u.x+g.x*p,y:u.y+g.y*p},v={x:a.x-d.x*p,y:a.y-d.y*p};return{p0:u,p1:f,p2:v,p3:a}}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,s){const n=L(t.start,t.end);let i;return s?i=e:i=n>0?e/n:0,i=Math.max(0,Math.min(1,i)),F(t,i)}function T(t,e){const{p0:s,p1:n,p2:i,p3:o}=t,c=1-e,r=c*c,a=r*c,l=e*e,u=l*e;return{x:a*s.x+3*r*e*n.x+3*c*l*i.x+u*o.x,y:a*s.y+3*r*e*n.y+3*c*l*i.y+u*o.y}}function ee(t,e,s=10){return L(t,e)<=s}function N(t,e=100){const s=[{t:0,distance:0}];let n=t.p0,i=0;for(let o=1;o<=e;o++){const c=o/e,r=T(t,c);i+=L(n,r),s.push({t:c,distance:i}),n=r}return s}function $(t,e){if(e<=0)return 0;const s=t[t.length-1].distance;if(e>=s)return 1;let n=0,i=t.length-1;for(;n<i-1;){const u=Math.floor((n+i)/2);t[u].distance<e?n=u:i=u}const o=t[n].distance,c=t[i].distance,r=t[n].t,a=t[i].t;if(c===o)return r;const l=(e-o)/(c-o);return r+l*(a-r)}function te(t){return t[t.length-1].distance}function j(t,e=100){let s=0,n=t.p0;for(let i=1;i<=e;i++){const o=i/e,c=T(t,o);s+=L(n,c),n=c}return s}function z(t,e,s,n,i){const o=L(t.start,t.end);return e===void 0?n*o:s?Math.max(0,Math.min(e,1))*o:Math.max(0,Math.min(e,o))}function W(t,e,s,n,i){const o=L(t.start,t.end);return e===void 0?n*o:s?Math.max(0,Math.min(e,1))*o:Math.max(0,Math.min(e,o))}function x(t,e,s){const n=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)),n.set(c.id,[]);for(let c=0;c<e.length;c++){const r=e[c],a=i.get(r.fromLineId),l=i.get(r.toLineId);if(!a||!l)continue;const u=z(a,r.fromOffset,r.fromIsPercentage,1,s.maxWheelbase),g=W(l,r.toOffset,r.toIsPercentage,0,s.maxWheelbase),d=V(a,l,s,!1,{fromOffset:u,fromIsPercentage:!1,toOffset:g,toIsPercentage:!1}),h=j(d),p={curveIndex:c,fromLineId:r.fromLineId,toLineId:r.toLineId,fromOffset:u,toOffset:g,curveLength:h};n.get(r.fromLineId).push(p)}return{adjacency:n,lines:i,lineLengths:o}}function q(t,e){return t.curveCount!==e.curveCount?t.curveCount-e.curveCount:t.totalDistance-e.totalDistance}function K(t,e,s,n,i=!1){const{adjacency:o,lines:c,lineLengths:r}=t;if(!c.get(s))return null;const l=r.get(s),u=i?n/100*l:n,g=[],d=new Map,h=(f,v)=>`${f}:${Math.round(v)}`;if(e.lineId===s&&u>=e.offset){const f=u-e.offset;return{segments:[{type:"line",lineId:e.lineId,startOffset:e.offset,endOffset:u,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(q);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===s){const m=Math.abs(u-f.entryOffset);if(u>=f.entryOffset){const P={type:"line",lineId:s,startOffset:f.entryOffset,endOffset:u,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,w=f.curveCount+1,X=h(m.toLineId,m.toOffset),C=d.get(X);if(C!==void 0&&(C.curveCount<w||C.curveCount===w&&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:w,path:[...f.path,Y,Z]})}g.sort(q)}return null}function S(t,e){const s=Math.sqrt(Math.pow(t.end.x-t.start.x,2)+Math.pow(t.end.y-t.start.y,2)),n=s>0?e/s:0;return{x:t.start.x+(t.end.x-t.start.x)*Math.min(1,Math.max(0,n)),y:t.start.y+(t.end.y-t.start.y)*Math.min(1,Math.max(0,n))}}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,s){let n=0;for(let i=0;i<e;i++)n+=t.segments[i].length;return n+=s,n}function k(t,e){let s=0;for(let n=0;n<t.segments.length;n++){const i=t.segments[n],o=s+i.length;if(e<o)return{segmentIndex:n,segmentDistance:e-s};if(e===o)return n+1<t.segments.length?{segmentIndex:n+1,segmentDistance:0}:{segmentIndex:n,segmentDistance:i.length};s+=i.length}return null}function ne(t,e,s,n){const o=_(t,e,s)+n;return k(t,o)}function G(t,e,s,n){const i=M(n),o=s.length+1,c=new Array(o);c[o-1]={lineId:t,absoluteOffset:e,position:S(n,e)};let r=e;for(let a=o-2;a>=0;a--)r=Math.min(r+s[a],i),c[a]={lineId:t,absoluteOffset:r,position:S(n,r)};return c}function Q(t,e){return{...t,state:"idle"}}function R(t){return{vehicle:t,execution:null}}function se(t,e){const s=[],n=new Map;for(const i of t){if(!e.get(i.lineId))continue;const c=Q(i);s.push(c);const r=R(c);n.set(i.id,r)}return{movingVehicles:s,stateMap:n}}function y(t,e){return{position:S(t,e),lineId:t.id,absoluteOffset:e}}function A(t,e){const s=$(t.arcLengthTable,e);return{position:T(t.bezier,s)}}function H(t,e,s,n,i,o,c){const r=s.segments[e.currentSegmentIndex],a=e.segmentDistance+n;if(a>=r.length){const u=a-r.length,g=e.currentSegmentIndex+1;if(g>=s.segments.length){if(c!==void 0&&r.type==="line"){const f=i.get(r.lineId),v=r.startOffset+a;if(v<=c){const O=y(f,v);return{axleState:{...t,...O},execution:{...e,segmentDistance:a},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):A(o.get(r.curveIndex),r.length);return{axleState:{...t,...p},execution:{...e,segmentDistance:r.length},completed:!0}}const d=s.segments[g],h=d.type==="line"?y(i.get(d.lineId),d.startOffset+u):A(o.get(d.curveIndex),u);return{axleState:{...t,...h},execution:{currentSegmentIndex:g,segmentDistance:u},completed:!1}}const l=r.type==="line"?y(i.get(r.lineId),r.startOffset+a):A(o.get(r.curveIndex),a);return{axleState:{...t,...l},execution:{...e,segmentDistance:a},completed:!1}}function ie(t,e,s,n){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=s.get(c.fromLineId),a=s.get(c.toLineId);if(r&&a){const l=z(r,c.fromOffset,c.fromIsPercentage,1,n.maxWheelbase),u=W(a,c.toOffset,c.toIsPercentage,0,n.maxWheelbase),g=V(r,a,n,!1,{fromOffset:l,fromIsPercentage:!1,toOffset:u,toIsPercentage:!1}),d=N(g);i.set(o.curveIndex,{bezier:g,arcLengthTable:d})}}}return i}function J(t,e,s){const{graph:n,linesMap:i,curves:o,config:c}=s,r=i.get(e.targetLineId);if(!r)return null;const a=t.axleSpacings.reduce((f,v)=>f+v,0),u=M(r)-a;if(u<=0)return null;const g=e.isPercentage?e.targetOffset*u:Math.min(e.targetOffset,u),d=t.axles[t.axles.length-1],h=K(n,{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 s=t.execution,i=e.vehicleQueues.get(t.vehicle.id)?.[s.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:s,isWaiting:!0}}function U(t,e,s,n,i,o){let c;const r=e[0];if(r.currentSegmentIndex<s.segments.length){const l=s.segments[r.currentSegmentIndex];if(l.type==="line"){const u=i.get(l.lineId);u&&(c=M(u))}}const a=t.map((l,u)=>{const g=u===0?c:void 0;return H(l,e[u],s,n,i,o,g)});return{axles:a.map(l=>l.axleState),axleExecutions:a.map(l=>l.execution),arrived:a[a.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,s){this.linesMap.clear();for(const n of e)this.linesMap.set(n.id,n);this.curves=s,this.graph=x(e,s,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,s){const n=this.linesMap.get(e);return n?(s.start&&(n.start=s.start),s.end&&(n.end=s.end),this.graph=x(Array.from(this.linesMap.values()),this.curves,this.config),!0):!1}updateLineEndpoint(e,s,n){return this.updateLine(e,{[s]:n})}renameLine(e,s){const n=s.trim();if(!n)return{success:!1,error:"Name cannot be empty"};if(n===e)return{success:!0};if(this.linesMap.has(n))return{success:!1,error:`"${n}" already exists`};const i=this.linesMap.get(e);if(!i)return{success:!1,error:`Line "${e}" not found`};i.id=n,this.linesMap.delete(e),this.linesMap.set(n,i);for(const o of this.curves)o.fromLineId===e&&(o.fromLineId=n),o.toLineId===e&&(o.toLineId=n);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(s=>s.fromLineId!==e&&s.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,s){return e<0||e>=this.curves.length?!1:(this.curves[e]={...this.curves[e],...s},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,s,n){const i=this.linesMap.get(e);if(!i)return null;const o=n.reduce((l,u)=>l+u,0),c=M(i),r=Math.min(s,c-o);return{axles:G(e,r,n,i).map(l=>({lineId:l.lineId,offset:l.absoluteOffset,position:l.position})),axleSpacings:n}}preparePath(e,s,n,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},a=J(r,{targetLineId:s,targetOffset:n,isPercentage:i},{graph:this.graph,linesMap:this.linesMap,curves:this.curves,config:this.config});if(!a)return null;let l=n;const u=this.linesMap.get(s);if(u){const h=Math.max(0,M(u)-o);l=i?n*h:Math.min(n,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:a.path,curveDataMap:a.curveDataMap,axleExecutions:d,targetLineId:s,targetOffset:l}}moveVehicle(e,s,n){const i=e.axles.map(r=>({lineId:r.lineId,position:r.position,absoluteOffset:r.offset})),o=s.axleExecutions.map(r=>({currentSegmentIndex:r.segmentIndex,segmentDistance:r.segmentDistance})),c=U(i,o,s.path,n,this.linesMap,s.curveDataMap);return{state:{axles:c.axles.map(r=>({lineId:r.lineId,offset:r.absoluteOffset,position:r.position})),axleSpacings:e.axleSpacings},execution:{...s,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=A;exports.calculatePositionOnLine=y;exports.calculateTangentLength=E;exports.createBezierCurve=V;exports.createInitialMovementState=R;exports.distance=L;exports.distanceToT=$;exports.findPath=K;exports.getArcLength=te;exports.getCumulativeArcLength=_;exports.getLineLength=M;exports.getPointOnBezier=T;exports.getPointOnLine=F;exports.getPointOnLineByOffset=b;exports.getPositionFromOffset=S;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;
|
|
@@ -3,27 +3,27 @@ function y(t, e) {
|
|
|
3
3
|
return Math.sqrt(s * s + n * n);
|
|
4
4
|
}
|
|
5
5
|
function w(t, e) {
|
|
6
|
-
const s = e.x - t.x, n = e.y - t.y,
|
|
7
|
-
return
|
|
6
|
+
const s = e.x - t.x, n = e.y - t.y, r = Math.sqrt(s * s + n * n);
|
|
7
|
+
return r === 0 ? { x: 0, y: 0 } : { x: s / r, y: n / r };
|
|
8
8
|
}
|
|
9
9
|
function k(t, e) {
|
|
10
10
|
return e * (t === "proportional-40" ? 0.4 : 0.5522);
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
const { maxWheelbase:
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
let
|
|
17
|
-
|
|
12
|
+
function z(t, e, s, n = !1, r) {
|
|
13
|
+
const { maxWheelbase: o, tangentMode: a } = s;
|
|
14
|
+
let i;
|
|
15
|
+
r?.fromOffset !== void 0 ? i = V(t, r.fromOffset, r.fromIsPercentage ?? !1) : i = t.end;
|
|
16
|
+
let c;
|
|
17
|
+
r?.toOffset !== void 0 ? c = V(e, r.toOffset, r.toIsPercentage ?? !1) : c = e.start;
|
|
18
18
|
const l = w(t.start, t.end), f = n ? {
|
|
19
19
|
// Transition with flip: kurva dimulai dari P (baseP0 - wheelbase in line direction)
|
|
20
|
-
x:
|
|
21
|
-
y:
|
|
22
|
-
} :
|
|
23
|
-
x:
|
|
24
|
-
y:
|
|
20
|
+
x: i.x - l.x * o,
|
|
21
|
+
y: i.y - l.y * o
|
|
22
|
+
} : i, g = w(t.start, t.end), d = w(e.start, e.end), h = y(f, c), p = k(a, h), u = n ? { x: f.x - g.x * p, y: f.y - g.y * p } : { x: f.x + g.x * p, y: f.y + g.y * p }, v = {
|
|
23
|
+
x: c.x - d.x * p,
|
|
24
|
+
y: c.y - d.y * p
|
|
25
25
|
};
|
|
26
|
-
return { p0: f, p1: u, p2: v, p3:
|
|
26
|
+
return { p0: f, p1: u, p2: v, p3: c };
|
|
27
27
|
}
|
|
28
28
|
function K(t, e) {
|
|
29
29
|
return {
|
|
@@ -33,14 +33,14 @@ function K(t, e) {
|
|
|
33
33
|
}
|
|
34
34
|
function V(t, e, s) {
|
|
35
35
|
const n = y(t.start, t.end);
|
|
36
|
-
let
|
|
37
|
-
return s ?
|
|
36
|
+
let r;
|
|
37
|
+
return s ? r = e : r = n > 0 ? e / n : 0, r = Math.max(0, Math.min(1, r)), K(t, r);
|
|
38
38
|
}
|
|
39
|
-
function
|
|
40
|
-
const { p0: s, p1: n, p2:
|
|
39
|
+
function b(t, e) {
|
|
40
|
+
const { p0: s, p1: n, p2: r, p3: o } = t, a = 1 - e, i = a * a, c = i * a, l = e * e, f = l * e;
|
|
41
41
|
return {
|
|
42
|
-
x:
|
|
43
|
-
y:
|
|
42
|
+
x: c * s.x + 3 * i * e * n.x + 3 * a * l * r.x + f * o.x,
|
|
43
|
+
y: c * s.y + 3 * i * e * n.y + 3 * a * l * r.y + f * o.y
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
function ne(t, e, s = 10) {
|
|
@@ -48,75 +48,55 @@ function ne(t, e, s = 10) {
|
|
|
48
48
|
}
|
|
49
49
|
function N(t, e = 100) {
|
|
50
50
|
const s = [{ t: 0, distance: 0 }];
|
|
51
|
-
let n = t.p0,
|
|
52
|
-
for (let
|
|
53
|
-
const
|
|
54
|
-
|
|
51
|
+
let n = t.p0, r = 0;
|
|
52
|
+
for (let o = 1; o <= e; o++) {
|
|
53
|
+
const a = o / e, i = b(t, a);
|
|
54
|
+
r += y(n, i), s.push({ t: a, distance: r }), n = i;
|
|
55
55
|
}
|
|
56
56
|
return s;
|
|
57
57
|
}
|
|
58
|
-
function
|
|
58
|
+
function _(t, e) {
|
|
59
59
|
if (e <= 0) return 0;
|
|
60
60
|
const s = t[t.length - 1].distance;
|
|
61
61
|
if (e >= s) return 1;
|
|
62
|
-
let n = 0,
|
|
63
|
-
for (; n <
|
|
64
|
-
const f = Math.floor((n +
|
|
65
|
-
t[f].distance < e ? n = f :
|
|
62
|
+
let n = 0, r = t.length - 1;
|
|
63
|
+
for (; n < r - 1; ) {
|
|
64
|
+
const f = Math.floor((n + r) / 2);
|
|
65
|
+
t[f].distance < e ? n = f : r = f;
|
|
66
66
|
}
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
69
|
-
const l = (e -
|
|
70
|
-
return
|
|
67
|
+
const o = t[n].distance, a = t[r].distance, i = t[n].t, c = t[r].t;
|
|
68
|
+
if (a === o) return i;
|
|
69
|
+
const l = (e - o) / (a - o);
|
|
70
|
+
return i + l * (c - i);
|
|
71
71
|
}
|
|
72
72
|
function se(t) {
|
|
73
73
|
return t[t.length - 1].distance;
|
|
74
74
|
}
|
|
75
|
-
function
|
|
75
|
+
function F(t, e = 100) {
|
|
76
76
|
let s = 0, n = t.p0;
|
|
77
|
-
for (let
|
|
78
|
-
const
|
|
79
|
-
s += y(n,
|
|
77
|
+
for (let r = 1; r <= e; r++) {
|
|
78
|
+
const o = r / e, a = b(t, o);
|
|
79
|
+
s += y(n, a), n = a;
|
|
80
80
|
}
|
|
81
81
|
return s;
|
|
82
82
|
}
|
|
83
|
-
function
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
return c;
|
|
87
|
-
let r;
|
|
88
|
-
if (e === void 0)
|
|
89
|
-
r = n;
|
|
90
|
-
else if (s)
|
|
91
|
-
r = e;
|
|
92
|
-
else {
|
|
93
|
-
const a = Math.max(0, Math.min(e, o));
|
|
94
|
-
return i + a;
|
|
95
|
-
}
|
|
96
|
-
return i + r * o;
|
|
83
|
+
function q(t, e, s, n, r) {
|
|
84
|
+
const o = y(t.start, t.end);
|
|
85
|
+
return e === void 0 ? n * o : s ? Math.max(0, Math.min(e, 1)) * o : Math.max(0, Math.min(e, o));
|
|
97
86
|
}
|
|
98
|
-
function
|
|
99
|
-
const o = y(t.start, t.end)
|
|
100
|
-
|
|
101
|
-
return 0;
|
|
102
|
-
let r;
|
|
103
|
-
if (e === void 0)
|
|
104
|
-
r = n;
|
|
105
|
-
else if (s)
|
|
106
|
-
r = e;
|
|
107
|
-
else
|
|
108
|
-
return Math.max(0, Math.min(e, o));
|
|
109
|
-
return r * o;
|
|
87
|
+
function E(t, e, s, n, r) {
|
|
88
|
+
const o = y(t.start, t.end);
|
|
89
|
+
return e === void 0 ? n * o : s ? Math.max(0, Math.min(e, 1)) * o : Math.max(0, Math.min(e, o));
|
|
110
90
|
}
|
|
111
91
|
function I(t, e, s) {
|
|
112
|
-
const n = /* @__PURE__ */ new Map(),
|
|
113
|
-
for (const
|
|
114
|
-
|
|
115
|
-
for (let
|
|
116
|
-
const
|
|
117
|
-
if (!
|
|
118
|
-
const f =
|
|
119
|
-
|
|
92
|
+
const n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
|
|
93
|
+
for (const a of t)
|
|
94
|
+
r.set(a.id, a), o.set(a.id, y(a.start, a.end)), n.set(a.id, []);
|
|
95
|
+
for (let a = 0; a < e.length; a++) {
|
|
96
|
+
const i = e[a], c = r.get(i.fromLineId), l = r.get(i.toLineId);
|
|
97
|
+
if (!c || !l) continue;
|
|
98
|
+
const f = q(c, i.fromOffset, i.fromIsPercentage, 1, s.maxWheelbase), g = E(l, i.toOffset, i.toIsPercentage, 0, s.maxWheelbase), d = z(
|
|
99
|
+
c,
|
|
120
100
|
l,
|
|
121
101
|
s,
|
|
122
102
|
!1,
|
|
@@ -129,25 +109,25 @@ function I(t, e, s) {
|
|
|
129
109
|
toIsPercentage: !1
|
|
130
110
|
// Already resolved to absolute
|
|
131
111
|
}
|
|
132
|
-
), h =
|
|
133
|
-
curveIndex:
|
|
134
|
-
fromLineId:
|
|
135
|
-
toLineId:
|
|
112
|
+
), h = F(d), p = {
|
|
113
|
+
curveIndex: a,
|
|
114
|
+
fromLineId: i.fromLineId,
|
|
115
|
+
toLineId: i.toLineId,
|
|
136
116
|
fromOffset: f,
|
|
137
117
|
toOffset: g,
|
|
138
118
|
curveLength: h
|
|
139
119
|
};
|
|
140
|
-
n.get(
|
|
120
|
+
n.get(i.fromLineId).push(p);
|
|
141
121
|
}
|
|
142
|
-
return { adjacency: n, lines:
|
|
122
|
+
return { adjacency: n, lines: r, lineLengths: o };
|
|
143
123
|
}
|
|
144
|
-
function
|
|
124
|
+
function W(t, e) {
|
|
145
125
|
return t.curveCount !== e.curveCount ? t.curveCount - e.curveCount : t.totalDistance - e.totalDistance;
|
|
146
126
|
}
|
|
147
|
-
function
|
|
148
|
-
const { adjacency:
|
|
149
|
-
if (!
|
|
150
|
-
const l =
|
|
127
|
+
function G(t, e, s, n, r = !1) {
|
|
128
|
+
const { adjacency: o, lines: a, lineLengths: i } = t;
|
|
129
|
+
if (!a.get(s)) return null;
|
|
130
|
+
const l = i.get(s), f = r ? n / 100 * l : n, g = [], d = /* @__PURE__ */ new Map(), h = (u, v) => `${u}:${Math.round(v)}`;
|
|
151
131
|
if (e.lineId === s && f >= e.offset) {
|
|
152
132
|
const u = f - e.offset;
|
|
153
133
|
return {
|
|
@@ -162,7 +142,7 @@ function Q(t, e, s, n, i = !1) {
|
|
|
162
142
|
curveCount: 0
|
|
163
143
|
};
|
|
164
144
|
}
|
|
165
|
-
const p =
|
|
145
|
+
const p = o.get(e.lineId) || [];
|
|
166
146
|
for (const u of p) {
|
|
167
147
|
if (u.fromOffset < e.offset) continue;
|
|
168
148
|
const v = u.fromOffset - e.offset, x = v + u.curveLength, L = {
|
|
@@ -186,7 +166,7 @@ function Q(t, e, s, n, i = !1) {
|
|
|
186
166
|
path: [L, m]
|
|
187
167
|
});
|
|
188
168
|
}
|
|
189
|
-
for (g.sort(
|
|
169
|
+
for (g.sort(W); g.length > 0; ) {
|
|
190
170
|
const u = g.shift(), v = h(u.lineId, u.entryOffset), x = d.get(v);
|
|
191
171
|
if (x !== void 0 && (x.curveCount < u.curveCount || x.curveCount === u.curveCount && x.distance <= u.totalDistance))
|
|
192
172
|
continue;
|
|
@@ -207,11 +187,11 @@ function Q(t, e, s, n, i = !1) {
|
|
|
207
187
|
};
|
|
208
188
|
}
|
|
209
189
|
}
|
|
210
|
-
const L =
|
|
190
|
+
const L = o.get(u.lineId) || [];
|
|
211
191
|
for (const m of L) {
|
|
212
192
|
if (m.fromOffset < u.entryOffset) continue;
|
|
213
|
-
const C = m.fromOffset - u.entryOffset,
|
|
214
|
-
if (D !== void 0 && (D.curveCount < P || D.curveCount === P && D.distance <=
|
|
193
|
+
const C = m.fromOffset - u.entryOffset, T = u.totalDistance + C + m.curveLength, P = u.curveCount + 1, B = h(m.toLineId, m.toOffset), D = d.get(B);
|
|
194
|
+
if (D !== void 0 && (D.curveCount < P || D.curveCount === P && D.distance <= T))
|
|
215
195
|
continue;
|
|
216
196
|
const j = {
|
|
217
197
|
type: "line",
|
|
@@ -229,12 +209,12 @@ function Q(t, e, s, n, i = !1) {
|
|
|
229
209
|
g.push({
|
|
230
210
|
lineId: m.toLineId,
|
|
231
211
|
entryOffset: m.toOffset,
|
|
232
|
-
totalDistance:
|
|
212
|
+
totalDistance: T,
|
|
233
213
|
curveCount: P,
|
|
234
214
|
path: [...u.path, j, $]
|
|
235
215
|
});
|
|
236
216
|
}
|
|
237
|
-
g.sort(
|
|
217
|
+
g.sort(W);
|
|
238
218
|
}
|
|
239
219
|
return null;
|
|
240
220
|
}
|
|
@@ -252,56 +232,56 @@ function O(t) {
|
|
|
252
232
|
Math.pow(t.end.x - t.start.x, 2) + Math.pow(t.end.y - t.start.y, 2)
|
|
253
233
|
);
|
|
254
234
|
}
|
|
255
|
-
function
|
|
235
|
+
function Q(t, e, s) {
|
|
256
236
|
let n = 0;
|
|
257
|
-
for (let
|
|
258
|
-
n += t.segments[
|
|
237
|
+
for (let r = 0; r < e; r++)
|
|
238
|
+
n += t.segments[r].length;
|
|
259
239
|
return n += s, n;
|
|
260
240
|
}
|
|
261
|
-
function
|
|
241
|
+
function R(t, e) {
|
|
262
242
|
let s = 0;
|
|
263
243
|
for (let n = 0; n < t.segments.length; n++) {
|
|
264
|
-
const
|
|
265
|
-
if (e <
|
|
244
|
+
const r = t.segments[n], o = s + r.length;
|
|
245
|
+
if (e < o)
|
|
266
246
|
return {
|
|
267
247
|
segmentIndex: n,
|
|
268
248
|
segmentDistance: e - s
|
|
269
249
|
};
|
|
270
|
-
if (e ===
|
|
250
|
+
if (e === o)
|
|
271
251
|
return n + 1 < t.segments.length ? {
|
|
272
252
|
segmentIndex: n + 1,
|
|
273
253
|
segmentDistance: 0
|
|
274
254
|
} : {
|
|
275
255
|
segmentIndex: n,
|
|
276
|
-
segmentDistance:
|
|
256
|
+
segmentDistance: r.length
|
|
277
257
|
};
|
|
278
|
-
s +=
|
|
258
|
+
s += r.length;
|
|
279
259
|
}
|
|
280
260
|
return null;
|
|
281
261
|
}
|
|
282
|
-
function
|
|
283
|
-
const
|
|
262
|
+
function re(t, e, s, n) {
|
|
263
|
+
const o = Q(
|
|
284
264
|
t,
|
|
285
265
|
e,
|
|
286
266
|
s
|
|
287
267
|
) + n;
|
|
288
|
-
return
|
|
268
|
+
return R(t, o);
|
|
289
269
|
}
|
|
290
270
|
function H(t, e, s, n) {
|
|
291
|
-
const
|
|
292
|
-
o
|
|
271
|
+
const r = O(n), o = s.length + 1, a = new Array(o);
|
|
272
|
+
a[o - 1] = {
|
|
293
273
|
lineId: t,
|
|
294
274
|
absoluteOffset: e,
|
|
295
275
|
position: A(n, e)
|
|
296
276
|
};
|
|
297
|
-
let
|
|
298
|
-
for (let
|
|
299
|
-
|
|
277
|
+
let i = e;
|
|
278
|
+
for (let c = o - 2; c >= 0; c--)
|
|
279
|
+
i = Math.min(i + s[c], r), a[c] = {
|
|
300
280
|
lineId: t,
|
|
301
|
-
absoluteOffset:
|
|
302
|
-
position: A(n,
|
|
281
|
+
absoluteOffset: i,
|
|
282
|
+
position: A(n, i)
|
|
303
283
|
};
|
|
304
|
-
return
|
|
284
|
+
return a;
|
|
305
285
|
}
|
|
306
286
|
function J(t, e) {
|
|
307
287
|
return {
|
|
@@ -315,14 +295,14 @@ function U(t) {
|
|
|
315
295
|
execution: null
|
|
316
296
|
};
|
|
317
297
|
}
|
|
318
|
-
function
|
|
298
|
+
function ie(t, e) {
|
|
319
299
|
const s = [], n = /* @__PURE__ */ new Map();
|
|
320
|
-
for (const
|
|
321
|
-
if (!e.get(
|
|
322
|
-
const
|
|
323
|
-
s.push(
|
|
324
|
-
const
|
|
325
|
-
n.set(
|
|
300
|
+
for (const r of t) {
|
|
301
|
+
if (!e.get(r.lineId)) continue;
|
|
302
|
+
const a = J(r);
|
|
303
|
+
s.push(a);
|
|
304
|
+
const i = U(a);
|
|
305
|
+
n.set(r.id, i);
|
|
326
306
|
}
|
|
327
307
|
return { movingVehicles: s, stateMap: n };
|
|
328
308
|
}
|
|
@@ -330,49 +310,49 @@ function M(t, e) {
|
|
|
330
310
|
return { position: A(t, e), lineId: t.id, absoluteOffset: e };
|
|
331
311
|
}
|
|
332
312
|
function S(t, e) {
|
|
333
|
-
const s =
|
|
334
|
-
return { position:
|
|
313
|
+
const s = _(t.arcLengthTable, e);
|
|
314
|
+
return { position: b(t.bezier, s) };
|
|
335
315
|
}
|
|
336
|
-
function X(t, e, s, n,
|
|
337
|
-
const
|
|
338
|
-
if (
|
|
339
|
-
const f =
|
|
316
|
+
function X(t, e, s, n, r, o, a) {
|
|
317
|
+
const i = s.segments[e.currentSegmentIndex], c = e.segmentDistance + n;
|
|
318
|
+
if (c >= i.length) {
|
|
319
|
+
const f = c - i.length, g = e.currentSegmentIndex + 1;
|
|
340
320
|
if (g >= s.segments.length) {
|
|
341
|
-
if (
|
|
342
|
-
const u =
|
|
343
|
-
if (v <=
|
|
321
|
+
if (a !== void 0 && i.type === "line") {
|
|
322
|
+
const u = r.get(i.lineId), v = i.startOffset + c;
|
|
323
|
+
if (v <= a) {
|
|
344
324
|
const L = M(u, v);
|
|
345
325
|
return {
|
|
346
326
|
axleState: { ...t, ...L },
|
|
347
|
-
execution: { ...e, segmentDistance:
|
|
327
|
+
execution: { ...e, segmentDistance: c },
|
|
348
328
|
completed: !1
|
|
349
329
|
};
|
|
350
330
|
}
|
|
351
|
-
const x = M(u,
|
|
331
|
+
const x = M(u, a);
|
|
352
332
|
return {
|
|
353
333
|
axleState: { ...t, ...x },
|
|
354
|
-
execution: { ...e, segmentDistance:
|
|
334
|
+
execution: { ...e, segmentDistance: a - i.startOffset },
|
|
355
335
|
completed: !0
|
|
356
336
|
};
|
|
357
337
|
}
|
|
358
|
-
const p =
|
|
359
|
-
|
|
360
|
-
|
|
338
|
+
const p = i.type === "line" ? M(
|
|
339
|
+
r.get(i.lineId),
|
|
340
|
+
i.endOffset
|
|
361
341
|
) : S(
|
|
362
|
-
|
|
363
|
-
|
|
342
|
+
o.get(i.curveIndex),
|
|
343
|
+
i.length
|
|
364
344
|
);
|
|
365
345
|
return {
|
|
366
346
|
axleState: { ...t, ...p },
|
|
367
|
-
execution: { ...e, segmentDistance:
|
|
347
|
+
execution: { ...e, segmentDistance: i.length },
|
|
368
348
|
completed: !0
|
|
369
349
|
};
|
|
370
350
|
}
|
|
371
351
|
const d = s.segments[g], h = d.type === "line" ? M(
|
|
372
|
-
|
|
352
|
+
r.get(d.lineId),
|
|
373
353
|
d.startOffset + f
|
|
374
354
|
) : S(
|
|
375
|
-
|
|
355
|
+
o.get(d.curveIndex),
|
|
376
356
|
f
|
|
377
357
|
);
|
|
378
358
|
return {
|
|
@@ -384,43 +364,43 @@ function X(t, e, s, n, i, c, o) {
|
|
|
384
364
|
completed: !1
|
|
385
365
|
};
|
|
386
366
|
}
|
|
387
|
-
const l =
|
|
388
|
-
|
|
389
|
-
|
|
367
|
+
const l = i.type === "line" ? M(
|
|
368
|
+
r.get(i.lineId),
|
|
369
|
+
i.startOffset + c
|
|
390
370
|
) : S(
|
|
391
|
-
|
|
392
|
-
|
|
371
|
+
o.get(i.curveIndex),
|
|
372
|
+
c
|
|
393
373
|
);
|
|
394
374
|
return {
|
|
395
375
|
axleState: { ...t, ...l },
|
|
396
|
-
execution: { ...e, segmentDistance:
|
|
376
|
+
execution: { ...e, segmentDistance: c },
|
|
397
377
|
completed: !1
|
|
398
378
|
};
|
|
399
379
|
}
|
|
400
380
|
function Y(t, e, s, n) {
|
|
401
|
-
const
|
|
402
|
-
for (const
|
|
403
|
-
if (
|
|
404
|
-
const
|
|
405
|
-
if (
|
|
406
|
-
const
|
|
407
|
-
if (
|
|
408
|
-
const l =
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
381
|
+
const r = /* @__PURE__ */ new Map();
|
|
382
|
+
for (const o of t.segments)
|
|
383
|
+
if (o.type === "curve" && o.curveIndex !== void 0) {
|
|
384
|
+
const a = e[o.curveIndex];
|
|
385
|
+
if (a) {
|
|
386
|
+
const i = s.get(a.fromLineId), c = s.get(a.toLineId);
|
|
387
|
+
if (i && c) {
|
|
388
|
+
const l = q(
|
|
389
|
+
i,
|
|
390
|
+
a.fromOffset,
|
|
391
|
+
a.fromIsPercentage,
|
|
412
392
|
1,
|
|
413
393
|
// Default: 100% = 1.0
|
|
414
394
|
n.maxWheelbase
|
|
415
|
-
), f =
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
395
|
+
), f = E(
|
|
396
|
+
c,
|
|
397
|
+
a.toOffset,
|
|
398
|
+
a.toIsPercentage,
|
|
419
399
|
0,
|
|
420
400
|
n.maxWheelbase
|
|
421
|
-
), g =
|
|
422
|
-
|
|
423
|
-
|
|
401
|
+
), g = z(
|
|
402
|
+
i,
|
|
403
|
+
c,
|
|
424
404
|
n,
|
|
425
405
|
!1,
|
|
426
406
|
// willFlip is always false now
|
|
@@ -433,18 +413,18 @@ function Y(t, e, s, n) {
|
|
|
433
413
|
// Already resolved to absolute
|
|
434
414
|
}
|
|
435
415
|
), d = N(g);
|
|
436
|
-
|
|
416
|
+
r.set(o.curveIndex, { bezier: g, arcLengthTable: d });
|
|
437
417
|
}
|
|
438
418
|
}
|
|
439
419
|
}
|
|
440
|
-
return
|
|
420
|
+
return r;
|
|
441
421
|
}
|
|
442
422
|
function Z(t, e, s) {
|
|
443
|
-
const { graph: n, linesMap:
|
|
444
|
-
if (!
|
|
445
|
-
const
|
|
423
|
+
const { graph: n, linesMap: r, curves: o, config: a } = s, i = r.get(e.targetLineId);
|
|
424
|
+
if (!i) return null;
|
|
425
|
+
const c = t.axleSpacings.reduce((u, v) => u + v, 0), f = O(i) - c;
|
|
446
426
|
if (f <= 0) return null;
|
|
447
|
-
const g = e.isPercentage ? e.targetOffset * f : Math.min(e.targetOffset, f), d = t.axles[t.axles.length - 1], h =
|
|
427
|
+
const g = e.isPercentage ? e.targetOffset * f : Math.min(e.targetOffset, f), d = t.axles[t.axles.length - 1], h = G(
|
|
448
428
|
n,
|
|
449
429
|
{ lineId: d.lineId, offset: d.absoluteOffset },
|
|
450
430
|
e.targetLineId,
|
|
@@ -452,20 +432,20 @@ function Z(t, e, s) {
|
|
|
452
432
|
!1
|
|
453
433
|
);
|
|
454
434
|
if (!h) return null;
|
|
455
|
-
const p = Y(h,
|
|
435
|
+
const p = Y(h, o, r, a);
|
|
456
436
|
return { path: h, curveDataMap: p };
|
|
457
437
|
}
|
|
458
438
|
function oe(t, e) {
|
|
459
|
-
const s = t.execution,
|
|
460
|
-
return
|
|
439
|
+
const s = t.execution, r = e.vehicleQueues.get(t.vehicle.id)?.[s.currentCommandIndex];
|
|
440
|
+
return r && e.onCommandComplete && e.onCommandComplete({
|
|
461
441
|
vehicleId: t.vehicle.id,
|
|
462
|
-
command:
|
|
442
|
+
command: r,
|
|
463
443
|
finalPosition: {
|
|
464
444
|
lineId: t.vehicle.axles[t.vehicle.axles.length - 1].lineId,
|
|
465
445
|
absoluteOffset: t.vehicle.axles[t.vehicle.axles.length - 1].absoluteOffset,
|
|
466
446
|
position: t.vehicle.axles[t.vehicle.axles.length - 1].position
|
|
467
447
|
},
|
|
468
|
-
payload:
|
|
448
|
+
payload: r.payload
|
|
469
449
|
}), {
|
|
470
450
|
handled: !0,
|
|
471
451
|
vehicle: { ...t.vehicle, state: "waiting" },
|
|
@@ -474,28 +454,28 @@ function oe(t, e) {
|
|
|
474
454
|
isWaiting: !0
|
|
475
455
|
};
|
|
476
456
|
}
|
|
477
|
-
function ee(t, e, s, n,
|
|
478
|
-
let
|
|
479
|
-
const
|
|
480
|
-
if (
|
|
481
|
-
const l = s.segments[
|
|
457
|
+
function ee(t, e, s, n, r, o) {
|
|
458
|
+
let a;
|
|
459
|
+
const i = e[0];
|
|
460
|
+
if (i.currentSegmentIndex < s.segments.length) {
|
|
461
|
+
const l = s.segments[i.currentSegmentIndex];
|
|
482
462
|
if (l.type === "line") {
|
|
483
|
-
const f =
|
|
484
|
-
f && (
|
|
463
|
+
const f = r.get(l.lineId);
|
|
464
|
+
f && (a = O(f));
|
|
485
465
|
}
|
|
486
466
|
}
|
|
487
|
-
const
|
|
488
|
-
const g = f === 0 ?
|
|
489
|
-
return X(l, e[f], s, n,
|
|
467
|
+
const c = t.map((l, f) => {
|
|
468
|
+
const g = f === 0 ? a : void 0;
|
|
469
|
+
return X(l, e[f], s, n, r, o, g);
|
|
490
470
|
});
|
|
491
471
|
return {
|
|
492
|
-
axles:
|
|
493
|
-
axleExecutions:
|
|
494
|
-
arrived:
|
|
495
|
-
// axles[
|
|
472
|
+
axles: c.map((l) => l.axleState),
|
|
473
|
+
axleExecutions: c.map((l) => l.execution),
|
|
474
|
+
arrived: c[c.length - 1].completed
|
|
475
|
+
// axles[N-1] = rearmost menentukan arrived
|
|
496
476
|
};
|
|
497
477
|
}
|
|
498
|
-
class
|
|
478
|
+
class ae {
|
|
499
479
|
graph = null;
|
|
500
480
|
linesMap = /* @__PURE__ */ new Map();
|
|
501
481
|
curves = [];
|
|
@@ -557,11 +537,11 @@ class ce {
|
|
|
557
537
|
if (!n) return { success: !1, error: "Name cannot be empty" };
|
|
558
538
|
if (n === e) return { success: !0 };
|
|
559
539
|
if (this.linesMap.has(n)) return { success: !1, error: `"${n}" already exists` };
|
|
560
|
-
const
|
|
561
|
-
if (!
|
|
562
|
-
|
|
563
|
-
for (const
|
|
564
|
-
|
|
540
|
+
const r = this.linesMap.get(e);
|
|
541
|
+
if (!r) return { success: !1, error: `Line "${e}" not found` };
|
|
542
|
+
r.id = n, this.linesMap.delete(e), this.linesMap.set(n, r);
|
|
543
|
+
for (const o of this.curves)
|
|
544
|
+
o.fromLineId === e && (o.fromLineId = n), o.toLineId === e && (o.toLineId = n);
|
|
565
545
|
return this.graph = I(Array.from(this.linesMap.values()), this.curves, this.config), { success: !0 };
|
|
566
546
|
}
|
|
567
547
|
/**
|
|
@@ -600,11 +580,11 @@ class ce {
|
|
|
600
580
|
* @returns Initial VehiclePathState, or null if lineId does not exist
|
|
601
581
|
*/
|
|
602
582
|
initializeVehicle(e, s, n) {
|
|
603
|
-
const
|
|
604
|
-
if (!
|
|
605
|
-
const
|
|
583
|
+
const r = this.linesMap.get(e);
|
|
584
|
+
if (!r) return null;
|
|
585
|
+
const o = n.reduce((l, f) => l + f, 0), a = O(r), i = Math.min(s, a - o);
|
|
606
586
|
return {
|
|
607
|
-
axles: H(e,
|
|
587
|
+
axles: H(e, i, n, r).map((l) => ({ lineId: l.lineId, offset: l.absoluteOffset, position: l.position })),
|
|
608
588
|
axleSpacings: n
|
|
609
589
|
};
|
|
610
590
|
}
|
|
@@ -618,44 +598,44 @@ class ce {
|
|
|
618
598
|
* @param targetOffset - Position on the target line
|
|
619
599
|
* @param isPercentage - If true, targetOffset is 0-1 fraction; if false, absolute distance
|
|
620
600
|
*/
|
|
621
|
-
preparePath(e, s, n,
|
|
601
|
+
preparePath(e, s, n, r = !1) {
|
|
622
602
|
if (!this.graph) return null;
|
|
623
|
-
const
|
|
624
|
-
lineId:
|
|
625
|
-
offset:
|
|
603
|
+
const o = e.axleSpacings.reduce((h, p) => h + p, 0), a = e.axles[e.axles.length - 1], i = {
|
|
604
|
+
lineId: a.lineId,
|
|
605
|
+
offset: a.offset,
|
|
626
606
|
axles: e.axles.map((h) => ({
|
|
627
607
|
lineId: h.lineId,
|
|
628
608
|
position: h.position,
|
|
629
609
|
absoluteOffset: h.offset
|
|
630
610
|
})),
|
|
631
611
|
axleSpacings: e.axleSpacings
|
|
632
|
-
},
|
|
612
|
+
}, c = Z(i, {
|
|
633
613
|
targetLineId: s,
|
|
634
614
|
targetOffset: n,
|
|
635
|
-
isPercentage:
|
|
615
|
+
isPercentage: r
|
|
636
616
|
}, {
|
|
637
617
|
graph: this.graph,
|
|
638
618
|
linesMap: this.linesMap,
|
|
639
619
|
curves: this.curves,
|
|
640
620
|
config: this.config
|
|
641
621
|
});
|
|
642
|
-
if (!
|
|
622
|
+
if (!c) return null;
|
|
643
623
|
let l = n;
|
|
644
624
|
const f = this.linesMap.get(s);
|
|
645
625
|
if (f) {
|
|
646
|
-
const h = Math.max(0, O(f) -
|
|
647
|
-
l =
|
|
626
|
+
const h = Math.max(0, O(f) - o);
|
|
627
|
+
l = r ? n * h : Math.min(n, h);
|
|
648
628
|
}
|
|
649
629
|
let g = 0;
|
|
650
630
|
const d = [
|
|
651
|
-
{ segmentIndex: 0, segmentDistance:
|
|
631
|
+
{ segmentIndex: 0, segmentDistance: o }
|
|
652
632
|
// axles[0] = front
|
|
653
633
|
];
|
|
654
634
|
for (let h = 0; h < e.axleSpacings.length; h++)
|
|
655
|
-
g += e.axleSpacings[h], d.push({ segmentIndex: 0, segmentDistance:
|
|
635
|
+
g += e.axleSpacings[h], d.push({ segmentIndex: 0, segmentDistance: o - g });
|
|
656
636
|
return {
|
|
657
|
-
path:
|
|
658
|
-
curveDataMap:
|
|
637
|
+
path: c.path,
|
|
638
|
+
curveDataMap: c.curveDataMap,
|
|
659
639
|
axleExecutions: d,
|
|
660
640
|
targetLineId: s,
|
|
661
641
|
targetOffset: l
|
|
@@ -672,60 +652,60 @@ class ce {
|
|
|
672
652
|
* @param distance - Distance to advance this tick (speed × deltaTime)
|
|
673
653
|
*/
|
|
674
654
|
moveVehicle(e, s, n) {
|
|
675
|
-
const
|
|
676
|
-
lineId:
|
|
677
|
-
position:
|
|
678
|
-
absoluteOffset:
|
|
679
|
-
})),
|
|
680
|
-
currentSegmentIndex:
|
|
681
|
-
segmentDistance:
|
|
682
|
-
})),
|
|
655
|
+
const r = e.axles.map((i) => ({
|
|
656
|
+
lineId: i.lineId,
|
|
657
|
+
position: i.position,
|
|
658
|
+
absoluteOffset: i.offset
|
|
659
|
+
})), o = s.axleExecutions.map((i) => ({
|
|
660
|
+
currentSegmentIndex: i.segmentIndex,
|
|
661
|
+
segmentDistance: i.segmentDistance
|
|
662
|
+
})), a = ee(r, o, s.path, n, this.linesMap, s.curveDataMap);
|
|
683
663
|
return {
|
|
684
664
|
state: {
|
|
685
|
-
axles:
|
|
665
|
+
axles: a.axles.map((i) => ({ lineId: i.lineId, offset: i.absoluteOffset, position: i.position })),
|
|
686
666
|
axleSpacings: e.axleSpacings
|
|
687
667
|
},
|
|
688
668
|
execution: {
|
|
689
669
|
...s,
|
|
690
|
-
axleExecutions:
|
|
691
|
-
segmentIndex:
|
|
692
|
-
segmentDistance:
|
|
670
|
+
axleExecutions: a.axleExecutions.map((i) => ({
|
|
671
|
+
segmentIndex: i.currentSegmentIndex,
|
|
672
|
+
segmentDistance: i.segmentDistance
|
|
693
673
|
}))
|
|
694
674
|
},
|
|
695
|
-
arrived:
|
|
675
|
+
arrived: a.arrived
|
|
696
676
|
};
|
|
697
677
|
}
|
|
698
678
|
}
|
|
699
679
|
export {
|
|
700
680
|
w as A,
|
|
701
681
|
Z as B,
|
|
702
|
-
|
|
703
|
-
|
|
682
|
+
q as C,
|
|
683
|
+
E as D,
|
|
704
684
|
X as E,
|
|
705
|
-
|
|
706
|
-
|
|
685
|
+
ae as P,
|
|
686
|
+
R as a,
|
|
707
687
|
N as b,
|
|
708
688
|
I as c,
|
|
709
|
-
|
|
710
|
-
|
|
689
|
+
F as d,
|
|
690
|
+
re as e,
|
|
711
691
|
H as f,
|
|
712
692
|
S as g,
|
|
713
693
|
M as h,
|
|
714
694
|
k as i,
|
|
715
|
-
|
|
695
|
+
z as j,
|
|
716
696
|
U as k,
|
|
717
697
|
y as l,
|
|
718
|
-
|
|
719
|
-
|
|
698
|
+
_ as m,
|
|
699
|
+
G as n,
|
|
720
700
|
se as o,
|
|
721
|
-
|
|
701
|
+
Q as p,
|
|
722
702
|
O as q,
|
|
723
|
-
|
|
703
|
+
b as r,
|
|
724
704
|
K as s,
|
|
725
705
|
V as t,
|
|
726
706
|
A as u,
|
|
727
707
|
oe as v,
|
|
728
|
-
|
|
708
|
+
ie as w,
|
|
729
709
|
J as x,
|
|
730
710
|
ne as y,
|
|
731
711
|
ee as z
|
package/dist/vehicle-path.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-BUYdltrL.cjs");exports.PathEngine=e.PathEngine;exports.arcLengthToSegmentPosition=e.arcLengthToSegmentPosition;exports.buildArcLengthTable=e.buildArcLengthTable;exports.buildGraph=e.buildGraph;exports.calculateBezierArcLength=e.calculateBezierArcLength;exports.calculateFrontAxlePosition=e.calculateFrontAxlePosition;exports.calculateInitialAxlePositions=e.calculateInitialAxlePositions;exports.calculatePositionOnCurve=e.calculatePositionOnCurve;exports.calculatePositionOnLine=e.calculatePositionOnLine;exports.createBezierCurve=e.createBezierCurve;exports.createInitialMovementState=e.createInitialMovementState;exports.distance=e.distance;exports.distanceToT=e.distanceToT;exports.findPath=e.findPath;exports.getArcLength=e.getArcLength;exports.getCumulativeArcLength=e.getCumulativeArcLength;exports.getLineLength=e.getLineLength;exports.getPointOnBezier=e.getPointOnBezier;exports.getPointOnLine=e.getPointOnLine;exports.getPointOnLineByOffset=e.getPointOnLineByOffset;exports.getPositionFromOffset=e.getPositionFromOffset;exports.handleArrival=e.handleArrival;exports.initializeAllVehicles=e.initializeAllVehicles;exports.initializeMovingVehicle=e.initializeMovingVehicle;exports.moveVehicle=e.moveVehicle;exports.normalize=e.normalize;exports.prepareCommandPath=e.prepareCommandPath;exports.resolveFromLineOffset=e.resolveFromLineOffset;exports.resolveToLineOffset=e.resolveToLineOffset;exports.updateAxlePosition=e.updateAxlePosition;
|
package/dist/vehicle-path.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as t, a as i, b as s, c as n, d as o, e as l, f as r, g as c, h as g, j as h, k as P, l as u, m as L, n as f, o as m, p as v, q as A, r as d, s as O, t as z, u as p, v as x, w as B, x as C, z as T, A as b, B as F, C as V, D as E, E as I } from "./index-
|
|
1
|
+
import { P as t, a as i, b as s, c as n, d as o, e as l, f as r, g as c, h as g, j as h, k as P, l as u, m as L, n as f, o as m, p as v, q as A, r as d, s as O, t as z, u as p, v as x, w as B, x as C, z as T, A as b, B as F, C as V, D as E, E as I } from "./index-D-HctiIv.js";
|
|
2
2
|
export {
|
|
3
3
|
t as PathEngine,
|
|
4
4
|
i as arcLengthToSegmentPosition,
|
package/package.json
CHANGED
package/dist/index-DfPg-M5u.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";function L(t,e){const s=e.x-t.x,n=e.y-t.y;return Math.sqrt(s*s+n*n)}function D(t,e){const s=e.x-t.x,n=e.y-t.y,i=Math.sqrt(s*s+n*n);return i===0?{x:0,y:0}:{x:s/i,y:n/i}}function W(t,e){return e*(t==="proportional-40"?.4:.5522)}function V(t,e,s,n=!1,i){const{maxWheelbase:c,tangentMode:o}=s;let r;i?.fromOffset!==void 0?r=b(t,i.fromOffset,i.fromIsPercentage??!1):r=t.end;let a;i?.toOffset!==void 0?a=b(e,i.toOffset,i.toIsPercentage??!1):a=e.start;const l=D(t.start,t.end),f=n?{x:r.x-l.x*c,y:r.y-l.y*c}:r,g=D(t.start,t.end),d=D(e.start,e.end),h=L(f,a),p=W(o,h),u=n?{x:f.x-g.x*p,y:f.y-g.y*p}:{x:f.x+g.x*p,y:f.y+g.y*p},v={x:a.x-d.x*p,y:a.y-d.y*p};return{p0:f,p1:u,p2:v,p3:a}}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,s){const n=L(t.start,t.end);let i;return s?i=e:i=n>0?e/n:0,i=Math.max(0,Math.min(1,i)),F(t,i)}function T(t,e){const{p0:s,p1:n,p2:i,p3:c}=t,o=1-e,r=o*o,a=r*o,l=e*e,f=l*e;return{x:a*s.x+3*r*e*n.x+3*o*l*i.x+f*c.x,y:a*s.y+3*r*e*n.y+3*o*l*i.y+f*c.y}}function ee(t,e,s=10){return L(t,e)<=s}function N(t,e=100){const s=[{t:0,distance:0}];let n=t.p0,i=0;for(let c=1;c<=e;c++){const o=c/e,r=T(t,o);i+=L(n,r),s.push({t:o,distance:i}),n=r}return s}function $(t,e){if(e<=0)return 0;const s=t[t.length-1].distance;if(e>=s)return 1;let n=0,i=t.length-1;for(;n<i-1;){const f=Math.floor((n+i)/2);t[f].distance<e?n=f:i=f}const c=t[n].distance,o=t[i].distance,r=t[n].t,a=t[i].t;if(o===c)return r;const l=(e-c)/(o-c);return r+l*(a-r)}function te(t){return t[t.length-1].distance}function j(t,e=100){let s=0,n=t.p0;for(let i=1;i<=e;i++){const c=i/e,o=T(t,c);s+=L(n,o),n=o}return s}function z(t,e,s,n,i){const c=L(t.start,t.end),o=c-i;if(o<=0)return c;let r;if(e===void 0)r=n;else if(s)r=e;else{const a=Math.max(0,Math.min(e,o));return i+a}return i+r*o}function B(t,e,s,n,i){const o=L(t.start,t.end)-i;if(o<=0)return 0;let r;if(e===void 0)r=n;else if(s)r=e;else return Math.max(0,Math.min(e,o));return r*o}function x(t,e,s){const n=new Map,i=new Map,c=new Map;for(const o of t)i.set(o.id,o),c.set(o.id,L(o.start,o.end)),n.set(o.id,[]);for(let o=0;o<e.length;o++){const r=e[o],a=i.get(r.fromLineId),l=i.get(r.toLineId);if(!a||!l)continue;const f=z(a,r.fromOffset,r.fromIsPercentage,1,s.maxWheelbase),g=B(l,r.toOffset,r.toIsPercentage,0,s.maxWheelbase),d=V(a,l,s,!1,{fromOffset:f,fromIsPercentage:!1,toOffset:g,toIsPercentage:!1}),h=j(d),p={curveIndex:o,fromLineId:r.fromLineId,toLineId:r.toLineId,fromOffset:f,toOffset:g,curveLength:h};n.get(r.fromLineId).push(p)}return{adjacency:n,lines:i,lineLengths:c}}function E(t,e){return t.curveCount!==e.curveCount?t.curveCount-e.curveCount:t.totalDistance-e.totalDistance}function K(t,e,s,n,i=!1){const{adjacency:c,lines:o,lineLengths:r}=t;if(!o.get(s))return null;const l=r.get(s),f=i?n/100*l:n,g=[],d=new Map,h=(u,v)=>`${u}:${Math.round(v)}`;if(e.lineId===s&&f>=e.offset){const u=f-e.offset;return{segments:[{type:"line",lineId:e.lineId,startOffset:e.offset,endOffset:f,length:u}],totalDistance:u,curveCount:0}}const p=c.get(e.lineId)||[];for(const u of p){if(u.fromOffset<e.offset)continue;const v=u.fromOffset-e.offset,I=v+u.curveLength,M={type:"line",lineId:e.lineId,startOffset:e.offset,endOffset:u.fromOffset,length:v},m={type:"curve",curveIndex:u.curveIndex,startOffset:0,endOffset:u.curveLength,length:u.curveLength};g.push({lineId:u.toLineId,entryOffset:u.toOffset,totalDistance:I,curveCount:1,path:[M,m]})}for(g.sort(E);g.length>0;){const u=g.shift(),v=h(u.lineId,u.entryOffset),I=d.get(v);if(I!==void 0&&(I.curveCount<u.curveCount||I.curveCount===u.curveCount&&I.distance<=u.totalDistance))continue;if(d.set(v,{curveCount:u.curveCount,distance:u.totalDistance}),u.lineId===s){const m=Math.abs(f-u.entryOffset);if(f>=u.entryOffset){const P={type:"line",lineId:s,startOffset:u.entryOffset,endOffset:f,length:m};return{segments:[...u.path,P],totalDistance:u.totalDistance+m,curveCount:u.curveCount}}}const M=c.get(u.lineId)||[];for(const m of M){if(m.fromOffset<u.entryOffset)continue;const P=m.fromOffset-u.entryOffset,q=u.totalDistance+P+m.curveLength,w=u.curveCount+1,X=h(m.toLineId,m.toOffset),C=d.get(X);if(C!==void 0&&(C.curveCount<w||C.curveCount===w&&C.distance<=q))continue;const Y={type:"line",lineId:u.lineId,startOffset:u.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:q,curveCount:w,path:[...u.path,Y,Z]})}g.sort(E)}return null}function S(t,e){const s=Math.sqrt(Math.pow(t.end.x-t.start.x,2)+Math.pow(t.end.y-t.start.y,2)),n=s>0?e/s:0;return{x:t.start.x+(t.end.x-t.start.x)*Math.min(1,Math.max(0,n)),y:t.start.y+(t.end.y-t.start.y)*Math.min(1,Math.max(0,n))}}function O(t){return Math.sqrt(Math.pow(t.end.x-t.start.x,2)+Math.pow(t.end.y-t.start.y,2))}function k(t,e,s){let n=0;for(let i=0;i<e;i++)n+=t.segments[i].length;return n+=s,n}function G(t,e){let s=0;for(let n=0;n<t.segments.length;n++){const i=t.segments[n],c=s+i.length;if(e<c)return{segmentIndex:n,segmentDistance:e-s};if(e===c)return n+1<t.segments.length?{segmentIndex:n+1,segmentDistance:0}:{segmentIndex:n,segmentDistance:i.length};s+=i.length}return null}function ne(t,e,s,n){const c=k(t,e,s)+n;return G(t,c)}function Q(t,e,s,n){const i=O(n),c=s.length+1,o=new Array(c);o[c-1]={lineId:t,absoluteOffset:e,position:S(n,e)};let r=e;for(let a=c-2;a>=0;a--)r=Math.min(r+s[a],i),o[a]={lineId:t,absoluteOffset:r,position:S(n,r)};return o}function R(t,e){return{...t,state:"idle"}}function _(t){return{vehicle:t,execution:null}}function se(t,e){const s=[],n=new Map;for(const i of t){if(!e.get(i.lineId))continue;const o=R(i);s.push(o);const r=_(o);n.set(i.id,r)}return{movingVehicles:s,stateMap:n}}function y(t,e){return{position:S(t,e),lineId:t.id,absoluteOffset:e}}function A(t,e){const s=$(t.arcLengthTable,e);return{position:T(t.bezier,s)}}function H(t,e,s,n,i,c,o){const r=s.segments[e.currentSegmentIndex],a=e.segmentDistance+n;if(a>=r.length){const f=a-r.length,g=e.currentSegmentIndex+1;if(g>=s.segments.length){if(o!==void 0&&r.type==="line"){const u=i.get(r.lineId),v=r.startOffset+a;if(v<=o){const M=y(u,v);return{axleState:{...t,...M},execution:{...e,segmentDistance:a},completed:!1}}const I=y(u,o);return{axleState:{...t,...I},execution:{...e,segmentDistance:o-r.startOffset},completed:!0}}const p=r.type==="line"?y(i.get(r.lineId),r.endOffset):A(c.get(r.curveIndex),r.length);return{axleState:{...t,...p},execution:{...e,segmentDistance:r.length},completed:!0}}const d=s.segments[g],h=d.type==="line"?y(i.get(d.lineId),d.startOffset+f):A(c.get(d.curveIndex),f);return{axleState:{...t,...h},execution:{currentSegmentIndex:g,segmentDistance:f},completed:!1}}const l=r.type==="line"?y(i.get(r.lineId),r.startOffset+a):A(c.get(r.curveIndex),a);return{axleState:{...t,...l},execution:{...e,segmentDistance:a},completed:!1}}function ie(t,e,s,n){const i=new Map;for(const c of t.segments)if(c.type==="curve"&&c.curveIndex!==void 0){const o=e[c.curveIndex];if(o){const r=s.get(o.fromLineId),a=s.get(o.toLineId);if(r&&a){const l=z(r,o.fromOffset,o.fromIsPercentage,1,n.maxWheelbase),f=B(a,o.toOffset,o.toIsPercentage,0,n.maxWheelbase),g=V(r,a,n,!1,{fromOffset:l,fromIsPercentage:!1,toOffset:f,toIsPercentage:!1}),d=N(g);i.set(c.curveIndex,{bezier:g,arcLengthTable:d})}}}return i}function J(t,e,s){const{graph:n,linesMap:i,curves:c,config:o}=s,r=i.get(e.targetLineId);if(!r)return null;const a=t.axleSpacings.reduce((u,v)=>u+v,0),f=O(r)-a;if(f<=0)return null;const g=e.isPercentage?e.targetOffset*f:Math.min(e.targetOffset,f),d=t.axles[t.axles.length-1],h=K(n,{lineId:d.lineId,offset:d.absoluteOffset},e.targetLineId,g,!1);if(!h)return null;const p=ie(h,c,i,o);return{path:h,curveDataMap:p}}function re(t,e){const s=t.execution,i=e.vehicleQueues.get(t.vehicle.id)?.[s.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:s,isWaiting:!0}}function U(t,e,s,n,i,c){let o;const r=e[0];if(r.currentSegmentIndex<s.segments.length){const l=s.segments[r.currentSegmentIndex];if(l.type==="line"){const f=i.get(l.lineId);f&&(o=O(f))}}const a=t.map((l,f)=>{const g=f===0?o:void 0;return H(l,e[f],s,n,i,c,g)});return{axles:a.map(l=>l.axleState),axleExecutions:a.map(l=>l.execution),arrived:a[0].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,s){this.linesMap.clear();for(const n of e)this.linesMap.set(n.id,n);this.curves=s,this.graph=x(e,s,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,s){const n=this.linesMap.get(e);return n?(s.start&&(n.start=s.start),s.end&&(n.end=s.end),this.graph=x(Array.from(this.linesMap.values()),this.curves,this.config),!0):!1}updateLineEndpoint(e,s,n){return this.updateLine(e,{[s]:n})}renameLine(e,s){const n=s.trim();if(!n)return{success:!1,error:"Name cannot be empty"};if(n===e)return{success:!0};if(this.linesMap.has(n))return{success:!1,error:`"${n}" already exists`};const i=this.linesMap.get(e);if(!i)return{success:!1,error:`Line "${e}" not found`};i.id=n,this.linesMap.delete(e),this.linesMap.set(n,i);for(const c of this.curves)c.fromLineId===e&&(c.fromLineId=n),c.toLineId===e&&(c.toLineId=n);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(s=>s.fromLineId!==e&&s.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,s){return e<0||e>=this.curves.length?!1:(this.curves[e]={...this.curves[e],...s},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,s,n){const i=this.linesMap.get(e);if(!i)return null;const c=n.reduce((l,f)=>l+f,0),o=O(i),r=Math.min(s,o-c);return{axles:Q(e,r,n,i).map(l=>({lineId:l.lineId,offset:l.absoluteOffset,position:l.position})),axleSpacings:n}}preparePath(e,s,n,i=!1){if(!this.graph)return null;const c=e.axleSpacings.reduce((h,p)=>h+p,0),o=e.axles[e.axles.length-1],r={lineId:o.lineId,offset:o.offset,axles:e.axles.map(h=>({lineId:h.lineId,position:h.position,absoluteOffset:h.offset})),axleSpacings:e.axleSpacings},a=J(r,{targetLineId:s,targetOffset:n,isPercentage:i},{graph:this.graph,linesMap:this.linesMap,curves:this.curves,config:this.config});if(!a)return null;let l=n;const f=this.linesMap.get(s);if(f){const h=Math.max(0,O(f)-c);l=i?n*h:Math.min(n,h)}let g=0;const d=[{segmentIndex:0,segmentDistance:c}];for(let h=0;h<e.axleSpacings.length;h++)g+=e.axleSpacings[h],d.push({segmentIndex:0,segmentDistance:c-g});return{path:a.path,curveDataMap:a.curveDataMap,axleExecutions:d,targetLineId:s,targetOffset:l}}moveVehicle(e,s,n){const i=e.axles.map(r=>({lineId:r.lineId,position:r.position,absoluteOffset:r.offset})),c=s.axleExecutions.map(r=>({currentSegmentIndex:r.segmentIndex,segmentDistance:r.segmentDistance})),o=U(i,c,s.path,n,this.linesMap,s.curveDataMap);return{state:{axles:o.axles.map(r=>({lineId:r.lineId,offset:r.absoluteOffset,position:r.position})),axleSpacings:e.axleSpacings},execution:{...s,axleExecutions:o.axleExecutions.map(r=>({segmentIndex:r.currentSegmentIndex,segmentDistance:r.segmentDistance}))},arrived:o.arrived}}}exports.PathEngine=oe;exports.arcLengthToSegmentPosition=G;exports.buildArcLengthTable=N;exports.buildGraph=x;exports.calculateBezierArcLength=j;exports.calculateFrontAxlePosition=ne;exports.calculateInitialAxlePositions=Q;exports.calculatePositionOnCurve=A;exports.calculatePositionOnLine=y;exports.calculateTangentLength=W;exports.createBezierCurve=V;exports.createInitialMovementState=_;exports.distance=L;exports.distanceToT=$;exports.findPath=K;exports.getArcLength=te;exports.getCumulativeArcLength=k;exports.getLineLength=O;exports.getPointOnBezier=T;exports.getPointOnLine=F;exports.getPointOnLineByOffset=b;exports.getPositionFromOffset=S;exports.handleArrival=re;exports.initializeAllVehicles=se;exports.initializeMovingVehicle=R;exports.isPointNearPoint=ee;exports.moveVehicle=U;exports.normalize=D;exports.prepareCommandPath=J;exports.resolveFromLineOffset=z;exports.resolveToLineOffset=B;exports.updateAxlePosition=H;
|