vehicle-path2 1.0.12 → 1.0.14

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.
@@ -128,6 +128,26 @@ export declare function updateAxlePosition(axleState: AxleState, axleExecution:
128
128
  execution: AxleExecutionState;
129
129
  completed: boolean;
130
130
  };
131
+ export interface MoveVehicleInput {
132
+ rear: AxleState;
133
+ front: AxleState;
134
+ rearExecution: AxleExecutionState;
135
+ frontExecution: AxleExecutionState;
136
+ }
137
+ export interface MoveVehicleResult {
138
+ rear: AxleState;
139
+ front: AxleState;
140
+ rearExecution: AxleExecutionState;
141
+ frontExecution: AxleExecutionState;
142
+ arrived: boolean;
143
+ }
144
+ /**
145
+ * Move a dual-axle vehicle along a path by a given distance.
146
+ *
147
+ * Coordinates rear and front axle updates, computes front maxOffset,
148
+ * detects arrival at target, and clamps both axles to preserve wheelbase.
149
+ */
150
+ export declare function moveVehicle(input: MoveVehicleInput, path: PathResult, distance: number, linesMap: Map<string, Line>, curveDataMap: Map<number, CurveData>, targetLineId: string, targetOffset: number, wheelbase: number): MoveVehicleResult;
131
151
  export interface PreparedPath {
132
152
  path: PathResult;
133
153
  curveDataMap: Map<number, CurveData>;
@@ -12,9 +12,9 @@
12
12
  */
13
13
  export type { Point, Line, BezierCurve, Curve } from './types/geometry';
14
14
  export type { VehicleState, VehicleStart, Vehicle, AxleState, GotoCommand, GotoCompletionInfo, GotoCompletionCallback } from './types/vehicle';
15
- export type { CurveData, PathExecutionState, VehicleMovementState, MovementConfig, SceneContext } from './types/movement';
15
+ export type { CurveData, PathExecutionState, AxleExecutionState, 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';
18
18
  export { buildGraph, findPath, calculateBezierArcLength, resolveFromLineOffset, resolveToLineOffset, type Graph, type GraphEdge, type PathSegment, type PathResult, type VehiclePosition } from './algorithms/pathFinding';
19
- export { initializeMovingVehicle, createInitialMovementState, initializeAllVehicles, calculateInitialFrontPosition, type InitializationResult, updateAxlePosition, calculatePositionOnLine, calculatePositionOnCurve, calculateFrontAxlePosition, getCumulativeArcLength, arcLengthToSegmentPosition, prepareCommandPath, type PreparedPath, handleArrival, type SegmentCompletionContext, type SegmentCompletionResult, type SegmentVehicleState, getPositionFromOffset, getLineLength } from './algorithms/vehicleMovement';
19
+ export { initializeMovingVehicle, createInitialMovementState, initializeAllVehicles, calculateInitialFrontPosition, type InitializationResult, updateAxlePosition, moveVehicle, type MoveVehicleInput, type MoveVehicleResult, calculatePositionOnLine, calculatePositionOnCurve, calculateFrontAxlePosition, getCumulativeArcLength, arcLengthToSegmentPosition, prepareCommandPath, type PreparedPath, handleArrival, type SegmentCompletionContext, type SegmentCompletionResult, type SegmentVehicleState, getPositionFromOffset, getLineLength } from './algorithms/vehicleMovement';
20
20
  export { distance, normalize, getPointOnLine, getPointOnLineByOffset, getPointOnBezier, createBezierCurve, buildArcLengthTable, distanceToT, getArcLength, calculateTangentLength, isPointNearPoint, type ArcLengthEntry, type CurveOffsetOptions } from './algorithms/math';
package/dist/core.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function L(t,e){const s=e.x-t.x,o=e.y-t.y;return Math.sqrt(s*s+o*o)}function M(t,e){const s=e.x-t.x,o=e.y-t.y,n=Math.sqrt(s*s+o*o);return n===0?{x:0,y:0}:{x:s/n,y:o/n}}function V(t,e){return e*(t==="proportional-40"?.4:.5522)}function S(t,e,s,o=!1,n){const{wheelbase:c,tangentMode:i}=s;let r;n?.fromOffset!==void 0?r=D(t,n.fromOffset,n.fromIsPercentage??!1):r=t.end;let a;n?.toOffset!==void 0?a=D(e,n.toOffset,n.toIsPercentage??!1):a=e.start;const d=M(t.start,t.end),u=o?{x:r.x-d.x*c,y:r.y-d.y*c}:r,l=M(t.start,t.end),g=M(e.start,e.end),y=L(u,a),m=V(i,y),f=o?{x:u.x-l.x*m,y:u.y-l.y*m}:{x:u.x+l.x*m,y:u.y+l.y*m},v={x:a.x-g.x*m,y:a.y-g.y*m};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 D(t,e,s){const o=L(t.start,t.end);let n;return s?n=e:n=o>0?e/o:0,n=Math.max(0,Math.min(1,n)),F(t,n)}function w(t,e){const{p0:s,p1:o,p2:n,p3:c}=t,i=1-e,r=i*i,a=r*i,d=e*e,u=d*e;return{x:a*s.x+3*r*e*o.x+3*i*d*n.x+u*c.x,y:a*s.y+3*r*e*o.y+3*i*d*n.y+u*c.y}}function U(t,e,s=10){return L(t,e)<=s}function j(t,e=100){const s=[{t:0,distance:0}];let o=t.p0,n=0;for(let c=1;c<=e;c++){const i=c/e,r=w(t,i);n+=L(o,r),s.push({t:i,distance:n}),o=r}return s}function K(t,e){if(e<=0)return 0;const s=t[t.length-1].distance;if(e>=s)return 1;let o=0,n=t.length-1;for(;o<n-1;){const u=Math.floor((o+n)/2);t[u].distance<e?o=u:n=u}const c=t[o].distance,i=t[n].distance,r=t[o].t,a=t[n].t;if(i===c)return r;const d=(e-c)/(i-c);return r+d*(a-r)}function X(t){return t[t.length-1].distance}function N(t,e=100){let s=0,o=t.p0;for(let n=1;n<=e;n++){const c=n/e,i=w(t,c);s+=L(o,i),o=i}return s}function A(t,e,s,o,n){const c=L(t.start,t.end),i=c-n;if(i<=0)return c;let r;if(e===void 0)r=o;else if(s)r=e;else{const a=Math.max(0,Math.min(e,i));return n+a}return n+r*i}function b(t,e,s,o,n){const i=L(t.start,t.end)-n;if(i<=0)return 0;let r;if(e===void 0)r=o;else if(s)r=e;else return Math.max(0,Math.min(e,i));return r*i}function Y(t,e,s){const o=new Map,n=new Map,c=new Map;for(const i of t)n.set(i.id,i),c.set(i.id,L(i.start,i.end)),o.set(i.id,[]);for(let i=0;i<e.length;i++){const r=e[i],a=n.get(r.fromLineId),d=n.get(r.toLineId);if(!a||!d)continue;const u=A(a,r.fromOffset,r.fromIsPercentage,1,s.wheelbase),l=b(d,r.toOffset,r.toIsPercentage,0,s.wheelbase),g=S(a,d,s,!1,{fromOffset:u,fromIsPercentage:!1,toOffset:l,toIsPercentage:!1}),y=N(g),m={curveIndex:i,fromLineId:r.fromLineId,toLineId:r.toLineId,fromOffset:u,toOffset:l,curveLength:y};o.get(r.fromLineId).push(m)}return{adjacency:o,lines:n,lineLengths:c}}function B(t,e){return t.curveCount!==e.curveCount?t.curveCount-e.curveCount:t.totalDistance-e.totalDistance}function k(t,e,s,o,n=!1){const{adjacency:c,lines:i,lineLengths:r}=t;if(!i.get(s))return null;const d=r.get(s),u=n?o/100*d:o,l=[],g=new Map,y=(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 m=c.get(e.lineId)||[];for(const f of m){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},h={type:"curve",curveIndex:f.curveIndex,startOffset:0,endOffset:f.curveLength,length:f.curveLength};l.push({lineId:f.toLineId,entryOffset:f.toOffset,totalDistance:I,curveCount:1,path:[O,h]})}for(l.sort(B);l.length>0;){const f=l.shift(),v=y(f.lineId,f.entryOffset),I=g.get(v);if(I!==void 0&&(I.curveCount<f.curveCount||I.curveCount===f.curveCount&&I.distance<=f.totalDistance))continue;if(g.set(v,{curveCount:f.curveCount,distance:f.totalDistance}),f.lineId===s){const h=Math.abs(u-f.entryOffset);if(u>=f.entryOffset){const x={type:"line",lineId:s,startOffset:f.entryOffset,endOffset:u,length:h};return{segments:[...f.path,x],totalDistance:f.totalDistance+h,curveCount:f.curveCount}}}const O=c.get(f.lineId)||[];for(const h of O){if(h.fromOffset<f.entryOffset)continue;const x=h.fromOffset-f.entryOffset,q=f.totalDistance+x+h.curveLength,T=f.curveCount+1,H=y(h.toLineId,h.toOffset),P=g.get(H);if(P!==void 0&&(P.curveCount<T||P.curveCount===T&&P.distance<=q))continue;const J={type:"line",lineId:f.lineId,startOffset:f.entryOffset,endOffset:h.fromOffset,length:x},R={type:"curve",curveIndex:h.curveIndex,startOffset:0,endOffset:h.curveLength,length:h.curveLength};l.push({lineId:h.toLineId,entryOffset:h.toOffset,totalDistance:q,curveCount:T,path:[...f.path,J,R]})}l.sort(B)}return null}function z(t,e){const s=Math.sqrt(Math.pow(t.end.x-t.start.x,2)+Math.pow(t.end.y-t.start.y,2)),o=s>0?e/s:0;return{x:t.start.x+(t.end.x-t.start.x)*Math.min(1,Math.max(0,o)),y:t.start.y+(t.end.y-t.start.y)*Math.min(1,Math.max(0,o))}}function G(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 o=0;for(let n=0;n<e;n++)o+=t.segments[n].length;return o+=s,o}function Q(t,e){let s=0;for(let o=0;o<t.segments.length;o++){const n=t.segments[o],c=s+n.length;if(e<c)return{segmentIndex:o,segmentDistance:e-s};if(e===c)return o+1<t.segments.length?{segmentIndex:o+1,segmentDistance:0}:{segmentIndex:o,segmentDistance:n.length};s+=n.length}return null}function Z(t,e,s,o){const c=$(t,e,s)+o;return Q(t,c)}function E(t,e,s,o){const n=Math.sqrt(Math.pow(o.end.x-o.start.x,2)+Math.pow(o.end.y-o.start.y,2));let c=e+s;c=Math.min(c,n);const i=z(o,c);return{lineId:t,position:i,absoluteOffset:c}}function W(t,e){return{...t,state:"idle"}}function _(t){return{vehicle:t,execution:null}}function tt(t,e){const s=[],o=new Map;for(const n of t){if(!e.get(n.lineId))continue;const i=W(n);s.push(i);const r=_(i);o.set(n.id,r)}return{movingVehicles:s,stateMap:o}}function p(t,e){return{position:z(t,e),lineId:t.id,absoluteOffset:e}}function C(t,e){const s=K(t.arcLengthTable,e);return{position:w(t.bezier,s)}}function et(t,e,s,o,n,c,i){const r=s.segments[e.currentSegmentIndex],a=e.segmentDistance+o;if(a>=r.length){const u=a-r.length,l=e.currentSegmentIndex+1;if(l>=s.segments.length){if(i!==void 0&&r.type==="line"){const f=n.get(r.lineId),v=r.startOffset+a;if(v<=i){const O=p(f,v);return{axleState:{...t,...O},execution:{...e,segmentDistance:a},completed:!1}}const I=p(f,i);return{axleState:{...t,...I},execution:{...e,segmentDistance:i-r.startOffset},completed:!0}}const m=r.type==="line"?p(n.get(r.lineId),r.endOffset):C(c.get(r.curveIndex),r.length);return{axleState:{...t,...m},execution:{...e,segmentDistance:r.length},completed:!0}}const g=s.segments[l],y=g.type==="line"?p(n.get(g.lineId),g.startOffset+u):C(c.get(g.curveIndex),u);return{axleState:{...t,...y},execution:{currentSegmentIndex:l,segmentDistance:u},completed:!1}}const d=r.type==="line"?p(n.get(r.lineId),r.startOffset+a):C(c.get(r.curveIndex),a);return{axleState:{...t,...d},execution:{...e,segmentDistance:a},completed:!1}}function nt(t,e,s,o){const n=new Map;for(const c of t.segments)if(c.type==="curve"&&c.curveIndex!==void 0){const i=e[c.curveIndex];if(i){const r=s.get(i.fromLineId),a=s.get(i.toLineId);if(r&&a){const d=A(r,i.fromOffset,i.fromIsPercentage,1,o.wheelbase),u=b(a,i.toOffset,i.toIsPercentage,0,o.wheelbase),l=S(r,a,o,!1,{fromOffset:d,fromIsPercentage:!1,toOffset:u,toIsPercentage:!1}),g=j(l);n.set(c.curveIndex,{bezier:l,arcLengthTable:g})}}}return n}function ot(t,e,s){const{graph:o,linesMap:n,curves:c,config:i}=s,r=n.get(e.targetLineId);if(!r)return null;const d=G(r)-i.wheelbase;if(d<=0)return null;const u=e.isPercentage?e.targetOffset*d:Math.min(e.targetOffset,d),l=k(o,{lineId:t.rear.lineId,offset:t.rear.absoluteOffset},e.targetLineId,u,!1);if(!l)return null;const g=nt(l,c,n,i);return{path:l,curveDataMap:g}}function st(t,e){const s=t.execution,n=e.vehicleQueues.get(t.vehicle.id)?.[s.currentCommandIndex];return n&&e.onCommandComplete&&e.onCommandComplete({vehicleId:t.vehicle.id,command:n,finalPosition:{lineId:t.vehicle.rear.lineId,absoluteOffset:t.vehicle.rear.absoluteOffset,position:t.vehicle.rear.position},payload:n.payload}),{handled:!0,vehicle:{...t.vehicle,state:"waiting"},newExecution:s,isWaiting:!0}}exports.arcLengthToSegmentPosition=Q;exports.buildArcLengthTable=j;exports.buildGraph=Y;exports.calculateBezierArcLength=N;exports.calculateFrontAxlePosition=Z;exports.calculateInitialFrontPosition=E;exports.calculatePositionOnCurve=C;exports.calculatePositionOnLine=p;exports.calculateTangentLength=V;exports.createBezierCurve=S;exports.createInitialMovementState=_;exports.distance=L;exports.distanceToT=K;exports.findPath=k;exports.getArcLength=X;exports.getCumulativeArcLength=$;exports.getLineLength=G;exports.getPointOnBezier=w;exports.getPointOnLine=F;exports.getPointOnLineByOffset=D;exports.getPositionFromOffset=z;exports.handleArrival=st;exports.initializeAllVehicles=tt;exports.initializeMovingVehicle=W;exports.isPointNearPoint=U;exports.normalize=M;exports.prepareCommandPath=ot;exports.resolveFromLineOffset=A;exports.resolveToLineOffset=b;exports.updateAxlePosition=et;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function I(e,t){const r=t.x-e.x,n=t.y-e.y;return Math.sqrt(r*r+n*n)}function C(e,t){const r=t.x-e.x,n=t.y-e.y,o=Math.sqrt(r*r+n*n);return o===0?{x:0,y:0}:{x:r/o,y:n/o}}function B(e,t){return t*(e==="proportional-40"?.4:.5522)}function A(e,t,r,n=!1,o){const{wheelbase:c,tangentMode:s}=r;let i;o?.fromOffset!==void 0?i=T(e,o.fromOffset,o.fromIsPercentage??!1):i=e.end;let f;o?.toOffset!==void 0?f=T(t,o.toOffset,o.toIsPercentage??!1):f=t.start;const l=C(e.start,e.end),u=n?{x:i.x-l.x*c,y:i.y-l.y*c}:i,d=C(e.start,e.end),g=C(t.start,t.end),v=I(u,f),m=B(s,v),a=n?{x:u.x-d.x*m,y:u.y-d.y*m}:{x:u.x+d.x*m,y:u.y+d.y*m},x={x:f.x-g.x*m,y:f.y-g.y*m};return{p0:u,p1:a,p2:x,p3:f}}function j(e,t){return{x:e.start.x+(e.end.x-e.start.x)*t,y:e.start.y+(e.end.y-e.start.y)*t}}function T(e,t,r){const n=I(e.start,e.end);let o;return r?o=t:o=n>0?t/n:0,o=Math.max(0,Math.min(1,o)),j(e,o)}function M(e,t){const{p0:r,p1:n,p2:o,p3:c}=e,s=1-t,i=s*s,f=i*s,l=t*t,u=l*t;return{x:f*r.x+3*i*t*n.x+3*s*l*o.x+u*c.x,y:f*r.y+3*i*t*n.y+3*s*l*o.y+u*c.y}}function U(e,t,r=10){return I(e,t)<=r}function k(e,t=100){const r=[{t:0,distance:0}];let n=e.p0,o=0;for(let c=1;c<=t;c++){const s=c/t,i=M(e,s);o+=I(n,i),r.push({t:s,distance:o}),n=i}return r}function K(e,t){if(t<=0)return 0;const r=e[e.length-1].distance;if(t>=r)return 1;let n=0,o=e.length-1;for(;n<o-1;){const u=Math.floor((n+o)/2);e[u].distance<t?n=u:o=u}const c=e[n].distance,s=e[o].distance,i=e[n].t,f=e[o].t;if(s===c)return i;const l=(t-c)/(s-c);return i+l*(f-i)}function X(e){return e[e.length-1].distance}function N(e,t=100){let r=0,n=e.p0;for(let o=1;o<=t;o++){const c=o/t,s=M(e,c);r+=I(n,s),n=s}return r}function b(e,t,r,n,o){const c=I(e.start,e.end),s=c-o;if(s<=0)return c;let i;if(t===void 0)i=n;else if(r)i=t;else{const f=Math.max(0,Math.min(t,s));return o+f}return o+i*s}function z(e,t,r,n,o){const s=I(e.start,e.end)-o;if(s<=0)return 0;let i;if(t===void 0)i=n;else if(r)i=t;else return Math.max(0,Math.min(t,s));return i*s}function Y(e,t,r){const n=new Map,o=new Map,c=new Map;for(const s of e)o.set(s.id,s),c.set(s.id,I(s.start,s.end)),n.set(s.id,[]);for(let s=0;s<t.length;s++){const i=t[s],f=o.get(i.fromLineId),l=o.get(i.toLineId);if(!f||!l)continue;const u=b(f,i.fromOffset,i.fromIsPercentage,1,r.wheelbase),d=z(l,i.toOffset,i.toIsPercentage,0,r.wheelbase),g=A(f,l,r,!1,{fromOffset:u,fromIsPercentage:!1,toOffset:d,toIsPercentage:!1}),v=N(g),m={curveIndex:s,fromLineId:i.fromLineId,toLineId:i.toLineId,fromOffset:u,toOffset:d,curveLength:v};n.get(i.fromLineId).push(m)}return{adjacency:n,lines:o,lineLengths:c}}function q(e,t){return e.curveCount!==t.curveCount?e.curveCount-t.curveCount:e.totalDistance-t.totalDistance}function R(e,t,r,n,o=!1){const{adjacency:c,lines:s,lineLengths:i}=e;if(!s.get(r))return null;const l=i.get(r),u=o?n/100*l:n,d=[],g=new Map,v=(a,x)=>`${a}:${Math.round(x)}`;if(t.lineId===r&&u>=t.offset){const a=u-t.offset;return{segments:[{type:"line",lineId:t.lineId,startOffset:t.offset,endOffset:u,length:a}],totalDistance:a,curveCount:0}}const m=c.get(t.lineId)||[];for(const a of m){if(a.fromOffset<t.offset)continue;const x=a.fromOffset-t.offset,L=x+a.curveLength,p={type:"line",lineId:t.lineId,startOffset:t.offset,endOffset:a.fromOffset,length:x},h={type:"curve",curveIndex:a.curveIndex,startOffset:0,endOffset:a.curveLength,length:a.curveLength};d.push({lineId:a.toLineId,entryOffset:a.toOffset,totalDistance:L,curveCount:1,path:[p,h]})}for(d.sort(q);d.length>0;){const a=d.shift(),x=v(a.lineId,a.entryOffset),L=g.get(x);if(L!==void 0&&(L.curveCount<a.curveCount||L.curveCount===a.curveCount&&L.distance<=a.totalDistance))continue;if(g.set(x,{curveCount:a.curveCount,distance:a.totalDistance}),a.lineId===r){const h=Math.abs(u-a.entryOffset);if(u>=a.entryOffset){const O={type:"line",lineId:r,startOffset:a.entryOffset,endOffset:u,length:h};return{segments:[...a.path,O],totalDistance:a.totalDistance+h,curveCount:a.curveCount}}}const p=c.get(a.lineId)||[];for(const h of p){if(h.fromOffset<a.entryOffset)continue;const O=h.fromOffset-a.entryOffset,F=a.totalDistance+O+h.curveLength,S=a.curveCount+1,_=v(h.toLineId,h.toOffset),P=g.get(_);if(P!==void 0&&(P.curveCount<S||P.curveCount===S&&P.distance<=F))continue;const H={type:"line",lineId:a.lineId,startOffset:a.entryOffset,endOffset:h.fromOffset,length:O},J={type:"curve",curveIndex:h.curveIndex,startOffset:0,endOffset:h.curveLength,length:h.curveLength};d.push({lineId:h.toLineId,entryOffset:h.toOffset,totalDistance:F,curveCount:S,path:[...a.path,H,J]})}d.sort(q)}return null}function E(e,t){const r=Math.sqrt(Math.pow(e.end.x-e.start.x,2)+Math.pow(e.end.y-e.start.y,2)),n=r>0?t/r:0;return{x:e.start.x+(e.end.x-e.start.x)*Math.min(1,Math.max(0,n)),y:e.start.y+(e.end.y-e.start.y)*Math.min(1,Math.max(0,n))}}function V(e){return Math.sqrt(Math.pow(e.end.x-e.start.x,2)+Math.pow(e.end.y-e.start.y,2))}function G(e,t,r){let n=0;for(let o=0;o<t;o++)n+=e.segments[o].length;return n+=r,n}function $(e,t){let r=0;for(let n=0;n<e.segments.length;n++){const o=e.segments[n],c=r+o.length;if(t<c)return{segmentIndex:n,segmentDistance:t-r};if(t===c)return n+1<e.segments.length?{segmentIndex:n+1,segmentDistance:0}:{segmentIndex:n,segmentDistance:o.length};r+=o.length}return null}function Z(e,t,r,n){const c=G(e,t,r)+n;return $(e,c)}function ee(e,t,r,n){const o=Math.sqrt(Math.pow(n.end.x-n.start.x,2)+Math.pow(n.end.y-n.start.y,2));let c=t+r;c=Math.min(c,o);const s=E(n,c);return{lineId:e,position:s,absoluteOffset:c}}function Q(e,t){return{...e,state:"idle"}}function W(e){return{vehicle:e,execution:null}}function te(e,t){const r=[],n=new Map;for(const o of e){if(!t.get(o.lineId))continue;const s=Q(o);r.push(s);const i=W(s);n.set(o.id,i)}return{movingVehicles:r,stateMap:n}}function y(e,t){return{position:E(e,t),lineId:e.id,absoluteOffset:t}}function w(e,t){const r=K(e.arcLengthTable,t);return{position:M(e.bezier,r)}}function D(e,t,r,n,o,c,s){let i=t.currentSegmentIndex,f=t.segmentDistance,l=n;for(;l>0;){const g=r.segments[i],v=g.length-f;if(l<v){f+=l,l=0;break}l-=v;const m=i+1;if(m>=r.segments.length){if(s!==void 0&&g.type==="line"){const x=g.startOffset+g.length+l;if(x<=s){const h=o.get(g.lineId),O=y(h,x);return{axleState:{...e,...O},execution:{currentSegmentIndex:i,segmentDistance:g.length+l},completed:!1}}const L=o.get(g.lineId),p=y(L,s);return{axleState:{...e,...p},execution:{currentSegmentIndex:i,segmentDistance:s-g.startOffset},completed:!0}}const a=g.type==="line"?y(o.get(g.lineId),g.endOffset):w(c.get(g.curveIndex),g.length);return{axleState:{...e,...a},execution:{currentSegmentIndex:i,segmentDistance:g.length},completed:!0}}i=m,f=0}const u=r.segments[i],d=u.type==="line"?y(o.get(u.lineId),u.startOffset+f):w(c.get(u.curveIndex),f);return{axleState:{...e,...d},execution:{currentSegmentIndex:i,segmentDistance:f},completed:!1}}function ne(e,t,r,n,o,c,s,i){const f=D(e.rear,e.rearExecution,t,r,n,o);let l;const u=e.frontExecution.currentSegmentIndex;if(u<t.segments.length){const v=t.segments[u];if(v.type==="line"){const m=n.get(v.lineId);m&&(l=V(m))}}const d=D(e.front,e.frontExecution,t,r,n,o,l);if(f.axleState.lineId===c&&f.axleState.absoluteOffset>=s-.001){const v=n.get(c),m=y(v,s),a=y(v,s+i);return{rear:{...f.axleState,...m},front:{...d.axleState,...a},rearExecution:f.execution,frontExecution:d.execution,arrived:!0}}return{rear:f.axleState,front:d.axleState,rearExecution:f.execution,frontExecution:d.execution,arrived:!1}}function oe(e,t,r,n){const o=new Map;for(const c of e.segments)if(c.type==="curve"&&c.curveIndex!==void 0){const s=t[c.curveIndex];if(s){const i=r.get(s.fromLineId),f=r.get(s.toLineId);if(i&&f){const l=b(i,s.fromOffset,s.fromIsPercentage,1,n.wheelbase),u=z(f,s.toOffset,s.toIsPercentage,0,n.wheelbase),d=A(i,f,n,!1,{fromOffset:l,fromIsPercentage:!1,toOffset:u,toIsPercentage:!1}),g=k(d);o.set(c.curveIndex,{bezier:d,arcLengthTable:g})}}}return o}function re(e,t,r){const{graph:n,linesMap:o,curves:c,config:s}=r,i=o.get(t.targetLineId);if(!i)return null;const l=V(i)-s.wheelbase;if(l<=0)return null;const u=t.isPercentage?t.targetOffset*l:Math.min(t.targetOffset,l),d=R(n,{lineId:e.rear.lineId,offset:e.rear.absoluteOffset},t.targetLineId,u,!1);if(!d)return null;const g=oe(d,c,o,s);return{path:d,curveDataMap:g}}function se(e,t){const r=e.execution,o=t.vehicleQueues.get(e.vehicle.id)?.[r.currentCommandIndex];return o&&t.onCommandComplete&&t.onCommandComplete({vehicleId:e.vehicle.id,command:o,finalPosition:{lineId:e.vehicle.rear.lineId,absoluteOffset:e.vehicle.rear.absoluteOffset,position:e.vehicle.rear.position},payload:o.payload}),{handled:!0,vehicle:{...e.vehicle,state:"waiting"},newExecution:r,isWaiting:!0}}exports.arcLengthToSegmentPosition=$;exports.buildArcLengthTable=k;exports.buildGraph=Y;exports.calculateBezierArcLength=N;exports.calculateFrontAxlePosition=Z;exports.calculateInitialFrontPosition=ee;exports.calculatePositionOnCurve=w;exports.calculatePositionOnLine=y;exports.calculateTangentLength=B;exports.createBezierCurve=A;exports.createInitialMovementState=W;exports.distance=I;exports.distanceToT=K;exports.findPath=R;exports.getArcLength=X;exports.getCumulativeArcLength=G;exports.getLineLength=V;exports.getPointOnBezier=M;exports.getPointOnLine=j;exports.getPointOnLineByOffset=T;exports.getPositionFromOffset=E;exports.handleArrival=se;exports.initializeAllVehicles=te;exports.initializeMovingVehicle=Q;exports.isPointNearPoint=U;exports.moveVehicle=ne;exports.normalize=C;exports.prepareCommandPath=re;exports.resolveFromLineOffset=b;exports.resolveToLineOffset=z;exports.updateAxlePosition=D;
package/dist/core.js CHANGED
@@ -1,124 +1,124 @@
1
- function p(t, e) {
2
- const o = e.x - t.x, s = e.y - t.y;
3
- return Math.sqrt(o * o + s * s);
1
+ function y(t, e) {
2
+ const s = e.x - t.x, n = e.y - t.y;
3
+ return Math.sqrt(s * s + n * n);
4
4
  }
5
- function w(t, e) {
6
- const o = e.x - t.x, s = e.y - t.y, n = Math.sqrt(o * o + s * s);
7
- return n === 0 ? { x: 0, y: 0 } : { x: o / n, y: s / n };
5
+ function P(t, e) {
6
+ const s = e.x - t.x, n = e.y - t.y, o = Math.sqrt(s * s + n * n);
7
+ return o === 0 ? { x: 0, y: 0 } : { x: s / o, y: n / o };
8
8
  }
9
9
  function K(t, e) {
10
10
  return e * (t === "proportional-40" ? 0.4 : 0.5522);
11
11
  }
12
- function b(t, e, o, s = !1, n) {
13
- const { wheelbase: c, tangentMode: i } = o;
14
- let r;
15
- n?.fromOffset !== void 0 ? r = S(t, n.fromOffset, n.fromIsPercentage ?? !1) : r = t.end;
12
+ function A(t, e, s, n = !1, o) {
13
+ const { wheelbase: i, tangentMode: r } = s;
14
+ let c;
15
+ o?.fromOffset !== void 0 ? c = D(t, o.fromOffset, o.fromIsPercentage ?? !1) : c = t.end;
16
16
  let a;
17
- n?.toOffset !== void 0 ? a = S(e, n.toOffset, n.toIsPercentage ?? !1) : a = e.start;
18
- const l = w(t.start, t.end), u = s ? {
17
+ o?.toOffset !== void 0 ? a = D(e, o.toOffset, o.toIsPercentage ?? !1) : a = e.start;
18
+ const l = P(t.start, t.end), u = n ? {
19
19
  // Transition with flip: kurva dimulai dari P (baseP0 - wheelbase in line direction)
20
- x: r.x - l.x * c,
21
- y: r.y - l.y * c
22
- } : r, d = w(t.start, t.end), g = w(e.start, e.end), I = p(u, a), m = K(i, I), f = s ? { x: u.x - d.x * m, y: u.y - d.y * m } : { x: u.x + d.x * m, y: u.y + d.y * m }, v = {
20
+ x: c.x - l.x * i,
21
+ y: c.y - l.y * i
22
+ } : c, d = P(t.start, t.end), g = P(e.start, e.end), x = y(u, a), m = K(r, x), f = n ? { x: u.x - d.x * m, y: u.y - d.y * m } : { x: u.x + d.x * m, y: u.y + d.y * m }, v = {
23
23
  x: a.x - g.x * m,
24
24
  y: a.y - g.y * m
25
25
  };
26
26
  return { p0: u, p1: f, p2: v, p3: a };
27
27
  }
28
- function k(t, e) {
28
+ function R(t, e) {
29
29
  return {
30
30
  x: t.start.x + (t.end.x - t.start.x) * e,
31
31
  y: t.start.y + (t.end.y - t.start.y) * e
32
32
  };
33
33
  }
34
- function S(t, e, o) {
35
- const s = p(t.start, t.end);
36
- let n;
37
- return o ? n = e : n = s > 0 ? e / s : 0, n = Math.max(0, Math.min(1, n)), k(t, n);
34
+ function D(t, e, s) {
35
+ const n = y(t.start, t.end);
36
+ let o;
37
+ return s ? o = e : o = n > 0 ? e / n : 0, o = Math.max(0, Math.min(1, o)), R(t, o);
38
38
  }
39
- function D(t, e) {
40
- const { p0: o, p1: s, p2: n, p3: c } = t, i = 1 - e, r = i * i, a = r * i, l = e * e, u = l * e;
39
+ function w(t, e) {
40
+ const { p0: s, p1: n, p2: o, p3: i } = t, r = 1 - e, c = r * r, a = c * r, l = e * e, u = l * e;
41
41
  return {
42
- x: a * o.x + 3 * r * e * s.x + 3 * i * l * n.x + u * c.x,
43
- y: a * o.y + 3 * r * e * s.y + 3 * i * l * n.y + u * c.y
42
+ x: a * s.x + 3 * c * e * n.x + 3 * r * l * o.x + u * i.x,
43
+ y: a * s.y + 3 * c * e * n.y + 3 * r * l * o.y + u * i.y
44
44
  };
45
45
  }
46
- function Y(t, e, o = 10) {
47
- return p(t, e) <= o;
46
+ function Y(t, e, s = 10) {
47
+ return y(t, e) <= s;
48
48
  }
49
49
  function N(t, e = 100) {
50
- const o = [{ t: 0, distance: 0 }];
51
- let s = t.p0, n = 0;
52
- for (let c = 1; c <= e; c++) {
53
- const i = c / e, r = D(t, i);
54
- n += p(s, r), o.push({ t: i, distance: n }), s = r;
50
+ const s = [{ t: 0, distance: 0 }];
51
+ let n = t.p0, o = 0;
52
+ for (let i = 1; i <= e; i++) {
53
+ const r = i / e, c = w(t, r);
54
+ o += y(n, c), s.push({ t: r, distance: o }), n = c;
55
55
  }
56
- return o;
56
+ return s;
57
57
  }
58
58
  function $(t, e) {
59
59
  if (e <= 0) return 0;
60
- const o = t[t.length - 1].distance;
61
- if (e >= o) return 1;
62
- let s = 0, n = t.length - 1;
63
- for (; s < n - 1; ) {
64
- const u = Math.floor((s + n) / 2);
65
- t[u].distance < e ? s = u : n = u;
60
+ const s = t[t.length - 1].distance;
61
+ if (e >= s) return 1;
62
+ let n = 0, o = t.length - 1;
63
+ for (; n < o - 1; ) {
64
+ const u = Math.floor((n + o) / 2);
65
+ t[u].distance < e ? n = u : o = u;
66
66
  }
67
- const c = t[s].distance, i = t[n].distance, r = t[s].t, a = t[n].t;
68
- if (i === c) return r;
69
- const l = (e - c) / (i - c);
70
- return r + l * (a - r);
67
+ const i = t[n].distance, r = t[o].distance, c = t[n].t, a = t[o].t;
68
+ if (r === i) return c;
69
+ const l = (e - i) / (r - i);
70
+ return c + l * (a - c);
71
71
  }
72
72
  function Z(t) {
73
73
  return t[t.length - 1].distance;
74
74
  }
75
75
  function G(t, e = 100) {
76
- let o = 0, s = t.p0;
77
- for (let n = 1; n <= e; n++) {
78
- const c = n / e, i = D(t, c);
79
- o += p(s, i), s = i;
76
+ let s = 0, n = t.p0;
77
+ for (let o = 1; o <= e; o++) {
78
+ const i = o / e, r = w(t, i);
79
+ s += y(n, r), n = r;
80
80
  }
81
- return o;
81
+ return s;
82
82
  }
83
- function q(t, e, o, s, n) {
84
- const c = p(t.start, t.end), i = c - n;
85
- if (i <= 0)
86
- return c;
87
- let r;
83
+ function q(t, e, s, n, o) {
84
+ const i = y(t.start, t.end), r = i - o;
85
+ if (r <= 0)
86
+ return i;
87
+ let c;
88
88
  if (e === void 0)
89
- r = s;
90
- else if (o)
91
- r = e;
89
+ c = n;
90
+ else if (s)
91
+ c = e;
92
92
  else {
93
- const a = Math.max(0, Math.min(e, i));
94
- return n + a;
93
+ const a = Math.max(0, Math.min(e, r));
94
+ return o + a;
95
95
  }
96
- return n + r * i;
96
+ return o + c * r;
97
97
  }
98
- function z(t, e, o, s, n) {
99
- const i = p(t.start, t.end) - n;
100
- if (i <= 0)
98
+ function z(t, e, s, n, o) {
99
+ const r = y(t.start, t.end) - o;
100
+ if (r <= 0)
101
101
  return 0;
102
- let r;
102
+ let c;
103
103
  if (e === void 0)
104
- r = s;
105
- else if (o)
106
- r = e;
104
+ c = n;
105
+ else if (s)
106
+ c = e;
107
107
  else
108
- return Math.max(0, Math.min(e, i));
109
- return r * i;
110
- }
111
- function E(t, e, o) {
112
- const s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map();
113
- for (const i of t)
114
- n.set(i.id, i), c.set(i.id, p(i.start, i.end)), s.set(i.id, []);
115
- for (let i = 0; i < e.length; i++) {
116
- const r = e[i], a = n.get(r.fromLineId), l = n.get(r.toLineId);
108
+ return Math.max(0, Math.min(e, r));
109
+ return c * r;
110
+ }
111
+ function tt(t, e, s) {
112
+ const n = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
113
+ for (const r of t)
114
+ o.set(r.id, r), i.set(r.id, y(r.start, r.end)), n.set(r.id, []);
115
+ for (let r = 0; r < e.length; r++) {
116
+ const c = e[r], a = o.get(c.fromLineId), l = o.get(c.toLineId);
117
117
  if (!a || !l) continue;
118
- const u = q(a, r.fromOffset, r.fromIsPercentage, 1, o.wheelbase), d = z(l, r.toOffset, r.toIsPercentage, 0, o.wheelbase), g = b(
118
+ const u = q(a, c.fromOffset, c.fromIsPercentage, 1, s.wheelbase), d = z(l, c.toOffset, c.toIsPercentage, 0, s.wheelbase), g = A(
119
119
  a,
120
120
  l,
121
- o,
121
+ s,
122
122
  !1,
123
123
  // willFlip is always false now
124
124
  {
@@ -129,26 +129,26 @@ function E(t, e, o) {
129
129
  toIsPercentage: !1
130
130
  // Already resolved to absolute
131
131
  }
132
- ), I = G(g), m = {
133
- curveIndex: i,
134
- fromLineId: r.fromLineId,
135
- toLineId: r.toLineId,
132
+ ), x = G(g), m = {
133
+ curveIndex: r,
134
+ fromLineId: c.fromLineId,
135
+ toLineId: c.toLineId,
136
136
  fromOffset: u,
137
137
  toOffset: d,
138
- curveLength: I
138
+ curveLength: x
139
139
  };
140
- s.get(r.fromLineId).push(m);
140
+ n.get(c.fromLineId).push(m);
141
141
  }
142
- return { adjacency: s, lines: n, lineLengths: c };
142
+ return { adjacency: n, lines: o, lineLengths: i };
143
143
  }
144
- function A(t, e) {
144
+ function T(t, e) {
145
145
  return t.curveCount !== e.curveCount ? t.curveCount - e.curveCount : t.totalDistance - e.totalDistance;
146
146
  }
147
- function Q(t, e, o, s, n = !1) {
148
- const { adjacency: c, lines: i, lineLengths: r } = t;
149
- if (!i.get(o)) return null;
150
- const l = r.get(o), u = n ? s / 100 * l : s, d = [], g = /* @__PURE__ */ new Map(), I = (f, v) => `${f}:${Math.round(v)}`;
151
- if (e.lineId === o && u >= e.offset) {
147
+ function Q(t, e, s, n, o = !1) {
148
+ const { adjacency: i, lines: r, lineLengths: c } = t;
149
+ if (!r.get(s)) return null;
150
+ const l = c.get(s), u = o ? n / 100 * l : n, d = [], g = /* @__PURE__ */ new Map(), x = (f, v) => `${f}:${Math.round(v)}`;
151
+ if (e.lineId === s && u >= e.offset) {
152
152
  const f = u - e.offset;
153
153
  return {
154
154
  segments: [{
@@ -162,10 +162,10 @@ function Q(t, e, o, s, n = !1) {
162
162
  curveCount: 0
163
163
  };
164
164
  }
165
- const m = c.get(e.lineId) || [];
165
+ const m = i.get(e.lineId) || [];
166
166
  for (const f of m) {
167
167
  if (f.fromOffset < e.offset) continue;
168
- const v = f.fromOffset - e.offset, y = v + f.curveLength, x = {
168
+ const v = f.fromOffset - e.offset, I = v + f.curveLength, p = {
169
169
  type: "line",
170
170
  lineId: e.lineId,
171
171
  startOffset: e.offset,
@@ -181,45 +181,45 @@ function Q(t, e, o, s, n = !1) {
181
181
  d.push({
182
182
  lineId: f.toLineId,
183
183
  entryOffset: f.toOffset,
184
- totalDistance: y,
184
+ totalDistance: I,
185
185
  curveCount: 1,
186
- path: [x, h]
186
+ path: [p, h]
187
187
  });
188
188
  }
189
- for (d.sort(A); d.length > 0; ) {
190
- const f = d.shift(), v = I(f.lineId, f.entryOffset), y = g.get(v);
191
- if (y !== void 0 && (y.curveCount < f.curveCount || y.curveCount === f.curveCount && y.distance <= f.totalDistance))
189
+ for (d.sort(T); d.length > 0; ) {
190
+ const f = d.shift(), v = x(f.lineId, f.entryOffset), I = g.get(v);
191
+ if (I !== void 0 && (I.curveCount < f.curveCount || I.curveCount === f.curveCount && I.distance <= f.totalDistance))
192
192
  continue;
193
- if (g.set(v, { curveCount: f.curveCount, distance: f.totalDistance }), f.lineId === o) {
193
+ if (g.set(v, { curveCount: f.curveCount, distance: f.totalDistance }), f.lineId === s) {
194
194
  const h = Math.abs(u - f.entryOffset);
195
195
  if (u >= f.entryOffset) {
196
- const O = {
196
+ const L = {
197
197
  type: "line",
198
- lineId: o,
198
+ lineId: s,
199
199
  startOffset: f.entryOffset,
200
200
  endOffset: u,
201
201
  length: h
202
202
  };
203
203
  return {
204
- segments: [...f.path, O],
204
+ segments: [...f.path, L],
205
205
  totalDistance: f.totalDistance + h,
206
206
  curveCount: f.curveCount
207
207
  };
208
208
  }
209
209
  }
210
- const x = c.get(f.lineId) || [];
211
- for (const h of x) {
210
+ const p = i.get(f.lineId) || [];
211
+ for (const h of p) {
212
212
  if (h.fromOffset < f.entryOffset) continue;
213
- const O = h.fromOffset - f.entryOffset, T = f.totalDistance + O + h.curveLength, C = f.curveCount + 1, B = I(h.toLineId, h.toOffset), M = g.get(B);
214
- if (M !== void 0 && (M.curveCount < C || M.curveCount === C && M.distance <= T))
213
+ const L = h.fromOffset - f.entryOffset, S = f.totalDistance + L + h.curveLength, C = f.curveCount + 1, B = x(h.toLineId, h.toOffset), M = g.get(B);
214
+ if (M !== void 0 && (M.curveCount < C || M.curveCount === C && M.distance <= S))
215
215
  continue;
216
216
  const j = {
217
217
  type: "line",
218
218
  lineId: f.lineId,
219
219
  startOffset: f.entryOffset,
220
220
  endOffset: h.fromOffset,
221
- length: O
222
- }, F = {
221
+ length: L
222
+ }, k = {
223
223
  type: "curve",
224
224
  curveIndex: h.curveIndex,
225
225
  startOffset: 0,
@@ -229,196 +229,233 @@ function Q(t, e, o, s, n = !1) {
229
229
  d.push({
230
230
  lineId: h.toLineId,
231
231
  entryOffset: h.toOffset,
232
- totalDistance: T,
232
+ totalDistance: S,
233
233
  curveCount: C,
234
- path: [...f.path, j, F]
234
+ path: [...f.path, j, k]
235
235
  });
236
236
  }
237
- d.sort(A);
237
+ d.sort(T);
238
238
  }
239
239
  return null;
240
240
  }
241
241
  function V(t, e) {
242
- const o = Math.sqrt(
242
+ const s = Math.sqrt(
243
243
  Math.pow(t.end.x - t.start.x, 2) + Math.pow(t.end.y - t.start.y, 2)
244
- ), s = o > 0 ? e / o : 0;
244
+ ), n = s > 0 ? e / s : 0;
245
245
  return {
246
- x: t.start.x + (t.end.x - t.start.x) * Math.min(1, Math.max(0, s)),
247
- y: t.start.y + (t.end.y - t.start.y) * Math.min(1, Math.max(0, s))
246
+ x: t.start.x + (t.end.x - t.start.x) * Math.min(1, Math.max(0, n)),
247
+ y: t.start.y + (t.end.y - t.start.y) * Math.min(1, Math.max(0, n))
248
248
  };
249
249
  }
250
- function W(t) {
250
+ function F(t) {
251
251
  return Math.sqrt(
252
252
  Math.pow(t.end.x - t.start.x, 2) + Math.pow(t.end.y - t.start.y, 2)
253
253
  );
254
254
  }
255
- function _(t, e, o) {
256
- let s = 0;
257
- for (let n = 0; n < e; n++)
258
- s += t.segments[n].length;
259
- return s += o, s;
255
+ function W(t, e, s) {
256
+ let n = 0;
257
+ for (let o = 0; o < e; o++)
258
+ n += t.segments[o].length;
259
+ return n += s, n;
260
260
  }
261
- function H(t, e) {
262
- let o = 0;
263
- for (let s = 0; s < t.segments.length; s++) {
264
- const n = t.segments[s], c = o + n.length;
265
- if (e < c)
261
+ function _(t, e) {
262
+ let s = 0;
263
+ for (let n = 0; n < t.segments.length; n++) {
264
+ const o = t.segments[n], i = s + o.length;
265
+ if (e < i)
266
266
  return {
267
- segmentIndex: s,
268
- segmentDistance: e - o
267
+ segmentIndex: n,
268
+ segmentDistance: e - s
269
269
  };
270
- if (e === c)
271
- return s + 1 < t.segments.length ? {
272
- segmentIndex: s + 1,
270
+ if (e === i)
271
+ return n + 1 < t.segments.length ? {
272
+ segmentIndex: n + 1,
273
273
  segmentDistance: 0
274
274
  } : {
275
- segmentIndex: s,
276
- segmentDistance: n.length
275
+ segmentIndex: n,
276
+ segmentDistance: o.length
277
277
  };
278
- o += n.length;
278
+ s += o.length;
279
279
  }
280
280
  return null;
281
281
  }
282
- function tt(t, e, o, s) {
283
- const c = _(
282
+ function et(t, e, s, n) {
283
+ const i = W(
284
284
  t,
285
285
  e,
286
- o
287
- ) + s;
288
- return H(t, c);
286
+ s
287
+ ) + n;
288
+ return _(t, i);
289
289
  }
290
- function et(t, e, o, s) {
291
- const n = Math.sqrt(
292
- Math.pow(s.end.x - s.start.x, 2) + Math.pow(s.end.y - s.start.y, 2)
290
+ function nt(t, e, s, n) {
291
+ const o = Math.sqrt(
292
+ Math.pow(n.end.x - n.start.x, 2) + Math.pow(n.end.y - n.start.y, 2)
293
293
  );
294
- let c = e + o;
295
- c = Math.min(c, n);
296
- const i = V(s, c);
294
+ let i = e + s;
295
+ i = Math.min(i, o);
296
+ const r = V(n, i);
297
297
  return {
298
298
  lineId: t,
299
- position: i,
300
- absoluteOffset: c
299
+ position: r,
300
+ absoluteOffset: i
301
301
  };
302
302
  }
303
- function J(t, e) {
303
+ function H(t, e) {
304
304
  return {
305
305
  ...t,
306
306
  state: "idle"
307
307
  };
308
308
  }
309
- function R(t) {
309
+ function J(t) {
310
310
  return {
311
311
  vehicle: t,
312
312
  execution: null
313
313
  };
314
314
  }
315
- function nt(t, e) {
316
- const o = [], s = /* @__PURE__ */ new Map();
317
- for (const n of t) {
318
- if (!e.get(n.lineId)) continue;
319
- const i = J(n);
320
- o.push(i);
321
- const r = R(i);
322
- s.set(n.id, r);
315
+ function ot(t, e) {
316
+ const s = [], n = /* @__PURE__ */ new Map();
317
+ for (const o of t) {
318
+ if (!e.get(o.lineId)) continue;
319
+ const r = H(o);
320
+ s.push(r);
321
+ const c = J(r);
322
+ n.set(o.id, c);
323
323
  }
324
- return { movingVehicles: o, stateMap: s };
324
+ return { movingVehicles: s, stateMap: n };
325
325
  }
326
- function L(t, e) {
326
+ function O(t, e) {
327
327
  return { position: V(t, e), lineId: t.id, absoluteOffset: e };
328
328
  }
329
- function P(t, e) {
330
- const o = $(t.arcLengthTable, e);
331
- return { position: D(t.bezier, o) };
332
- }
333
- function st(t, e, o, s, n, c, i) {
334
- const r = o.segments[e.currentSegmentIndex], a = e.segmentDistance + s;
335
- if (a >= r.length) {
336
- const u = a - r.length, d = e.currentSegmentIndex + 1;
337
- if (d >= o.segments.length) {
338
- if (i !== void 0 && r.type === "line") {
339
- const f = n.get(r.lineId), v = r.startOffset + a;
340
- if (v <= i) {
341
- const x = L(f, v);
329
+ function E(t, e) {
330
+ const s = $(t.arcLengthTable, e);
331
+ return { position: w(t.bezier, s) };
332
+ }
333
+ function b(t, e, s, n, o, i, r) {
334
+ let c = e.currentSegmentIndex, a = e.segmentDistance, l = n;
335
+ for (; l > 0; ) {
336
+ const g = s.segments[c], x = g.length - a;
337
+ if (l < x) {
338
+ a += l, l = 0;
339
+ break;
340
+ }
341
+ l -= x;
342
+ const m = c + 1;
343
+ if (m >= s.segments.length) {
344
+ if (r !== void 0 && g.type === "line") {
345
+ const v = g.startOffset + g.length + l;
346
+ if (v <= r) {
347
+ const h = o.get(g.lineId), L = O(h, v);
342
348
  return {
343
- axleState: { ...t, ...x },
344
- execution: { ...e, segmentDistance: a },
349
+ axleState: { ...t, ...L },
350
+ execution: { currentSegmentIndex: c, segmentDistance: g.length + l },
345
351
  completed: !1
346
352
  };
347
353
  }
348
- const y = L(f, i);
354
+ const I = o.get(g.lineId), p = O(I, r);
349
355
  return {
350
- axleState: { ...t, ...y },
351
- execution: { ...e, segmentDistance: i - r.startOffset },
356
+ axleState: { ...t, ...p },
357
+ execution: { currentSegmentIndex: c, segmentDistance: r - g.startOffset },
352
358
  completed: !0
353
359
  };
354
360
  }
355
- const m = r.type === "line" ? L(
356
- n.get(r.lineId),
357
- r.endOffset
358
- ) : P(
359
- c.get(r.curveIndex),
360
- r.length
361
+ const f = g.type === "line" ? O(
362
+ o.get(g.lineId),
363
+ g.endOffset
364
+ ) : E(
365
+ i.get(g.curveIndex),
366
+ g.length
361
367
  );
362
368
  return {
363
- axleState: { ...t, ...m },
364
- execution: { ...e, segmentDistance: r.length },
369
+ axleState: { ...t, ...f },
370
+ execution: { currentSegmentIndex: c, segmentDistance: g.length },
365
371
  completed: !0
366
372
  };
367
373
  }
368
- const g = o.segments[d], I = g.type === "line" ? L(
369
- n.get(g.lineId),
370
- g.startOffset + u
371
- ) : P(
372
- c.get(g.curveIndex),
373
- u
374
- );
375
- return {
376
- axleState: { ...t, ...I },
377
- execution: {
378
- currentSegmentIndex: d,
379
- segmentDistance: u
380
- },
381
- completed: !1
382
- };
374
+ c = m, a = 0;
383
375
  }
384
- const l = r.type === "line" ? L(
385
- n.get(r.lineId),
386
- r.startOffset + a
387
- ) : P(
388
- c.get(r.curveIndex),
376
+ const u = s.segments[c], d = u.type === "line" ? O(
377
+ o.get(u.lineId),
378
+ u.startOffset + a
379
+ ) : E(
380
+ i.get(u.curveIndex),
389
381
  a
390
382
  );
391
383
  return {
392
- axleState: { ...t, ...l },
393
- execution: { ...e, segmentDistance: a },
384
+ axleState: { ...t, ...d },
385
+ execution: { currentSegmentIndex: c, segmentDistance: a },
394
386
  completed: !1
395
387
  };
396
388
  }
397
- function U(t, e, o, s) {
398
- const n = /* @__PURE__ */ new Map();
399
- for (const c of t.segments)
400
- if (c.type === "curve" && c.curveIndex !== void 0) {
401
- const i = e[c.curveIndex];
402
- if (i) {
403
- const r = o.get(i.fromLineId), a = o.get(i.toLineId);
404
- if (r && a) {
389
+ function st(t, e, s, n, o, i, r, c) {
390
+ const a = b(
391
+ t.rear,
392
+ t.rearExecution,
393
+ e,
394
+ s,
395
+ n,
396
+ o
397
+ );
398
+ let l;
399
+ const u = t.frontExecution.currentSegmentIndex;
400
+ if (u < e.segments.length) {
401
+ const x = e.segments[u];
402
+ if (x.type === "line") {
403
+ const m = n.get(x.lineId);
404
+ m && (l = F(m));
405
+ }
406
+ }
407
+ const d = b(
408
+ t.front,
409
+ t.frontExecution,
410
+ e,
411
+ s,
412
+ n,
413
+ o,
414
+ l
415
+ );
416
+ if (a.axleState.lineId === i && a.axleState.absoluteOffset >= r - 1e-3) {
417
+ const x = n.get(i), m = O(x, r), f = O(x, r + c);
418
+ return {
419
+ rear: { ...a.axleState, ...m },
420
+ front: { ...d.axleState, ...f },
421
+ rearExecution: a.execution,
422
+ frontExecution: d.execution,
423
+ arrived: !0
424
+ };
425
+ }
426
+ return {
427
+ rear: a.axleState,
428
+ front: d.axleState,
429
+ rearExecution: a.execution,
430
+ frontExecution: d.execution,
431
+ arrived: !1
432
+ };
433
+ }
434
+ function U(t, e, s, n) {
435
+ const o = /* @__PURE__ */ new Map();
436
+ for (const i of t.segments)
437
+ if (i.type === "curve" && i.curveIndex !== void 0) {
438
+ const r = e[i.curveIndex];
439
+ if (r) {
440
+ const c = s.get(r.fromLineId), a = s.get(r.toLineId);
441
+ if (c && a) {
405
442
  const l = q(
406
- r,
407
- i.fromOffset,
408
- i.fromIsPercentage,
443
+ c,
444
+ r.fromOffset,
445
+ r.fromIsPercentage,
409
446
  1,
410
447
  // Default: 100% = 1.0
411
- s.wheelbase
448
+ n.wheelbase
412
449
  ), u = z(
413
450
  a,
414
- i.toOffset,
415
- i.toIsPercentage,
451
+ r.toOffset,
452
+ r.toIsPercentage,
416
453
  0,
417
- s.wheelbase
418
- ), d = b(
419
- r,
454
+ n.wheelbase
455
+ ), d = A(
456
+ c,
420
457
  a,
421
- s,
458
+ n,
422
459
  !1,
423
460
  // willFlip is always false now
424
461
  {
@@ -430,76 +467,77 @@ function U(t, e, o, s) {
430
467
  // Already resolved to absolute
431
468
  }
432
469
  ), g = N(d);
433
- n.set(c.curveIndex, { bezier: d, arcLengthTable: g });
470
+ o.set(i.curveIndex, { bezier: d, arcLengthTable: g });
434
471
  }
435
472
  }
436
473
  }
437
- return n;
474
+ return o;
438
475
  }
439
- function ot(t, e, o) {
440
- const { graph: s, linesMap: n, curves: c, config: i } = o, r = n.get(e.targetLineId);
441
- if (!r) return null;
442
- const l = W(r) - i.wheelbase;
476
+ function rt(t, e, s) {
477
+ const { graph: n, linesMap: o, curves: i, config: r } = s, c = o.get(e.targetLineId);
478
+ if (!c) return null;
479
+ const l = F(c) - r.wheelbase;
443
480
  if (l <= 0) return null;
444
481
  const u = e.isPercentage ? e.targetOffset * l : Math.min(e.targetOffset, l), d = Q(
445
- s,
482
+ n,
446
483
  { lineId: t.rear.lineId, offset: t.rear.absoluteOffset },
447
484
  e.targetLineId,
448
485
  u,
449
486
  !1
450
487
  );
451
488
  if (!d) return null;
452
- const g = U(d, c, n, i);
489
+ const g = U(d, i, o, r);
453
490
  return { path: d, curveDataMap: g };
454
491
  }
455
- function rt(t, e) {
456
- const o = t.execution, n = e.vehicleQueues.get(t.vehicle.id)?.[o.currentCommandIndex];
457
- return n && e.onCommandComplete && e.onCommandComplete({
492
+ function ct(t, e) {
493
+ const s = t.execution, o = e.vehicleQueues.get(t.vehicle.id)?.[s.currentCommandIndex];
494
+ return o && e.onCommandComplete && e.onCommandComplete({
458
495
  vehicleId: t.vehicle.id,
459
- command: n,
496
+ command: o,
460
497
  finalPosition: {
461
498
  lineId: t.vehicle.rear.lineId,
462
499
  absoluteOffset: t.vehicle.rear.absoluteOffset,
463
500
  position: t.vehicle.rear.position
464
501
  },
465
- payload: n.payload
502
+ payload: o.payload
466
503
  }), {
467
504
  handled: !0,
468
505
  vehicle: { ...t.vehicle, state: "waiting" },
469
- newExecution: o,
506
+ newExecution: s,
470
507
  // Keep execution state for resume
471
508
  isWaiting: !0
472
509
  };
473
510
  }
474
511
  export {
475
- H as arcLengthToSegmentPosition,
512
+ _ as arcLengthToSegmentPosition,
476
513
  N as buildArcLengthTable,
477
- E as buildGraph,
514
+ tt as buildGraph,
478
515
  G as calculateBezierArcLength,
479
- tt as calculateFrontAxlePosition,
480
- et as calculateInitialFrontPosition,
481
- P as calculatePositionOnCurve,
482
- L as calculatePositionOnLine,
516
+ et as calculateFrontAxlePosition,
517
+ nt as calculateInitialFrontPosition,
518
+ E as calculatePositionOnCurve,
519
+ O as calculatePositionOnLine,
483
520
  K as calculateTangentLength,
484
- b as createBezierCurve,
485
- R as createInitialMovementState,
486
- p as distance,
521
+ A as createBezierCurve,
522
+ J as createInitialMovementState,
523
+ y as distance,
487
524
  $ as distanceToT,
488
525
  Q as findPath,
489
526
  Z as getArcLength,
490
- _ as getCumulativeArcLength,
491
- W as getLineLength,
492
- D as getPointOnBezier,
493
- k as getPointOnLine,
494
- S as getPointOnLineByOffset,
527
+ W as getCumulativeArcLength,
528
+ F as getLineLength,
529
+ w as getPointOnBezier,
530
+ R as getPointOnLine,
531
+ D as getPointOnLineByOffset,
495
532
  V as getPositionFromOffset,
496
- rt as handleArrival,
497
- nt as initializeAllVehicles,
498
- J as initializeMovingVehicle,
533
+ ct as handleArrival,
534
+ ot as initializeAllVehicles,
535
+ H as initializeMovingVehicle,
499
536
  Y as isPointNearPoint,
500
- w as normalize,
501
- ot as prepareCommandPath,
537
+ st as moveVehicle,
538
+ P as normalize,
539
+ rt as prepareCommandPath,
502
540
  q as resolveFromLineOffset,
503
541
  z as resolveToLineOffset,
504
- st as updateAxlePosition
542
+ b as updateAxlePosition
505
543
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vehicle-path2",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "description": "Vehicle motion simulator library for dual-axle vehicle movement along paths composed of lines and Bezier curves",
5
5
  "type": "module",
6
6
  "main": "./dist/vehicle-path.cjs",