vehicle-path2 2.4.0 → 3.0.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/engine.d.ts +7 -7
- package/dist/core/index.d.ts +1 -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 +50 -59
- package/dist/{index-wjEuFiRl.js → index-BV93143R.js} +259 -255
- package/dist/index-C4FckUel.cjs +1 -0
- package/dist/vehicle-path.cjs +1 -1
- package/dist/vehicle-path.js +1 -1
- package/package.json +1 -1
- package/dist/index-BUYdltrL.cjs +0 -1
package/dist/core/engine.d.ts
CHANGED
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
* ```typescript
|
|
10
10
|
* import { PathEngine } from 'vehicle-path/core'
|
|
11
11
|
*
|
|
12
|
-
* const engine = new PathEngine({
|
|
12
|
+
* const engine = new PathEngine({ maxWheelbase: 100, tangentMode: 'proportional-40' })
|
|
13
13
|
*
|
|
14
14
|
* engine.setScene(lines, curves)
|
|
15
15
|
*
|
|
16
|
-
* const state = engine.initializeVehicle('line-1', 0)
|
|
16
|
+
* const state = engine.initializeVehicle('line-1', 0, { axleSpacings: [40] })
|
|
17
17
|
* const execution = engine.preparePath(state, 'line-3', 1.0, true)
|
|
18
18
|
*
|
|
19
19
|
* // In your animation/game loop:
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
28
|
import type { Line, Curve, Point } from './types/geometry';
|
|
29
|
+
import type { VehicleDefinition } from './types/vehicle';
|
|
29
30
|
import type { MovementConfig, CurveData } from './types/movement';
|
|
30
31
|
import type { PathResult } from './algorithms/pathFinding';
|
|
31
32
|
import type { TangentMode } from './types/config';
|
|
@@ -37,14 +38,12 @@ export interface PathEngineConfig {
|
|
|
37
38
|
* Multi-axle position state for use with PathEngine.
|
|
38
39
|
* axles[0] = terdepan, axles[N-1] = paling belakang.
|
|
39
40
|
*/
|
|
40
|
-
export interface VehiclePathState {
|
|
41
|
+
export interface VehiclePathState extends VehicleDefinition {
|
|
41
42
|
axles: Array<{
|
|
42
43
|
lineId: string;
|
|
43
44
|
offset: number;
|
|
44
45
|
position: Point;
|
|
45
46
|
}>;
|
|
46
|
-
/** N-1 jarak arc-length antar axle berurutan */
|
|
47
|
-
axleSpacings: number[];
|
|
48
47
|
}
|
|
49
48
|
/**
|
|
50
49
|
* Active path execution state for a vehicle in motion.
|
|
@@ -127,10 +126,11 @@ export declare class PathEngine {
|
|
|
127
126
|
*
|
|
128
127
|
* @param lineId - The line to place the vehicle on
|
|
129
128
|
* @param rearOffset - Absolute distance offset untuk axle paling belakang
|
|
130
|
-
* @param
|
|
129
|
+
* @param vehicle - VehicleDefinition (or any object extending it with axleSpacings)
|
|
131
130
|
* @returns Initial VehiclePathState, or null if lineId does not exist
|
|
131
|
+
* @throws if axleSpacings is empty
|
|
132
132
|
*/
|
|
133
|
-
initializeVehicle(lineId: string, rearOffset: number,
|
|
133
|
+
initializeVehicle(lineId: string, rearOffset: number, vehicle: VehicleDefinition): VehiclePathState | null;
|
|
134
134
|
/**
|
|
135
135
|
* Prepare a path from the vehicle's current position to a target.
|
|
136
136
|
*
|
package/dist/core/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* ```
|
|
12
12
|
*/
|
|
13
13
|
export type { Point, Line, BezierCurve, Curve } from './types/geometry';
|
|
14
|
-
export type { VehicleState, VehicleStart, Vehicle, AxleState, GotoCommand, GotoCompletionInfo, GotoCompletionCallback } from './types/vehicle';
|
|
14
|
+
export type { VehicleDefinition, VehicleState, VehicleStart, Vehicle, AxleState, GotoCommand, GotoCompletionInfo, GotoCompletionCallback } from './types/vehicle';
|
|
15
15
|
export type { CurveData, AxleExecutionState, PathExecutionState, VehicleMovementState, MovementConfig, SceneContext } from './types/movement';
|
|
16
16
|
export type { TangentMode } from './types/config';
|
|
17
17
|
export type { CoordinateInput, SceneLineInput, SceneConnectionInput, SceneConfig, VehicleInput, VehicleUpdateInput, ConnectionUpdateInput, GotoCommandInput } from './types/api';
|
package/dist/core/snapshot.d.ts
CHANGED
|
@@ -10,24 +10,10 @@ export interface SceneSnapshot {
|
|
|
10
10
|
toOffset: number;
|
|
11
11
|
toIsPercentage: boolean;
|
|
12
12
|
}>;
|
|
13
|
-
vehicles: Array<{
|
|
14
|
-
id: string;
|
|
15
|
-
lineId: string;
|
|
16
|
-
axles: Array<{
|
|
17
|
-
offset: number;
|
|
18
|
-
}>;
|
|
19
|
-
axleSpacings: number[];
|
|
20
|
-
isPercentage: boolean;
|
|
21
|
-
}>;
|
|
22
13
|
}
|
|
23
14
|
/**
|
|
24
|
-
* Serialize scene state to a JSON string
|
|
25
|
-
*
|
|
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.
|
|
15
|
+
* Serialize scene state (lines + curves) to a JSON string.
|
|
16
|
+
* Vehicles are NOT included — vehicle persistence is the client's responsibility.
|
|
31
17
|
*/
|
|
32
18
|
export declare function serializeScene(lines: Line[], curves: Array<{
|
|
33
19
|
id: string;
|
|
@@ -37,18 +23,10 @@ export declare function serializeScene(lines: Line[], curves: Array<{
|
|
|
37
23
|
fromIsPercentage?: boolean;
|
|
38
24
|
toOffset: number;
|
|
39
25
|
toIsPercentage?: boolean;
|
|
40
|
-
}>, vehicles: Array<{
|
|
41
|
-
id: string;
|
|
42
|
-
axles: Array<{
|
|
43
|
-
lineId: string;
|
|
44
|
-
offset: number;
|
|
45
|
-
[key: string]: unknown;
|
|
46
|
-
}>;
|
|
47
|
-
axleSpacings: number[];
|
|
48
|
-
isPercentage?: boolean;
|
|
49
26
|
}>): string;
|
|
50
27
|
/**
|
|
51
28
|
* Deserialize a JSON string back into a SceneSnapshot.
|
|
52
|
-
* Throws if the string is not valid JSON or missing required fields.
|
|
29
|
+
* Throws if the string is not valid JSON or missing required fields (lines, curves).
|
|
30
|
+
* Extra fields in the JSON (e.g. legacy "vehicles") are silently ignored.
|
|
53
31
|
*/
|
|
54
32
|
export declare function deserializeScene(json: string): SceneSnapshot;
|
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
* Vehicle-related types
|
|
3
3
|
*/
|
|
4
4
|
import type { Point } from './geometry';
|
|
5
|
+
/**
|
|
6
|
+
* Base definition of a vehicle's physical structure.
|
|
7
|
+
* Client code is free to extend this with additional fields (id, name, color, etc).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* interface MyVehicle extends VehicleDefinition { id: string; name: string }
|
|
11
|
+
*/
|
|
12
|
+
export interface VehicleDefinition {
|
|
13
|
+
/** N-1 arc-length spacings between consecutive axles. axleSpacings[i] = distance from axles[i] to axles[i+1]. */
|
|
14
|
+
axleSpacings: number[];
|
|
15
|
+
}
|
|
5
16
|
/**
|
|
6
17
|
* Animation state for a vehicle
|
|
7
18
|
*/
|
|
@@ -28,14 +39,13 @@ export interface AxleState {
|
|
|
28
39
|
/**
|
|
29
40
|
* Vehicle with runtime state (used during animation)
|
|
30
41
|
*/
|
|
31
|
-
export interface Vehicle {
|
|
42
|
+
export interface Vehicle extends VehicleDefinition {
|
|
32
43
|
id: string;
|
|
33
44
|
lineId: string;
|
|
34
45
|
offset: number;
|
|
35
46
|
isPercentage: boolean;
|
|
36
47
|
state: VehicleState;
|
|
37
48
|
axles: AxleState[];
|
|
38
|
-
axleSpacings: number[];
|
|
39
49
|
}
|
|
40
50
|
/**
|
|
41
51
|
* Command to move a vehicle to a target position
|
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-C4FckUel.cjs");function f(r,n){const i={lines:r,curves:n.map(t=>({id:t.id,fromLineId:t.fromLineId,toLineId:t.toLineId,fromOffset:t.fromOffset,fromIsPercentage:t.fromIsPercentage??!1,toOffset:t.toOffset,toIsPercentage:t.toIsPercentage??!1}))};return JSON.stringify(i,null,2)}function g(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 i=n;if(!Array.isArray(i.lines))throw new Error('deserializeScene: missing "lines"');if(!Array.isArray(i.curves))throw new Error('deserializeScene: missing "curves"');return{lines:i.lines,curves:i.curves}}function u(r,n){const i=n.end.x-n.start.x,t=n.end.y-n.start.y,o=i*i+t*t;if(o===0)return{offset:0,distance:Math.sqrt((r.x-n.start.x)**2+(r.y-n.start.y)**2)};const a=Math.max(0,Math.min(1,((r.x-n.start.x)*i+(r.y-n.start.y)*t)/o)),s=n.start.x+a*i,c=n.start.y+a*t,l=Math.sqrt((r.x-s)**2+(r.y-c)**2);return{offset:a*Math.sqrt(o),distance:l}}function h(r,n){const i=e.getLineLength(r),t=n.reduce((a,s)=>a+s,0);return[0,Math.max(0,i-t)]}function d(r,n){let i=0;for(const t of n)t.fromLineId===r&&!t.fromIsPercentage&&t.fromOffset!==void 0&&(i=Math.max(i,t.fromOffset)),t.toLineId===r&&!t.toIsPercentage&&t.toOffset!==void 0&&(i=Math.max(i,t.toOffset));return i}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.computeMinLineLength=d;exports.deserializeScene=g;exports.getValidRearOffsetRange=h;exports.projectPointOnLine=u;exports.serializeScene=f;
|
package/dist/core.js
CHANGED
|
@@ -1,86 +1,77 @@
|
|
|
1
|
-
import { g as f } from "./index-
|
|
2
|
-
import { P as y, a as v, b as A, c as
|
|
3
|
-
function
|
|
4
|
-
const
|
|
5
|
-
lines:
|
|
6
|
-
curves:
|
|
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
|
|
1
|
+
import { g as f } from "./index-BV93143R.js";
|
|
2
|
+
import { P as y, a as v, b as A, c as S, d as p, e as z, f as I, h as M, i as w, j as b, k as j, l as E, m as T, n as q, o as B, p as C, q as N, r as J, s as V, t as F, u as R, v as k, w as D, x as G, y as X, z as Y, A as H, B as K, C as Q, D as U, E as W } from "./index-BV93143R.js";
|
|
3
|
+
function u(a, t) {
|
|
4
|
+
const s = {
|
|
5
|
+
lines: a,
|
|
6
|
+
curves: t.map((e) => ({
|
|
7
|
+
id: e.id,
|
|
8
|
+
fromLineId: e.fromLineId,
|
|
9
|
+
toLineId: e.toLineId,
|
|
10
|
+
fromOffset: e.fromOffset,
|
|
11
|
+
fromIsPercentage: e.fromIsPercentage ?? !1,
|
|
12
|
+
toOffset: e.toOffset,
|
|
13
|
+
toIsPercentage: e.toIsPercentage ?? !1
|
|
21
14
|
}))
|
|
22
15
|
};
|
|
23
|
-
return JSON.stringify(
|
|
16
|
+
return JSON.stringify(s, null, 2);
|
|
24
17
|
}
|
|
25
|
-
function
|
|
26
|
-
let
|
|
18
|
+
function g(a) {
|
|
19
|
+
let t;
|
|
27
20
|
try {
|
|
28
|
-
|
|
21
|
+
t = JSON.parse(a);
|
|
29
22
|
} catch {
|
|
30
23
|
throw new Error("deserializeScene: invalid JSON");
|
|
31
24
|
}
|
|
32
|
-
if (!
|
|
25
|
+
if (!t || typeof t != "object" || Array.isArray(t))
|
|
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 s = t;
|
|
28
|
+
if (!Array.isArray(s.lines)) throw new Error('deserializeScene: missing "lines"');
|
|
29
|
+
if (!Array.isArray(s.curves)) throw new Error('deserializeScene: missing "curves"');
|
|
38
30
|
return {
|
|
39
|
-
lines:
|
|
40
|
-
curves:
|
|
41
|
-
vehicles: t.vehicles
|
|
31
|
+
lines: s.lines,
|
|
32
|
+
curves: s.curves
|
|
42
33
|
};
|
|
43
34
|
}
|
|
44
|
-
function
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
35
|
+
function h(a, t) {
|
|
36
|
+
const s = t.end.x - t.start.x, e = t.end.y - t.start.y, n = s * s + e * e;
|
|
37
|
+
if (n === 0)
|
|
47
38
|
return { offset: 0, distance: Math.sqrt(
|
|
48
|
-
(
|
|
39
|
+
(a.x - t.start.x) ** 2 + (a.y - t.start.y) ** 2
|
|
49
40
|
) };
|
|
50
|
-
const
|
|
41
|
+
const r = Math.max(
|
|
51
42
|
0,
|
|
52
43
|
Math.min(
|
|
53
44
|
1,
|
|
54
|
-
((
|
|
45
|
+
((a.x - t.start.x) * s + (a.y - t.start.y) * e) / n
|
|
55
46
|
)
|
|
56
|
-
), i =
|
|
57
|
-
return { offset:
|
|
47
|
+
), i = t.start.x + r * s, o = t.start.y + r * e, c = Math.sqrt((a.x - i) ** 2 + (a.y - o) ** 2);
|
|
48
|
+
return { offset: r * Math.sqrt(n), distance: c };
|
|
58
49
|
}
|
|
59
|
-
function
|
|
60
|
-
const
|
|
61
|
-
return [0, Math.max(0,
|
|
50
|
+
function L(a, t) {
|
|
51
|
+
const s = f(a), e = t.reduce((r, i) => r + i, 0);
|
|
52
|
+
return [0, Math.max(0, s - e)];
|
|
62
53
|
}
|
|
63
|
-
function
|
|
64
|
-
let
|
|
65
|
-
for (const
|
|
66
|
-
|
|
67
|
-
return
|
|
54
|
+
function O(a, t) {
|
|
55
|
+
let s = 0;
|
|
56
|
+
for (const e of t)
|
|
57
|
+
e.fromLineId === a && !e.fromIsPercentage && e.fromOffset !== void 0 && (s = Math.max(s, e.fromOffset)), e.toLineId === a && !e.toIsPercentage && e.toOffset !== void 0 && (s = Math.max(s, e.toOffset));
|
|
58
|
+
return s;
|
|
68
59
|
}
|
|
69
60
|
export {
|
|
70
61
|
y as PathEngine,
|
|
71
62
|
v as arcLengthToSegmentPosition,
|
|
72
63
|
A as buildArcLengthTable,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
S as buildGraph,
|
|
65
|
+
p as calculateBezierArcLength,
|
|
66
|
+
z as calculateFrontAxlePosition,
|
|
67
|
+
I as calculateInitialAxlePositions,
|
|
68
|
+
M as calculatePositionOnCurve,
|
|
69
|
+
w as calculatePositionOnLine,
|
|
79
70
|
b as calculateTangentLength,
|
|
80
|
-
|
|
71
|
+
O as computeMinLineLength,
|
|
81
72
|
j as createBezierCurve,
|
|
82
73
|
E as createInitialMovementState,
|
|
83
|
-
|
|
74
|
+
g as deserializeScene,
|
|
84
75
|
T as distance,
|
|
85
76
|
q as distanceToT,
|
|
86
77
|
B as findPath,
|
|
@@ -91,7 +82,7 @@ export {
|
|
|
91
82
|
V as getPointOnLine,
|
|
92
83
|
F as getPointOnLineByOffset,
|
|
93
84
|
R as getPositionFromOffset,
|
|
94
|
-
|
|
85
|
+
L as getValidRearOffsetRange,
|
|
95
86
|
k as handleArrival,
|
|
96
87
|
D as initializeAllVehicles,
|
|
97
88
|
G as initializeMovingVehicle,
|
|
@@ -99,9 +90,9 @@ export {
|
|
|
99
90
|
Y as moveVehicle,
|
|
100
91
|
H as normalize,
|
|
101
92
|
K as prepareCommandPath,
|
|
102
|
-
|
|
93
|
+
h as projectPointOnLine,
|
|
103
94
|
Q as resolveFromLineOffset,
|
|
104
95
|
U as resolveToLineOffset,
|
|
105
|
-
|
|
96
|
+
u as serializeScene,
|
|
106
97
|
W as updateAxlePosition
|
|
107
98
|
};
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
function y(t, e) {
|
|
2
|
-
const
|
|
3
|
-
return Math.sqrt(
|
|
2
|
+
const n = e.x - t.x, s = e.y - t.y;
|
|
3
|
+
return Math.sqrt(n * n + s * s);
|
|
4
4
|
}
|
|
5
|
-
function
|
|
6
|
-
const
|
|
7
|
-
return
|
|
5
|
+
function S(t, e) {
|
|
6
|
+
const n = e.x - t.x, s = e.y - t.y, i = Math.sqrt(n * n + s * s);
|
|
7
|
+
return i === 0 ? { x: 0, y: 0 } : { x: n / i, y: s / i };
|
|
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: o, tangentMode: a } =
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
const l =
|
|
12
|
+
function W(t, e, n, s = !1, i) {
|
|
13
|
+
const { maxWheelbase: o, tangentMode: a } = n;
|
|
14
|
+
let r;
|
|
15
|
+
i?.fromOffset !== void 0 ? r = V(t, i.fromOffset, i.fromIsPercentage ?? !1) : r = t.end;
|
|
16
|
+
let f;
|
|
17
|
+
i?.toOffset !== void 0 ? f = V(e, i.toOffset, i.toIsPercentage ?? !1) : f = e.start;
|
|
18
|
+
const l = S(t.start, t.end), c = s ? {
|
|
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: r.x - l.x * o,
|
|
21
|
+
y: r.y - l.y * o
|
|
22
|
+
} : r, g = S(t.start, t.end), d = S(e.start, e.end), h = y(c, f), p = k(a, h), u = s ? { x: c.x - g.x * p, y: c.y - g.y * p } : { x: c.x + g.x * p, y: c.y + g.y * p }, v = {
|
|
23
|
+
x: f.x - d.x * p,
|
|
24
|
+
y: f.y - d.y * p
|
|
25
25
|
};
|
|
26
|
-
return { p0:
|
|
26
|
+
return { p0: c, p1: u, p2: v, p3: f };
|
|
27
27
|
}
|
|
28
28
|
function K(t, e) {
|
|
29
29
|
return {
|
|
@@ -31,78 +31,78 @@ function K(t, e) {
|
|
|
31
31
|
y: t.start.y + (t.end.y - t.start.y) * e
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
-
function V(t, e,
|
|
35
|
-
const
|
|
36
|
-
let
|
|
37
|
-
return
|
|
34
|
+
function V(t, e, n) {
|
|
35
|
+
const s = y(t.start, t.end);
|
|
36
|
+
let i;
|
|
37
|
+
return n ? i = e : i = s > 0 ? e / s : 0, i = Math.max(0, Math.min(1, i)), K(t, i);
|
|
38
38
|
}
|
|
39
39
|
function b(t, e) {
|
|
40
|
-
const { p0:
|
|
40
|
+
const { p0: n, p1: s, p2: i, p3: o } = t, a = 1 - e, r = a * a, f = r * a, l = e * e, c = l * e;
|
|
41
41
|
return {
|
|
42
|
-
x:
|
|
43
|
-
y:
|
|
42
|
+
x: f * n.x + 3 * r * e * s.x + 3 * a * l * i.x + c * o.x,
|
|
43
|
+
y: f * n.y + 3 * r * e * s.y + 3 * a * l * i.y + c * o.y
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
-
function ne(t, e,
|
|
47
|
-
return y(t, e) <=
|
|
46
|
+
function ne(t, e, n = 10) {
|
|
47
|
+
return y(t, e) <= n;
|
|
48
48
|
}
|
|
49
49
|
function N(t, e = 100) {
|
|
50
|
-
const
|
|
51
|
-
let
|
|
50
|
+
const n = [{ t: 0, distance: 0 }];
|
|
51
|
+
let s = t.p0, i = 0;
|
|
52
52
|
for (let o = 1; o <= e; o++) {
|
|
53
|
-
const a = o / e,
|
|
54
|
-
|
|
53
|
+
const a = o / e, r = b(t, a);
|
|
54
|
+
i += y(s, r), n.push({ t: a, distance: i }), s = r;
|
|
55
55
|
}
|
|
56
|
-
return
|
|
56
|
+
return n;
|
|
57
57
|
}
|
|
58
58
|
function _(t, e) {
|
|
59
59
|
if (e <= 0) return 0;
|
|
60
|
-
const
|
|
61
|
-
if (e >=
|
|
62
|
-
let
|
|
63
|
-
for (;
|
|
64
|
-
const
|
|
65
|
-
t[
|
|
60
|
+
const n = t[t.length - 1].distance;
|
|
61
|
+
if (e >= n) return 1;
|
|
62
|
+
let s = 0, i = t.length - 1;
|
|
63
|
+
for (; s < i - 1; ) {
|
|
64
|
+
const c = Math.floor((s + i) / 2);
|
|
65
|
+
t[c].distance < e ? s = c : i = c;
|
|
66
66
|
}
|
|
67
|
-
const o = t[
|
|
68
|
-
if (a === o) return
|
|
67
|
+
const o = t[s].distance, a = t[i].distance, r = t[s].t, f = t[i].t;
|
|
68
|
+
if (a === o) return r;
|
|
69
69
|
const l = (e - o) / (a - o);
|
|
70
|
-
return
|
|
70
|
+
return r + l * (f - r);
|
|
71
71
|
}
|
|
72
72
|
function se(t) {
|
|
73
73
|
return t[t.length - 1].distance;
|
|
74
74
|
}
|
|
75
75
|
function F(t, e = 100) {
|
|
76
|
-
let
|
|
77
|
-
for (let
|
|
78
|
-
const o =
|
|
79
|
-
|
|
76
|
+
let n = 0, s = t.p0;
|
|
77
|
+
for (let i = 1; i <= e; i++) {
|
|
78
|
+
const o = i / e, a = b(t, o);
|
|
79
|
+
n += y(s, a), s = a;
|
|
80
80
|
}
|
|
81
|
-
return
|
|
81
|
+
return n;
|
|
82
82
|
}
|
|
83
|
-
function q(t, e,
|
|
83
|
+
function q(t, e, n, s, i) {
|
|
84
84
|
const o = y(t.start, t.end);
|
|
85
|
-
return e === void 0 ?
|
|
85
|
+
return e === void 0 ? s * o : n ? Math.max(0, Math.min(e, 1)) * o : Math.max(0, Math.min(e, o));
|
|
86
86
|
}
|
|
87
|
-
function E(t, e,
|
|
87
|
+
function E(t, e, n, s, i) {
|
|
88
88
|
const o = y(t.start, t.end);
|
|
89
|
-
return e === void 0 ?
|
|
89
|
+
return e === void 0 ? s * o : n ? Math.max(0, Math.min(e, 1)) * o : Math.max(0, Math.min(e, o));
|
|
90
90
|
}
|
|
91
|
-
function I(t, e,
|
|
92
|
-
const
|
|
91
|
+
function I(t, e, n) {
|
|
92
|
+
const s = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
|
|
93
93
|
for (const a of t)
|
|
94
|
-
|
|
94
|
+
i.set(a.id, a), o.set(a.id, y(a.start, a.end)), s.set(a.id, []);
|
|
95
95
|
for (let a = 0; a < e.length; a++) {
|
|
96
|
-
const
|
|
97
|
-
if (!
|
|
98
|
-
const
|
|
99
|
-
|
|
96
|
+
const r = e[a], f = i.get(r.fromLineId), l = i.get(r.toLineId);
|
|
97
|
+
if (!f || !l) continue;
|
|
98
|
+
const c = q(f, r.fromOffset, r.fromIsPercentage, 1, n.maxWheelbase), g = E(l, r.toOffset, r.toIsPercentage, 0, n.maxWheelbase), d = W(
|
|
99
|
+
f,
|
|
100
100
|
l,
|
|
101
|
-
|
|
101
|
+
n,
|
|
102
102
|
!1,
|
|
103
103
|
// willFlip is always false now
|
|
104
104
|
{
|
|
105
|
-
fromOffset:
|
|
105
|
+
fromOffset: c,
|
|
106
106
|
fromIsPercentage: !1,
|
|
107
107
|
// Already resolved to absolute
|
|
108
108
|
toOffset: g,
|
|
@@ -111,31 +111,31 @@ function I(t, e, s) {
|
|
|
111
111
|
}
|
|
112
112
|
), h = F(d), p = {
|
|
113
113
|
curveIndex: a,
|
|
114
|
-
fromLineId:
|
|
115
|
-
toLineId:
|
|
116
|
-
fromOffset:
|
|
114
|
+
fromLineId: r.fromLineId,
|
|
115
|
+
toLineId: r.toLineId,
|
|
116
|
+
fromOffset: c,
|
|
117
117
|
toOffset: g,
|
|
118
118
|
curveLength: h
|
|
119
119
|
};
|
|
120
|
-
|
|
120
|
+
s.get(r.fromLineId).push(p);
|
|
121
121
|
}
|
|
122
|
-
return { adjacency:
|
|
122
|
+
return { adjacency: s, lines: i, lineLengths: o };
|
|
123
123
|
}
|
|
124
|
-
function
|
|
124
|
+
function z(t, e) {
|
|
125
125
|
return t.curveCount !== e.curveCount ? t.curveCount - e.curveCount : t.totalDistance - e.totalDistance;
|
|
126
126
|
}
|
|
127
|
-
function G(t, e,
|
|
128
|
-
const { adjacency: o, lines: a, lineLengths:
|
|
129
|
-
if (!a.get(
|
|
130
|
-
const l =
|
|
131
|
-
if (e.lineId ===
|
|
132
|
-
const u =
|
|
127
|
+
function G(t, e, n, s, i = !1) {
|
|
128
|
+
const { adjacency: o, lines: a, lineLengths: r } = t;
|
|
129
|
+
if (!a.get(n)) return null;
|
|
130
|
+
const l = r.get(n), c = i ? s / 100 * l : s, g = [], d = /* @__PURE__ */ new Map(), h = (u, v) => `${u}:${Math.round(v)}`;
|
|
131
|
+
if (e.lineId === n && c >= e.offset) {
|
|
132
|
+
const u = c - e.offset;
|
|
133
133
|
return {
|
|
134
134
|
segments: [{
|
|
135
135
|
type: "line",
|
|
136
136
|
lineId: e.lineId,
|
|
137
137
|
startOffset: e.offset,
|
|
138
|
-
endOffset:
|
|
138
|
+
endOffset: c,
|
|
139
139
|
length: u
|
|
140
140
|
}],
|
|
141
141
|
totalDistance: u,
|
|
@@ -166,18 +166,18 @@ function G(t, e, s, n, r = !1) {
|
|
|
166
166
|
path: [L, m]
|
|
167
167
|
});
|
|
168
168
|
}
|
|
169
|
-
for (g.sort(
|
|
169
|
+
for (g.sort(z); g.length > 0; ) {
|
|
170
170
|
const u = g.shift(), v = h(u.lineId, u.entryOffset), x = d.get(v);
|
|
171
171
|
if (x !== void 0 && (x.curveCount < u.curveCount || x.curveCount === u.curveCount && x.distance <= u.totalDistance))
|
|
172
172
|
continue;
|
|
173
|
-
if (d.set(v, { curveCount: u.curveCount, distance: u.totalDistance }), u.lineId ===
|
|
174
|
-
const m = Math.abs(
|
|
175
|
-
if (
|
|
173
|
+
if (d.set(v, { curveCount: u.curveCount, distance: u.totalDistance }), u.lineId === n) {
|
|
174
|
+
const m = Math.abs(c - u.entryOffset);
|
|
175
|
+
if (c >= u.entryOffset) {
|
|
176
176
|
const C = {
|
|
177
177
|
type: "line",
|
|
178
|
-
lineId:
|
|
178
|
+
lineId: n,
|
|
179
179
|
startOffset: u.entryOffset,
|
|
180
|
-
endOffset:
|
|
180
|
+
endOffset: c,
|
|
181
181
|
length: m
|
|
182
182
|
};
|
|
183
183
|
return {
|
|
@@ -214,17 +214,17 @@ function G(t, e, s, n, r = !1) {
|
|
|
214
214
|
path: [...u.path, j, $]
|
|
215
215
|
});
|
|
216
216
|
}
|
|
217
|
-
g.sort(
|
|
217
|
+
g.sort(z);
|
|
218
218
|
}
|
|
219
219
|
return null;
|
|
220
220
|
}
|
|
221
221
|
function A(t, e) {
|
|
222
|
-
const
|
|
222
|
+
const n = Math.sqrt(
|
|
223
223
|
Math.pow(t.end.x - t.start.x, 2) + Math.pow(t.end.y - t.start.y, 2)
|
|
224
|
-
),
|
|
224
|
+
), s = n > 0 ? e / n : 0;
|
|
225
225
|
return {
|
|
226
|
-
x: t.start.x + (t.end.x - t.start.x) * Math.min(1, Math.max(0,
|
|
227
|
-
y: t.start.y + (t.end.y - t.start.y) * Math.min(1, Math.max(0,
|
|
226
|
+
x: t.start.x + (t.end.x - t.start.x) * Math.min(1, Math.max(0, s)),
|
|
227
|
+
y: t.start.y + (t.end.y - t.start.y) * Math.min(1, Math.max(0, s))
|
|
228
228
|
};
|
|
229
229
|
}
|
|
230
230
|
function O(t) {
|
|
@@ -232,54 +232,54 @@ function O(t) {
|
|
|
232
232
|
Math.pow(t.end.x - t.start.x, 2) + Math.pow(t.end.y - t.start.y, 2)
|
|
233
233
|
);
|
|
234
234
|
}
|
|
235
|
-
function Q(t, e,
|
|
236
|
-
let
|
|
237
|
-
for (let
|
|
238
|
-
|
|
239
|
-
return
|
|
235
|
+
function Q(t, e, n) {
|
|
236
|
+
let s = 0;
|
|
237
|
+
for (let i = 0; i < e; i++)
|
|
238
|
+
s += t.segments[i].length;
|
|
239
|
+
return s += n, s;
|
|
240
240
|
}
|
|
241
241
|
function R(t, e) {
|
|
242
|
-
let
|
|
243
|
-
for (let
|
|
244
|
-
const
|
|
242
|
+
let n = 0;
|
|
243
|
+
for (let s = 0; s < t.segments.length; s++) {
|
|
244
|
+
const i = t.segments[s], o = n + i.length;
|
|
245
245
|
if (e < o)
|
|
246
246
|
return {
|
|
247
|
-
segmentIndex:
|
|
248
|
-
segmentDistance: e -
|
|
247
|
+
segmentIndex: s,
|
|
248
|
+
segmentDistance: e - n
|
|
249
249
|
};
|
|
250
250
|
if (e === o)
|
|
251
|
-
return
|
|
252
|
-
segmentIndex:
|
|
251
|
+
return s + 1 < t.segments.length ? {
|
|
252
|
+
segmentIndex: s + 1,
|
|
253
253
|
segmentDistance: 0
|
|
254
254
|
} : {
|
|
255
|
-
segmentIndex:
|
|
256
|
-
segmentDistance:
|
|
255
|
+
segmentIndex: s,
|
|
256
|
+
segmentDistance: i.length
|
|
257
257
|
};
|
|
258
|
-
|
|
258
|
+
n += i.length;
|
|
259
259
|
}
|
|
260
260
|
return null;
|
|
261
261
|
}
|
|
262
|
-
function
|
|
262
|
+
function ie(t, e, n, s) {
|
|
263
263
|
const o = Q(
|
|
264
264
|
t,
|
|
265
265
|
e,
|
|
266
|
-
|
|
267
|
-
) +
|
|
266
|
+
n
|
|
267
|
+
) + s;
|
|
268
268
|
return R(t, o);
|
|
269
269
|
}
|
|
270
|
-
function H(t, e,
|
|
271
|
-
const
|
|
270
|
+
function H(t, e, n, s) {
|
|
271
|
+
const i = O(s), o = n.length + 1, a = new Array(o);
|
|
272
272
|
a[o - 1] = {
|
|
273
273
|
lineId: t,
|
|
274
274
|
absoluteOffset: e,
|
|
275
|
-
position: A(
|
|
275
|
+
position: A(s, e)
|
|
276
276
|
};
|
|
277
|
-
let
|
|
278
|
-
for (let
|
|
279
|
-
|
|
277
|
+
let r = e;
|
|
278
|
+
for (let f = o - 2; f >= 0; f--)
|
|
279
|
+
r = Math.min(r + n[f], i), a[f] = {
|
|
280
280
|
lineId: t,
|
|
281
|
-
absoluteOffset:
|
|
282
|
-
position: A(
|
|
281
|
+
absoluteOffset: r,
|
|
282
|
+
position: A(s, r)
|
|
283
283
|
};
|
|
284
284
|
return a;
|
|
285
285
|
}
|
|
@@ -295,183 +295,183 @@ function U(t) {
|
|
|
295
295
|
execution: null
|
|
296
296
|
};
|
|
297
297
|
}
|
|
298
|
-
function
|
|
299
|
-
const
|
|
300
|
-
for (const
|
|
301
|
-
if (!e.get(
|
|
302
|
-
const a = J(
|
|
303
|
-
|
|
304
|
-
const
|
|
305
|
-
|
|
298
|
+
function re(t, e) {
|
|
299
|
+
const n = [], s = /* @__PURE__ */ new Map();
|
|
300
|
+
for (const i of t) {
|
|
301
|
+
if (!e.get(i.lineId)) continue;
|
|
302
|
+
const a = J(i);
|
|
303
|
+
n.push(a);
|
|
304
|
+
const r = U(a);
|
|
305
|
+
s.set(i.id, r);
|
|
306
306
|
}
|
|
307
|
-
return { movingVehicles:
|
|
307
|
+
return { movingVehicles: n, stateMap: s };
|
|
308
308
|
}
|
|
309
309
|
function M(t, e) {
|
|
310
310
|
return { position: A(t, e), lineId: t.id, absoluteOffset: e };
|
|
311
311
|
}
|
|
312
|
-
function
|
|
313
|
-
const
|
|
314
|
-
return { position: b(t.bezier,
|
|
315
|
-
}
|
|
316
|
-
function X(t, e,
|
|
317
|
-
const
|
|
318
|
-
if (
|
|
319
|
-
const
|
|
320
|
-
if (g >=
|
|
321
|
-
if (a !== void 0 &&
|
|
322
|
-
const u =
|
|
312
|
+
function w(t, e) {
|
|
313
|
+
const n = _(t.arcLengthTable, e);
|
|
314
|
+
return { position: b(t.bezier, n) };
|
|
315
|
+
}
|
|
316
|
+
function X(t, e, n, s, i, o, a) {
|
|
317
|
+
const r = n.segments[e.currentSegmentIndex], f = e.segmentDistance + s;
|
|
318
|
+
if (f >= r.length) {
|
|
319
|
+
const c = f - r.length, g = e.currentSegmentIndex + 1;
|
|
320
|
+
if (g >= n.segments.length) {
|
|
321
|
+
if (a !== void 0 && r.type === "line") {
|
|
322
|
+
const u = i.get(r.lineId), v = r.startOffset + f;
|
|
323
323
|
if (v <= a) {
|
|
324
324
|
const L = M(u, v);
|
|
325
325
|
return {
|
|
326
326
|
axleState: { ...t, ...L },
|
|
327
|
-
execution: { ...e, segmentDistance:
|
|
327
|
+
execution: { ...e, segmentDistance: f },
|
|
328
328
|
completed: !1
|
|
329
329
|
};
|
|
330
330
|
}
|
|
331
331
|
const x = M(u, a);
|
|
332
332
|
return {
|
|
333
333
|
axleState: { ...t, ...x },
|
|
334
|
-
execution: { ...e, segmentDistance: a -
|
|
334
|
+
execution: { ...e, segmentDistance: a - r.startOffset },
|
|
335
335
|
completed: !0
|
|
336
336
|
};
|
|
337
337
|
}
|
|
338
|
-
const p =
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
) :
|
|
342
|
-
o.get(
|
|
343
|
-
|
|
338
|
+
const p = r.type === "line" ? M(
|
|
339
|
+
i.get(r.lineId),
|
|
340
|
+
r.endOffset
|
|
341
|
+
) : w(
|
|
342
|
+
o.get(r.curveIndex),
|
|
343
|
+
r.length
|
|
344
344
|
);
|
|
345
345
|
return {
|
|
346
346
|
axleState: { ...t, ...p },
|
|
347
|
-
execution: { ...e, segmentDistance:
|
|
347
|
+
execution: { ...e, segmentDistance: r.length },
|
|
348
348
|
completed: !0
|
|
349
349
|
};
|
|
350
350
|
}
|
|
351
|
-
const d =
|
|
352
|
-
|
|
353
|
-
d.startOffset +
|
|
354
|
-
) :
|
|
351
|
+
const d = n.segments[g], h = d.type === "line" ? M(
|
|
352
|
+
i.get(d.lineId),
|
|
353
|
+
d.startOffset + c
|
|
354
|
+
) : w(
|
|
355
355
|
o.get(d.curveIndex),
|
|
356
|
-
|
|
356
|
+
c
|
|
357
357
|
);
|
|
358
358
|
return {
|
|
359
359
|
axleState: { ...t, ...h },
|
|
360
360
|
execution: {
|
|
361
361
|
currentSegmentIndex: g,
|
|
362
|
-
segmentDistance:
|
|
362
|
+
segmentDistance: c
|
|
363
363
|
},
|
|
364
364
|
completed: !1
|
|
365
365
|
};
|
|
366
366
|
}
|
|
367
|
-
const l =
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
) :
|
|
371
|
-
o.get(
|
|
372
|
-
|
|
367
|
+
const l = r.type === "line" ? M(
|
|
368
|
+
i.get(r.lineId),
|
|
369
|
+
r.startOffset + f
|
|
370
|
+
) : w(
|
|
371
|
+
o.get(r.curveIndex),
|
|
372
|
+
f
|
|
373
373
|
);
|
|
374
374
|
return {
|
|
375
375
|
axleState: { ...t, ...l },
|
|
376
|
-
execution: { ...e, segmentDistance:
|
|
376
|
+
execution: { ...e, segmentDistance: f },
|
|
377
377
|
completed: !1
|
|
378
378
|
};
|
|
379
379
|
}
|
|
380
|
-
function Y(t, e,
|
|
381
|
-
const
|
|
380
|
+
function Y(t, e, n, s) {
|
|
381
|
+
const i = /* @__PURE__ */ new Map();
|
|
382
382
|
for (const o of t.segments)
|
|
383
383
|
if (o.type === "curve" && o.curveIndex !== void 0) {
|
|
384
384
|
const a = e[o.curveIndex];
|
|
385
385
|
if (a) {
|
|
386
|
-
const
|
|
387
|
-
if (
|
|
386
|
+
const r = n.get(a.fromLineId), f = n.get(a.toLineId);
|
|
387
|
+
if (r && f) {
|
|
388
388
|
const l = q(
|
|
389
|
-
|
|
389
|
+
r,
|
|
390
390
|
a.fromOffset,
|
|
391
391
|
a.fromIsPercentage,
|
|
392
392
|
1,
|
|
393
393
|
// Default: 100% = 1.0
|
|
394
|
-
|
|
395
|
-
),
|
|
396
|
-
|
|
394
|
+
s.maxWheelbase
|
|
395
|
+
), c = E(
|
|
396
|
+
f,
|
|
397
397
|
a.toOffset,
|
|
398
398
|
a.toIsPercentage,
|
|
399
399
|
0,
|
|
400
|
-
|
|
401
|
-
), g =
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
400
|
+
s.maxWheelbase
|
|
401
|
+
), g = W(
|
|
402
|
+
r,
|
|
403
|
+
f,
|
|
404
|
+
s,
|
|
405
405
|
!1,
|
|
406
406
|
// willFlip is always false now
|
|
407
407
|
{
|
|
408
408
|
fromOffset: l,
|
|
409
409
|
fromIsPercentage: !1,
|
|
410
410
|
// Already resolved to absolute
|
|
411
|
-
toOffset:
|
|
411
|
+
toOffset: c,
|
|
412
412
|
toIsPercentage: !1
|
|
413
413
|
// Already resolved to absolute
|
|
414
414
|
}
|
|
415
415
|
), d = N(g);
|
|
416
|
-
|
|
416
|
+
i.set(o.curveIndex, { bezier: g, arcLengthTable: d });
|
|
417
417
|
}
|
|
418
418
|
}
|
|
419
419
|
}
|
|
420
|
-
return
|
|
421
|
-
}
|
|
422
|
-
function Z(t, e,
|
|
423
|
-
const { graph:
|
|
424
|
-
if (!
|
|
425
|
-
const
|
|
426
|
-
if (
|
|
427
|
-
const g = e.isPercentage ? e.targetOffset *
|
|
428
|
-
|
|
420
|
+
return i;
|
|
421
|
+
}
|
|
422
|
+
function Z(t, e, n) {
|
|
423
|
+
const { graph: s, linesMap: i, curves: o, config: a } = n, r = i.get(e.targetLineId);
|
|
424
|
+
if (!r) return null;
|
|
425
|
+
const f = t.axleSpacings.reduce((u, v) => u + v, 0), c = O(r) - f;
|
|
426
|
+
if (c <= 0) return null;
|
|
427
|
+
const g = e.isPercentage ? e.targetOffset * c : Math.min(e.targetOffset, c), d = t.axles[t.axles.length - 1], h = G(
|
|
428
|
+
s,
|
|
429
429
|
{ lineId: d.lineId, offset: d.absoluteOffset },
|
|
430
430
|
e.targetLineId,
|
|
431
431
|
g,
|
|
432
432
|
!1
|
|
433
433
|
);
|
|
434
434
|
if (!h) return null;
|
|
435
|
-
const p = Y(h, o,
|
|
435
|
+
const p = Y(h, o, i, a);
|
|
436
436
|
return { path: h, curveDataMap: p };
|
|
437
437
|
}
|
|
438
438
|
function oe(t, e) {
|
|
439
|
-
const
|
|
440
|
-
return
|
|
439
|
+
const n = t.execution, i = e.vehicleQueues.get(t.vehicle.id)?.[n.currentCommandIndex];
|
|
440
|
+
return i && e.onCommandComplete && e.onCommandComplete({
|
|
441
441
|
vehicleId: t.vehicle.id,
|
|
442
|
-
command:
|
|
442
|
+
command: i,
|
|
443
443
|
finalPosition: {
|
|
444
444
|
lineId: t.vehicle.axles[t.vehicle.axles.length - 1].lineId,
|
|
445
445
|
absoluteOffset: t.vehicle.axles[t.vehicle.axles.length - 1].absoluteOffset,
|
|
446
446
|
position: t.vehicle.axles[t.vehicle.axles.length - 1].position
|
|
447
447
|
},
|
|
448
|
-
payload:
|
|
448
|
+
payload: i.payload
|
|
449
449
|
}), {
|
|
450
450
|
handled: !0,
|
|
451
451
|
vehicle: { ...t.vehicle, state: "waiting" },
|
|
452
|
-
newExecution:
|
|
452
|
+
newExecution: n,
|
|
453
453
|
// Keep execution state for resume
|
|
454
454
|
isWaiting: !0
|
|
455
455
|
};
|
|
456
456
|
}
|
|
457
|
-
function ee(t, e,
|
|
457
|
+
function ee(t, e, n, s, i, o) {
|
|
458
458
|
let a;
|
|
459
|
-
const
|
|
460
|
-
if (
|
|
461
|
-
const l =
|
|
459
|
+
const r = e[0];
|
|
460
|
+
if (r.currentSegmentIndex < n.segments.length) {
|
|
461
|
+
const l = n.segments[r.currentSegmentIndex];
|
|
462
462
|
if (l.type === "line") {
|
|
463
|
-
const
|
|
464
|
-
|
|
463
|
+
const c = i.get(l.lineId);
|
|
464
|
+
c && (a = O(c));
|
|
465
465
|
}
|
|
466
466
|
}
|
|
467
|
-
const
|
|
468
|
-
const g =
|
|
469
|
-
return X(l, e[
|
|
467
|
+
const f = t.map((l, c) => {
|
|
468
|
+
const g = c === 0 ? a : void 0;
|
|
469
|
+
return X(l, e[c], n, s, i, o, g);
|
|
470
470
|
});
|
|
471
471
|
return {
|
|
472
|
-
axles:
|
|
473
|
-
axleExecutions:
|
|
474
|
-
arrived:
|
|
472
|
+
axles: f.map((l) => l.axleState),
|
|
473
|
+
axleExecutions: f.map((l) => l.execution),
|
|
474
|
+
arrived: f[f.length - 1].completed
|
|
475
475
|
// axles[N-1] = rearmost menentukan arrived
|
|
476
476
|
};
|
|
477
477
|
}
|
|
@@ -504,11 +504,11 @@ class ae {
|
|
|
504
504
|
/**
|
|
505
505
|
* Replace the entire scene and rebuild the graph.
|
|
506
506
|
*/
|
|
507
|
-
setScene(e,
|
|
507
|
+
setScene(e, n) {
|
|
508
508
|
this.linesMap.clear();
|
|
509
|
-
for (const
|
|
510
|
-
this.linesMap.set(
|
|
511
|
-
this.curves =
|
|
509
|
+
for (const s of e)
|
|
510
|
+
this.linesMap.set(s.id, s);
|
|
511
|
+
this.curves = n, this.graph = I(e, n, this.config);
|
|
512
512
|
}
|
|
513
513
|
/**
|
|
514
514
|
* Add a single line. Returns false if a line with the same ID already exists.
|
|
@@ -519,36 +519,36 @@ class ae {
|
|
|
519
519
|
/**
|
|
520
520
|
* Update start and/or end coordinates of an existing line.
|
|
521
521
|
*/
|
|
522
|
-
updateLine(e,
|
|
523
|
-
const
|
|
524
|
-
return
|
|
522
|
+
updateLine(e, n) {
|
|
523
|
+
const s = this.linesMap.get(e);
|
|
524
|
+
return s ? (n.start && (s.start = n.start), n.end && (s.end = n.end), this.graph = I(Array.from(this.linesMap.values()), this.curves, this.config), !0) : !1;
|
|
525
525
|
}
|
|
526
526
|
/**
|
|
527
527
|
* Update a single endpoint ('start' or 'end') of a line.
|
|
528
528
|
*/
|
|
529
|
-
updateLineEndpoint(e,
|
|
530
|
-
return this.updateLine(e, { [
|
|
529
|
+
updateLineEndpoint(e, n, s) {
|
|
530
|
+
return this.updateLine(e, { [n]: s });
|
|
531
531
|
}
|
|
532
532
|
/**
|
|
533
533
|
* Rename a line ID and cascade the change to all connected curves.
|
|
534
534
|
*/
|
|
535
|
-
renameLine(e,
|
|
536
|
-
const
|
|
537
|
-
if (!
|
|
538
|
-
if (
|
|
539
|
-
if (this.linesMap.has(
|
|
540
|
-
const
|
|
541
|
-
if (!
|
|
542
|
-
|
|
535
|
+
renameLine(e, n) {
|
|
536
|
+
const s = n.trim();
|
|
537
|
+
if (!s) return { success: !1, error: "Name cannot be empty" };
|
|
538
|
+
if (s === e) return { success: !0 };
|
|
539
|
+
if (this.linesMap.has(s)) return { success: !1, error: `"${s}" already exists` };
|
|
540
|
+
const i = this.linesMap.get(e);
|
|
541
|
+
if (!i) return { success: !1, error: `Line "${e}" not found` };
|
|
542
|
+
i.id = s, this.linesMap.delete(e), this.linesMap.set(s, i);
|
|
543
543
|
for (const o of this.curves)
|
|
544
|
-
o.fromLineId === e && (o.fromLineId =
|
|
544
|
+
o.fromLineId === e && (o.fromLineId = s), o.toLineId === e && (o.toLineId = s);
|
|
545
545
|
return this.graph = I(Array.from(this.linesMap.values()), this.curves, this.config), { success: !0 };
|
|
546
546
|
}
|
|
547
547
|
/**
|
|
548
548
|
* Remove a line and all curves connected to it.
|
|
549
549
|
*/
|
|
550
550
|
removeLine(e) {
|
|
551
|
-
return this.linesMap.has(e) ? (this.linesMap.delete(e), this.curves = this.curves.filter((
|
|
551
|
+
return this.linesMap.has(e) ? (this.linesMap.delete(e), this.curves = this.curves.filter((n) => n.fromLineId !== e && n.toLineId !== e), this.graph = I(Array.from(this.linesMap.values()), this.curves, this.config), !0) : !1;
|
|
552
552
|
}
|
|
553
553
|
/**
|
|
554
554
|
* Add a directional curve (connection) from one line to another.
|
|
@@ -559,8 +559,8 @@ class ae {
|
|
|
559
559
|
/**
|
|
560
560
|
* Update a curve by index. Returns false if index is out of bounds.
|
|
561
561
|
*/
|
|
562
|
-
updateCurve(e,
|
|
563
|
-
return e < 0 || e >= this.curves.length ? !1 : (this.curves[e] = { ...this.curves[e], ...
|
|
562
|
+
updateCurve(e, n) {
|
|
563
|
+
return e < 0 || e >= this.curves.length ? !1 : (this.curves[e] = { ...this.curves[e], ...n }, this.graph = I(Array.from(this.linesMap.values()), this.curves, this.config), !0);
|
|
564
564
|
}
|
|
565
565
|
/**
|
|
566
566
|
* Remove a curve by index. Returns false if index is out of bounds.
|
|
@@ -576,16 +576,20 @@ class ae {
|
|
|
576
576
|
*
|
|
577
577
|
* @param lineId - The line to place the vehicle on
|
|
578
578
|
* @param rearOffset - Absolute distance offset untuk axle paling belakang
|
|
579
|
-
* @param
|
|
579
|
+
* @param vehicle - VehicleDefinition (or any object extending it with axleSpacings)
|
|
580
580
|
* @returns Initial VehiclePathState, or null if lineId does not exist
|
|
581
|
+
* @throws if axleSpacings is empty
|
|
581
582
|
*/
|
|
582
|
-
initializeVehicle(e,
|
|
583
|
-
const
|
|
584
|
-
if (!
|
|
585
|
-
const
|
|
583
|
+
initializeVehicle(e, n, s) {
|
|
584
|
+
const i = this.linesMap.get(e);
|
|
585
|
+
if (!i) return null;
|
|
586
|
+
const { axleSpacings: o } = s;
|
|
587
|
+
if (o.length === 0)
|
|
588
|
+
throw new Error("initializeVehicle: axleSpacings must have at least one entry (vehicle needs ≥2 axles)");
|
|
589
|
+
const a = o.reduce((c, g) => c + g, 0), r = O(i), f = Math.min(n, r - a);
|
|
586
590
|
return {
|
|
587
|
-
axles: H(e,
|
|
588
|
-
axleSpacings:
|
|
591
|
+
axles: H(e, f, o, i).map((c) => ({ lineId: c.lineId, offset: c.absoluteOffset, position: c.position })),
|
|
592
|
+
axleSpacings: o
|
|
589
593
|
};
|
|
590
594
|
}
|
|
591
595
|
/**
|
|
@@ -598,9 +602,9 @@ class ae {
|
|
|
598
602
|
* @param targetOffset - Position on the target line
|
|
599
603
|
* @param isPercentage - If true, targetOffset is 0-1 fraction; if false, absolute distance
|
|
600
604
|
*/
|
|
601
|
-
preparePath(e,
|
|
605
|
+
preparePath(e, n, s, i = !1) {
|
|
602
606
|
if (!this.graph) return null;
|
|
603
|
-
const o = e.axleSpacings.reduce((h, p) => h + p, 0), a = e.axles[e.axles.length - 1],
|
|
607
|
+
const o = e.axleSpacings.reduce((h, p) => h + p, 0), a = e.axles[e.axles.length - 1], r = {
|
|
604
608
|
lineId: a.lineId,
|
|
605
609
|
offset: a.offset,
|
|
606
610
|
axles: e.axles.map((h) => ({
|
|
@@ -609,22 +613,22 @@ class ae {
|
|
|
609
613
|
absoluteOffset: h.offset
|
|
610
614
|
})),
|
|
611
615
|
axleSpacings: e.axleSpacings
|
|
612
|
-
},
|
|
613
|
-
targetLineId:
|
|
614
|
-
targetOffset:
|
|
615
|
-
isPercentage:
|
|
616
|
+
}, f = Z(r, {
|
|
617
|
+
targetLineId: n,
|
|
618
|
+
targetOffset: s,
|
|
619
|
+
isPercentage: i
|
|
616
620
|
}, {
|
|
617
621
|
graph: this.graph,
|
|
618
622
|
linesMap: this.linesMap,
|
|
619
623
|
curves: this.curves,
|
|
620
624
|
config: this.config
|
|
621
625
|
});
|
|
622
|
-
if (!
|
|
623
|
-
let l =
|
|
624
|
-
const
|
|
625
|
-
if (
|
|
626
|
-
const h = Math.max(0, O(
|
|
627
|
-
l =
|
|
626
|
+
if (!f) return null;
|
|
627
|
+
let l = s;
|
|
628
|
+
const c = this.linesMap.get(n);
|
|
629
|
+
if (c) {
|
|
630
|
+
const h = Math.max(0, O(c) - o);
|
|
631
|
+
l = i ? s * h : Math.min(s, h);
|
|
628
632
|
}
|
|
629
633
|
let g = 0;
|
|
630
634
|
const d = [
|
|
@@ -634,10 +638,10 @@ class ae {
|
|
|
634
638
|
for (let h = 0; h < e.axleSpacings.length; h++)
|
|
635
639
|
g += e.axleSpacings[h], d.push({ segmentIndex: 0, segmentDistance: o - g });
|
|
636
640
|
return {
|
|
637
|
-
path:
|
|
638
|
-
curveDataMap:
|
|
641
|
+
path: f.path,
|
|
642
|
+
curveDataMap: f.curveDataMap,
|
|
639
643
|
axleExecutions: d,
|
|
640
|
-
targetLineId:
|
|
644
|
+
targetLineId: n,
|
|
641
645
|
targetOffset: l
|
|
642
646
|
};
|
|
643
647
|
}
|
|
@@ -651,25 +655,25 @@ class ae {
|
|
|
651
655
|
* @param execution - Current path execution (from preparePath or previous tick)
|
|
652
656
|
* @param distance - Distance to advance this tick (speed × deltaTime)
|
|
653
657
|
*/
|
|
654
|
-
moveVehicle(e,
|
|
655
|
-
const
|
|
656
|
-
lineId:
|
|
657
|
-
position:
|
|
658
|
-
absoluteOffset:
|
|
659
|
-
})), o =
|
|
660
|
-
currentSegmentIndex:
|
|
661
|
-
segmentDistance:
|
|
662
|
-
})), a = ee(
|
|
658
|
+
moveVehicle(e, n, s) {
|
|
659
|
+
const i = e.axles.map((r) => ({
|
|
660
|
+
lineId: r.lineId,
|
|
661
|
+
position: r.position,
|
|
662
|
+
absoluteOffset: r.offset
|
|
663
|
+
})), o = n.axleExecutions.map((r) => ({
|
|
664
|
+
currentSegmentIndex: r.segmentIndex,
|
|
665
|
+
segmentDistance: r.segmentDistance
|
|
666
|
+
})), a = ee(i, o, n.path, s, this.linesMap, n.curveDataMap);
|
|
663
667
|
return {
|
|
664
668
|
state: {
|
|
665
|
-
axles: a.axles.map((
|
|
669
|
+
axles: a.axles.map((r) => ({ lineId: r.lineId, offset: r.absoluteOffset, position: r.position })),
|
|
666
670
|
axleSpacings: e.axleSpacings
|
|
667
671
|
},
|
|
668
672
|
execution: {
|
|
669
|
-
...
|
|
670
|
-
axleExecutions: a.axleExecutions.map((
|
|
671
|
-
segmentIndex:
|
|
672
|
-
segmentDistance:
|
|
673
|
+
...n,
|
|
674
|
+
axleExecutions: a.axleExecutions.map((r) => ({
|
|
675
|
+
segmentIndex: r.currentSegmentIndex,
|
|
676
|
+
segmentDistance: r.segmentDistance
|
|
673
677
|
}))
|
|
674
678
|
},
|
|
675
679
|
arrived: a.arrived
|
|
@@ -677,7 +681,7 @@ class ae {
|
|
|
677
681
|
}
|
|
678
682
|
}
|
|
679
683
|
export {
|
|
680
|
-
|
|
684
|
+
S as A,
|
|
681
685
|
Z as B,
|
|
682
686
|
q as C,
|
|
683
687
|
E as D,
|
|
@@ -687,13 +691,13 @@ export {
|
|
|
687
691
|
N as b,
|
|
688
692
|
I as c,
|
|
689
693
|
F as d,
|
|
690
|
-
|
|
694
|
+
ie as e,
|
|
691
695
|
H as f,
|
|
692
696
|
O as g,
|
|
693
|
-
|
|
697
|
+
w as h,
|
|
694
698
|
M as i,
|
|
695
699
|
k as j,
|
|
696
|
-
|
|
700
|
+
W as k,
|
|
697
701
|
U as l,
|
|
698
702
|
y as m,
|
|
699
703
|
_ as n,
|
|
@@ -705,7 +709,7 @@ export {
|
|
|
705
709
|
V as t,
|
|
706
710
|
A as u,
|
|
707
711
|
oe as v,
|
|
708
|
-
|
|
712
|
+
re as w,
|
|
709
713
|
J as x,
|
|
710
714
|
ne as y,
|
|
711
715
|
ee as z
|
|
@@ -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;
|
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-C4FckUel.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 i, a as t, b as s, c as n, d as o, e as l, f as r, h as c, i as g, k as h, l as P, m as u, n as L, o as f, p as m, q as v, g 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 i, a as t, b as s, c as n, d as o, e as l, f as r, h as c, i as g, k as h, l as P, m as u, n as L, o as f, p as m, q as v, g 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-BV93143R.js";
|
|
2
2
|
export {
|
|
3
3
|
i as PathEngine,
|
|
4
4
|
t as arcLengthToSegmentPosition,
|
package/package.json
CHANGED
package/dist/index-BUYdltrL.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 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;
|