vehicle-path2 3.0.1 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/algorithms/math.d.ts +1 -1
- package/dist/core/algorithms/pathFinding.d.ts +2 -2
- package/dist/core/engine.d.ts +1 -2
- package/dist/core/types/movement.d.ts +0 -1
- package/dist/core/types/vehicle.d.ts +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.js +2 -2
- package/dist/index-BQoeJKCj.cjs +1 -0
- package/dist/index-DUYG8fxI.js +699 -0
- package/dist/vehicle-path.cjs +1 -1
- package/dist/vehicle-path.js +1 -1
- package/package.json +1 -1
- package/dist/index-C4FckUel.cjs +0 -1
- package/dist/index-C7pH7jZo.js +0 -716
|
@@ -10,7 +10,7 @@ export interface CurveOffsetOptions {
|
|
|
10
10
|
toOffset?: number;
|
|
11
11
|
toIsPercentage?: boolean;
|
|
12
12
|
}
|
|
13
|
-
export declare function createBezierCurve(line: Line, nextLine: Line, config: MovementConfig,
|
|
13
|
+
export declare function createBezierCurve(line: Line, nextLine: Line, config: MovementConfig, offsetOptions?: CurveOffsetOptions): BezierCurve;
|
|
14
14
|
export declare function getPointOnLine(line: Line, t: number): Point;
|
|
15
15
|
export declare function getPointOnLineByOffset(line: Line, offset: number, isPercentage: boolean): Point;
|
|
16
16
|
export declare function getPointOnBezier(bezier: BezierCurve, t: number): Point;
|
|
@@ -41,7 +41,7 @@ export declare function calculateBezierArcLength(bezier: BezierCurve, segments?:
|
|
|
41
41
|
* Untuk absolute offset: clamp ke [0, lineLength].
|
|
42
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): number;
|
|
45
45
|
/**
|
|
46
46
|
* Resolve offset untuk TO line (garis tujuan kurva).
|
|
47
47
|
* Kurva bisa ditempatkan di mana saja pada line: range [0, lineLength].
|
|
@@ -49,7 +49,7 @@ export declare function resolveFromLineOffset(line: Line, offset: number | undef
|
|
|
49
49
|
* Untuk absolute offset: clamp ke [0, lineLength].
|
|
50
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): number;
|
|
53
53
|
/**
|
|
54
54
|
* Membangun graph dari lines dan curves
|
|
55
55
|
*/
|
package/dist/core/engine.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* ```typescript
|
|
10
10
|
* import { PathEngine } from 'vehicle-path/core'
|
|
11
11
|
*
|
|
12
|
-
* const engine = new PathEngine({
|
|
12
|
+
* const engine = new PathEngine({ tangentMode: 'proportional-40' })
|
|
13
13
|
*
|
|
14
14
|
* engine.setScene(lines, curves)
|
|
15
15
|
*
|
|
@@ -31,7 +31,6 @@ import type { MovementConfig, CurveData } from './types/movement';
|
|
|
31
31
|
import type { PathResult } from './algorithms/pathFinding';
|
|
32
32
|
import type { TangentMode } from './types/config';
|
|
33
33
|
export interface PathEngineConfig {
|
|
34
|
-
maxWheelbase: number;
|
|
35
34
|
tangentMode: TangentMode;
|
|
36
35
|
}
|
|
37
36
|
/**
|
|
@@ -25,7 +25,7 @@ export interface VehicleStart {
|
|
|
25
25
|
lineId: string;
|
|
26
26
|
offset: number;
|
|
27
27
|
isPercentage: boolean;
|
|
28
|
-
/**
|
|
28
|
+
/** axleSpacings[i] = arc-length antara axles[i] dan axles[i+1]. Default: [] (1 axle) */
|
|
29
29
|
axleSpacings?: number[];
|
|
30
30
|
}
|
|
31
31
|
/**
|
package/dist/core.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./index-BQoeJKCj.cjs");function P(n,e){const a={lines:n,curves:e.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(a,null,2)}function O(n){let e;try{e=JSON.parse(n)}catch{throw new Error("deserializeScene: invalid JSON")}if(!e||typeof e!="object"||Array.isArray(e))throw new Error("deserializeScene: expected a JSON object");const a=e;if(!Array.isArray(a.lines))throw new Error('deserializeScene: missing "lines"');if(!Array.isArray(a.curves))throw new Error('deserializeScene: missing "curves"');return{lines:a.lines,curves:a.curves}}function h(n){const e=n.axleExecutions[n.axleExecutions.length-1],a=i.getCumulativeArcLength(n.path,e.segmentIndex,e.segmentDistance);return Math.max(0,n.path.totalDistance-a)}function d(n){const e=n.axleExecutions[0],a=i.getCumulativeArcLength(n.path,e.segmentIndex,e.segmentDistance);let t=0;for(let r=0;r<n.path.segments.length;r++){const o=n.path.segments[r];if(r>=e.segmentIndex&&o.type==="curve")return Math.max(0,t-a);t+=o.length}return null}function p(n,e,a){let t=a.maxSpeed;const r=Math.sqrt(2*a.deceleration*Math.max(0,n));if(t=Math.min(t,r),e!==null){const o=Math.sqrt(a.minCurveSpeed**2+2*a.deceleration*e);t=Math.min(t,o)}return Math.max(0,t)}function x(n,e,a,t,r){return n<e?Math.min(e,n+a*r):n>e?Math.max(e,n-t*r):n}function S(n,e,a,t,r,o){const c=h(e),l=d(e),f=p(c,l,t),g=x(a.currentSpeed,f,t.acceleration,t.deceleration,r),u=g*r,v=n.axles.map(s=>({lineId:s.lineId,position:s.position,absoluteOffset:s.offset})),L=e.axleExecutions.map(s=>({currentSegmentIndex:s.segmentIndex,segmentDistance:s.segmentDistance})),m=i.moveVehicle(v,L,e.path,u,o,e.curveDataMap);return{state:{axles:m.axles.map(s=>({lineId:s.lineId,offset:s.absoluteOffset,position:s.position})),axleSpacings:n.axleSpacings},execution:{...e,axleExecutions:m.axleExecutions.map(s=>({segmentIndex:s.currentSegmentIndex,segmentDistance:s.segmentDistance}))},accelState:{currentSpeed:g},arrived:m.arrived}}function A(n,e){const a=e.end.x-e.start.x,t=e.end.y-e.start.y,r=a*a+t*t;if(r===0)return{offset:0,distance:Math.sqrt((n.x-e.start.x)**2+(n.y-e.start.y)**2)};const o=Math.max(0,Math.min(1,((n.x-e.start.x)*a+(n.y-e.start.y)*t)/r)),c=e.start.x+o*a,l=e.start.y+o*t,f=Math.sqrt((n.x-c)**2+(n.y-l)**2);return{offset:o*Math.sqrt(r),distance:f}}function I(n,e){const a=i.getLineLength(n),t=e.reduce((o,c)=>o+c,0);return[0,Math.max(0,a-t)]}function M(n,e){let a=0;for(const t of e)t.fromLineId===n&&!t.fromIsPercentage&&t.fromOffset!==void 0&&(a=Math.max(a,t.fromOffset)),t.toLineId===n&&!t.toIsPercentage&&t.toOffset!==void 0&&(a=Math.max(a,t.toOffset));return a}exports.PathEngine=i.PathEngine;exports.arcLengthToSegmentPosition=i.arcLengthToSegmentPosition;exports.buildArcLengthTable=i.buildArcLengthTable;exports.buildGraph=i.buildGraph;exports.calculateBezierArcLength=i.calculateBezierArcLength;exports.calculateFrontAxlePosition=i.calculateFrontAxlePosition;exports.calculateInitialAxlePositions=i.calculateInitialAxlePositions;exports.calculatePositionOnCurve=i.calculatePositionOnCurve;exports.calculatePositionOnLine=i.calculatePositionOnLine;exports.calculateTangentLength=i.calculateTangentLength;exports.createBezierCurve=i.createBezierCurve;exports.createInitialMovementState=i.createInitialMovementState;exports.distance=i.distance;exports.distanceToT=i.distanceToT;exports.findPath=i.findPath;exports.getArcLength=i.getArcLength;exports.getCumulativeArcLength=i.getCumulativeArcLength;exports.getLineLength=i.getLineLength;exports.getPointOnBezier=i.getPointOnBezier;exports.getPointOnLine=i.getPointOnLine;exports.getPointOnLineByOffset=i.getPointOnLineByOffset;exports.getPositionFromOffset=i.getPositionFromOffset;exports.handleArrival=i.handleArrival;exports.initializeAllVehicles=i.initializeAllVehicles;exports.initializeMovingVehicle=i.initializeMovingVehicle;exports.isPointNearPoint=i.isPointNearPoint;exports.moveVehicle=i.moveVehicle;exports.normalize=i.normalize;exports.prepareCommandPath=i.prepareCommandPath;exports.resolveFromLineOffset=i.resolveFromLineOffset;exports.resolveToLineOffset=i.resolveToLineOffset;exports.updateAxlePosition=i.updateAxlePosition;exports.approachSpeed=x;exports.computeDistToNextCurve=d;exports.computeMinLineLength=M;exports.computeRemainingToArrival=h;exports.computeTargetSpeed=p;exports.deserializeScene=O;exports.getValidRearOffsetRange=I;exports.moveVehicleWithAcceleration=S;exports.projectPointOnLine=A;exports.serializeScene=P;
|
package/dist/core.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { g as u, m as x, a as p } from "./index-
|
|
2
|
-
import { P as T, b, c as j, d as q, e as C, f as N, h as B, i as V, j as J, k as F, l as R, n as k, o as G, p as W, q as X, r as Y, s as H, t as K, u as Q, v as U, w as Z, x as _, y as $, z as ee, A as te, B as ne, C as ae, D as se, E as re } from "./index-
|
|
1
|
+
import { g as u, m as x, a as p } from "./index-DUYG8fxI.js";
|
|
2
|
+
import { P as T, b, c as j, d as q, e as C, f as N, h as B, i as V, j as J, k as F, l as R, n as k, o as G, p as W, q as X, r as Y, s as H, t as K, u as Q, v as U, w as Z, x as _, y as $, z as ee, A as te, B as ne, C as ae, D as se, E as re } from "./index-DUYG8fxI.js";
|
|
3
3
|
function P(n, e) {
|
|
4
4
|
const a = {
|
|
5
5
|
lines: n,
|
|
@@ -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 T(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 F(t,e){return e*(t==="proportional-40"?.4:.5522)}function z(t,e,s,n){const{tangentMode:i}=s;let c;n?.fromOffset!==void 0?c=V(t,n.fromOffset,n.fromIsPercentage??!1):c=t.end;let o;n?.toOffset!==void 0?o=V(e,n.toOffset,n.toIsPercentage??!1):o=e.start;const r=T(t.start,t.end),f=T(e.start,e.end),h=L(c,o),a=F(i,h),l={x:c.x+r.x*a,y:c.y+r.y*a},d={x:o.x-f.x*a,y:o.y-f.y*a};return{p0:c,p1:l,p2:d,p3:o}}function N(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 V(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)),N(t,i)}function S(t,e){const{p0:s,p1:n,p2:i,p3:c}=t,o=1-e,r=o*o,f=r*o,h=e*e,a=h*e;return{x:f*s.x+3*r*e*n.x+3*o*h*i.x+a*c.x,y:f*s.y+3*r*e*n.y+3*o*h*i.y+a*c.y}}function ee(t,e,s=10){return L(t,e)<=s}function $(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=S(t,o);i+=L(n,r),s.push({t:o,distance:i}),n=r}return s}function j(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 a=Math.floor((n+i)/2);t[a].distance<e?n=a:i=a}const c=t[n].distance,o=t[i].distance,r=t[n].t,f=t[i].t;if(o===c)return r;const h=(e-c)/(o-c);return r+h*(f-r)}function te(t){return t[t.length-1].distance}function K(t,e=100){let s=0,n=t.p0;for(let i=1;i<=e;i++){const c=i/e,o=S(t,c);s+=L(n,o),n=o}return s}function b(t,e,s,n){const i=L(t.start,t.end);return e===void 0?n*i:s?Math.max(0,Math.min(e,1))*i:Math.max(0,Math.min(e,i))}function B(t,e,s,n){const i=L(t.start,t.end);return e===void 0?n*i:s?Math.max(0,Math.min(e,1))*i:Math.max(0,Math.min(e,i))}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],f=i.get(r.fromLineId),h=i.get(r.toLineId);if(!f||!h)continue;const a=b(f,r.fromOffset,r.fromIsPercentage,1),l=B(h,r.toOffset,r.toIsPercentage,0),d=z(f,h,s,{fromOffset:a,fromIsPercentage:!1,toOffset:l,toIsPercentage:!1}),g=K(d),v={curveIndex:o,fromLineId:r.fromLineId,toLineId:r.toLineId,fromOffset:a,toOffset:l,curveLength:g};n.get(r.fromLineId).push(v)}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 h=r.get(s),a=i?n/100*h:n,l=[],d=new Map,g=(u,p)=>`${u}:${Math.round(p)}`;if(e.lineId===s&&a>=e.offset){const u=a-e.offset;return{segments:[{type:"line",lineId:e.lineId,startOffset:e.offset,endOffset:a,length:u}],totalDistance:u,curveCount:0}}const v=c.get(e.lineId)||[];for(const u of v){if(u.fromOffset<e.offset)continue;const p=u.fromOffset-e.offset,I=p+u.curveLength,O={type:"line",lineId:e.lineId,startOffset:e.offset,endOffset:u.fromOffset,length:p},m={type:"curve",curveIndex:u.curveIndex,startOffset:0,endOffset:u.curveLength,length:u.curveLength};l.push({lineId:u.toLineId,entryOffset:u.toOffset,totalDistance:I,curveCount:1,path:[O,m]})}for(l.sort(E);l.length>0;){const u=l.shift(),p=g(u.lineId,u.entryOffset),I=d.get(p);if(I!==void 0&&(I.curveCount<u.curveCount||I.curveCount===u.curveCount&&I.distance<=u.totalDistance))continue;if(d.set(p,{curveCount:u.curveCount,distance:u.totalDistance}),u.lineId===s){const m=Math.abs(a-u.entryOffset);if(a>=u.entryOffset){const C={type:"line",lineId:s,startOffset:u.entryOffset,endOffset:a,length:m};return{segments:[...u.path,C],totalDistance:u.totalDistance+m,curveCount:u.curveCount}}}const O=c.get(u.lineId)||[];for(const m of O){if(m.fromOffset<u.entryOffset)continue;const C=m.fromOffset-u.entryOffset,q=u.totalDistance+C+m.curveLength,w=u.curveCount+1,X=g(m.toLineId,m.toOffset),P=d.get(X);if(P!==void 0&&(P.curveCount<w||P.curveCount===w&&P.distance<=q))continue;const Y={type:"line",lineId:u.lineId,startOffset:u.entryOffset,endOffset:m.fromOffset,length:C},Z={type:"curve",curveIndex:m.curveIndex,startOffset:0,endOffset:m.curveLength,length:m.curveLength};l.push({lineId:m.toLineId,entryOffset:m.toOffset,totalDistance:q,curveCount:w,path:[...u.path,Y,Z]})}l.sort(E)}return null}function A(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 G(t,e,s){let n=0;for(let i=0;i<e;i++)n+=t.segments[i].length;return n+=s,n}function R(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=G(t,e,s)+n;return R(t,c)}function Q(t,e,s,n){const i=M(n),c=s.length+1,o=new Array(c);o[c-1]={lineId:t,absoluteOffset:e,position:A(n,e)};let r=e;for(let f=c-2;f>=0;f--)r=Math.min(r+s[f],i),o[f]={lineId:t,absoluteOffset:r,position:A(n,r)};return o}function W(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=W(i);s.push(o);const r=_(o);n.set(i.id,r)}return{movingVehicles:s,stateMap:n}}function y(t,e){return{position:A(t,e),lineId:t.id,absoluteOffset:e}}function D(t,e){const s=j(t.arcLengthTable,e);return{position:S(t.bezier,s)}}function H(t,e,s,n,i,c,o){const r=s.segments[e.currentSegmentIndex],f=e.segmentDistance+n;if(f>=r.length){const a=f-r.length,l=e.currentSegmentIndex+1;if(l>=s.segments.length){if(o!==void 0&&r.type==="line"){const u=i.get(r.lineId),p=r.startOffset+f;if(p<=o){const O=y(u,p);return{axleState:{...t,...O},execution:{...e,segmentDistance:f},completed:!1}}const I=y(u,o);return{axleState:{...t,...I},execution:{...e,segmentDistance:o-r.startOffset},completed:!0}}const v=r.type==="line"?y(i.get(r.lineId),r.endOffset):D(c.get(r.curveIndex),r.length);return{axleState:{...t,...v},execution:{...e,segmentDistance:r.length},completed:!0}}const d=s.segments[l],g=d.type==="line"?y(i.get(d.lineId),d.startOffset+a):D(c.get(d.curveIndex),a);return{axleState:{...t,...g},execution:{currentSegmentIndex:l,segmentDistance:a},completed:!1}}const h=r.type==="line"?y(i.get(r.lineId),r.startOffset+f):D(c.get(r.curveIndex),f);return{axleState:{...t,...h},execution:{...e,segmentDistance:f},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),f=s.get(o.toLineId);if(r&&f){const h=b(r,o.fromOffset,o.fromIsPercentage,1),a=B(f,o.toOffset,o.toIsPercentage,0),l=z(r,f,n,{fromOffset:h,fromIsPercentage:!1,toOffset:a,toIsPercentage:!1}),d=$(l);i.set(c.curveIndex,{bezier:l,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 f=t.axleSpacings.reduce((u,p)=>u+p,0),a=M(r)-f;if(a<=0)return null;const l=e.isPercentage?e.targetOffset*a:Math.min(e.targetOffset,a),d=t.axles[t.axles.length-1],g=k(n,{lineId:d.lineId,offset:d.absoluteOffset},e.targetLineId,l,!1);if(!g)return null;const v=ie(g,c,i,o);return{path:g,curveDataMap:v}}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){const o=t.map((r,f)=>{const h=f===t.length-1;let a;if(!h){const l=e[f];if(l.currentSegmentIndex<s.segments.length){const d=s.segments[l.currentSegmentIndex];if(d.type==="line"){const g=i.get(d.lineId);g&&(a=M(g))}}}return H(r,e[f],s,n,i,c,a)});return{axles:o.map(r=>r.axleState),axleExecutions:o.map(r=>r.execution),arrived:o[o.length-1].completed}}class oe{graph=null;linesMap=new Map;curves=[];config;constructor(e){this.config={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{axleSpacings:c}=n;if(c.length===0)throw new Error("initializeVehicle: axleSpacings must have at least one entry (vehicle needs ≥2 axles)");const o=c.reduce((a,l)=>a+l,0),r=M(i),f=Math.min(s,r-o);return{axles:Q(e,f,c,i).map(a=>({lineId:a.lineId,offset:a.absoluteOffset,position:a.position})),axleSpacings:c}}preparePath(e,s,n,i=!1){if(!this.graph)return null;const c=e.axleSpacings.reduce((g,v)=>g+v,0),o=e.axles[e.axles.length-1],r={lineId:o.lineId,offset:o.offset,axles:e.axles.map(g=>({lineId:g.lineId,position:g.position,absoluteOffset:g.offset})),axleSpacings:e.axleSpacings},f=J(r,{targetLineId:s,targetOffset:n,isPercentage:i},{graph:this.graph,linesMap:this.linesMap,curves:this.curves,config:this.config});if(!f)return null;let h=n;const a=this.linesMap.get(s);if(a){const g=Math.max(0,M(a)-c);h=i?n*g:Math.min(n,g)}let l=0;const d=[{segmentIndex:0,segmentDistance:c}];for(let g=0;g<e.axleSpacings.length;g++)l+=e.axleSpacings[g],d.push({segmentIndex:0,segmentDistance:c-l});return{path:f.path,curveDataMap:f.curveDataMap,axleExecutions:d,targetLineId:s,targetOffset:h}}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=R;exports.buildArcLengthTable=$;exports.buildGraph=x;exports.calculateBezierArcLength=K;exports.calculateFrontAxlePosition=ne;exports.calculateInitialAxlePositions=Q;exports.calculatePositionOnCurve=D;exports.calculatePositionOnLine=y;exports.calculateTangentLength=F;exports.createBezierCurve=z;exports.createInitialMovementState=_;exports.distance=L;exports.distanceToT=j;exports.findPath=k;exports.getArcLength=te;exports.getCumulativeArcLength=G;exports.getLineLength=M;exports.getPointOnBezier=S;exports.getPointOnLine=N;exports.getPointOnLineByOffset=V;exports.getPositionFromOffset=A;exports.handleArrival=re;exports.initializeAllVehicles=se;exports.initializeMovingVehicle=W;exports.isPointNearPoint=ee;exports.moveVehicle=U;exports.normalize=T;exports.prepareCommandPath=J;exports.resolveFromLineOffset=b;exports.resolveToLineOffset=B;exports.updateAxlePosition=H;
|