vehicle-path2 1.0.14 → 2.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.
Files changed (40) hide show
  1. package/README.md +168 -168
  2. package/dist/core/algorithms/pathFinding.d.ts +2 -2
  3. package/dist/core/algorithms/vehicleMovement.d.ts +29 -20
  4. package/dist/core/engine.d.ts +160 -0
  5. package/dist/core/index.d.ts +3 -2
  6. package/dist/core/types/api.d.ts +9 -0
  7. package/dist/core/types/movement.d.ts +2 -3
  8. package/dist/core/types/vehicle.d.ts +4 -2
  9. package/dist/core.cjs +1 -1
  10. package/dist/core.js +33 -541
  11. package/dist/index.d.ts +4 -34
  12. package/dist/utils/event-emitter.d.ts +4 -6
  13. package/dist/vehicle-path.cjs +1 -1
  14. package/dist/vehicle-path.js +729 -59
  15. package/package.json +83 -103
  16. package/dist/animation-loop-bZEm2pMN.js +0 -37
  17. package/dist/animation-loop-fC2LjxCd.cjs +0 -1
  18. package/dist/react/dsl-hooks/useInitialMovement.d.ts +0 -24
  19. package/dist/react/dsl-hooks/useMovementSequence.d.ts +0 -27
  20. package/dist/react/dsl-hooks/useSceneDefinition.d.ts +0 -22
  21. package/dist/react/hooks/useAnimation.d.ts +0 -47
  22. package/dist/react/hooks/useMovementQueue.d.ts +0 -53
  23. package/dist/react/hooks/useScene.d.ts +0 -78
  24. package/dist/react/hooks/useVehicleSimulation.d.ts +0 -128
  25. package/dist/react/hooks/useVehicles.d.ts +0 -55
  26. package/dist/react/index.d.ts +0 -48
  27. package/dist/react/providers/useVehicleEvents.d.ts +0 -78
  28. package/dist/react.cjs +0 -1
  29. package/dist/react.js +0 -18
  30. package/dist/useVehicleEvents-BZVmIugl.cjs +0 -3
  31. package/dist/useVehicleEvents-CabztfQ4.js +0 -940
  32. package/dist/utils/animation-loop.d.ts +0 -105
  33. package/dist/utils/dsl-parser.d.ts +0 -151
  34. package/dist/utils/index.d.ts +0 -15
  35. package/dist/utils/type-converters.d.ts +0 -40
  36. package/dist/utils/vehicle-helpers.d.ts +0 -8
  37. package/dist/utils.cjs +0 -1
  38. package/dist/utils.js +0 -17
  39. package/dist/vehicle-helpers-BgD4BTAJ.js +0 -275
  40. package/dist/vehicle-helpers-DrnYWjm3.cjs +0 -7
package/dist/core.cjs CHANGED
@@ -1 +1 @@
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;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./vehicle-path.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.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;
package/dist/core.js CHANGED
@@ -1,543 +1,35 @@
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
- }
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
- }
9
- function K(t, e) {
10
- return e * (t === "proportional-40" ? 0.4 : 0.5522);
11
- }
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
- let a;
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
- // Transition with flip: kurva dimulai dari P (baseP0 - wheelbase in line direction)
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
- x: a.x - g.x * m,
24
- y: a.y - g.y * m
25
- };
26
- return { p0: u, p1: f, p2: v, p3: a };
27
- }
28
- function R(t, e) {
29
- return {
30
- x: t.start.x + (t.end.x - t.start.x) * e,
31
- y: t.start.y + (t.end.y - t.start.y) * e
32
- };
33
- }
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
- }
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
- return {
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
- };
45
- }
46
- function Y(t, e, s = 10) {
47
- return y(t, e) <= s;
48
- }
49
- function N(t, e = 100) {
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
- }
56
- return s;
57
- }
58
- function $(t, e) {
59
- if (e <= 0) return 0;
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
- }
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
- }
72
- function Z(t) {
73
- return t[t.length - 1].distance;
74
- }
75
- function G(t, e = 100) {
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
- }
81
- return s;
82
- }
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
- if (e === void 0)
89
- c = n;
90
- else if (s)
91
- c = e;
92
- else {
93
- const a = Math.max(0, Math.min(e, r));
94
- return o + a;
95
- }
96
- return o + c * r;
97
- }
98
- function z(t, e, s, n, o) {
99
- const r = y(t.start, t.end) - o;
100
- if (r <= 0)
101
- return 0;
102
- let c;
103
- if (e === void 0)
104
- c = n;
105
- else if (s)
106
- c = e;
107
- else
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
- if (!a || !l) continue;
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
- a,
120
- l,
121
- s,
122
- !1,
123
- // willFlip is always false now
124
- {
125
- fromOffset: u,
126
- fromIsPercentage: !1,
127
- // Already resolved to absolute
128
- toOffset: d,
129
- toIsPercentage: !1
130
- // Already resolved to absolute
131
- }
132
- ), x = G(g), m = {
133
- curveIndex: r,
134
- fromLineId: c.fromLineId,
135
- toLineId: c.toLineId,
136
- fromOffset: u,
137
- toOffset: d,
138
- curveLength: x
139
- };
140
- n.get(c.fromLineId).push(m);
141
- }
142
- return { adjacency: n, lines: o, lineLengths: i };
143
- }
144
- function T(t, e) {
145
- return t.curveCount !== e.curveCount ? t.curveCount - e.curveCount : t.totalDistance - e.totalDistance;
146
- }
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
- const f = u - e.offset;
153
- return {
154
- segments: [{
155
- type: "line",
156
- lineId: e.lineId,
157
- startOffset: e.offset,
158
- endOffset: u,
159
- length: f
160
- }],
161
- totalDistance: f,
162
- curveCount: 0
163
- };
164
- }
165
- const m = i.get(e.lineId) || [];
166
- for (const f of m) {
167
- if (f.fromOffset < e.offset) continue;
168
- const v = f.fromOffset - e.offset, I = v + f.curveLength, p = {
169
- type: "line",
170
- lineId: e.lineId,
171
- startOffset: e.offset,
172
- endOffset: f.fromOffset,
173
- length: v
174
- }, h = {
175
- type: "curve",
176
- curveIndex: f.curveIndex,
177
- startOffset: 0,
178
- endOffset: f.curveLength,
179
- length: f.curveLength
180
- };
181
- d.push({
182
- lineId: f.toLineId,
183
- entryOffset: f.toOffset,
184
- totalDistance: I,
185
- curveCount: 1,
186
- path: [p, h]
187
- });
188
- }
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
- continue;
193
- if (g.set(v, { curveCount: f.curveCount, distance: f.totalDistance }), f.lineId === s) {
194
- const h = Math.abs(u - f.entryOffset);
195
- if (u >= f.entryOffset) {
196
- const L = {
197
- type: "line",
198
- lineId: s,
199
- startOffset: f.entryOffset,
200
- endOffset: u,
201
- length: h
202
- };
203
- return {
204
- segments: [...f.path, L],
205
- totalDistance: f.totalDistance + h,
206
- curveCount: f.curveCount
207
- };
208
- }
209
- }
210
- const p = i.get(f.lineId) || [];
211
- for (const h of p) {
212
- if (h.fromOffset < f.entryOffset) continue;
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
- continue;
216
- const j = {
217
- type: "line",
218
- lineId: f.lineId,
219
- startOffset: f.entryOffset,
220
- endOffset: h.fromOffset,
221
- length: L
222
- }, k = {
223
- type: "curve",
224
- curveIndex: h.curveIndex,
225
- startOffset: 0,
226
- endOffset: h.curveLength,
227
- length: h.curveLength
228
- };
229
- d.push({
230
- lineId: h.toLineId,
231
- entryOffset: h.toOffset,
232
- totalDistance: S,
233
- curveCount: C,
234
- path: [...f.path, j, k]
235
- });
236
- }
237
- d.sort(T);
238
- }
239
- return null;
240
- }
241
- function V(t, e) {
242
- const s = Math.sqrt(
243
- Math.pow(t.end.x - t.start.x, 2) + Math.pow(t.end.y - t.start.y, 2)
244
- ), n = s > 0 ? e / s : 0;
245
- return {
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
- };
249
- }
250
- function F(t) {
251
- return Math.sqrt(
252
- Math.pow(t.end.x - t.start.x, 2) + Math.pow(t.end.y - t.start.y, 2)
253
- );
254
- }
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
- }
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
- return {
267
- segmentIndex: n,
268
- segmentDistance: e - s
269
- };
270
- if (e === i)
271
- return n + 1 < t.segments.length ? {
272
- segmentIndex: n + 1,
273
- segmentDistance: 0
274
- } : {
275
- segmentIndex: n,
276
- segmentDistance: o.length
277
- };
278
- s += o.length;
279
- }
280
- return null;
281
- }
282
- function et(t, e, s, n) {
283
- const i = W(
284
- t,
285
- e,
286
- s
287
- ) + n;
288
- return _(t, i);
289
- }
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
- );
294
- let i = e + s;
295
- i = Math.min(i, o);
296
- const r = V(n, i);
297
- return {
298
- lineId: t,
299
- position: r,
300
- absoluteOffset: i
301
- };
302
- }
303
- function H(t, e) {
304
- return {
305
- ...t,
306
- state: "idle"
307
- };
308
- }
309
- function J(t) {
310
- return {
311
- vehicle: t,
312
- execution: null
313
- };
314
- }
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
- }
324
- return { movingVehicles: s, stateMap: n };
325
- }
326
- function O(t, e) {
327
- return { position: V(t, e), lineId: t.id, absoluteOffset: e };
328
- }
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);
348
- return {
349
- axleState: { ...t, ...L },
350
- execution: { currentSegmentIndex: c, segmentDistance: g.length + l },
351
- completed: !1
352
- };
353
- }
354
- const I = o.get(g.lineId), p = O(I, r);
355
- return {
356
- axleState: { ...t, ...p },
357
- execution: { currentSegmentIndex: c, segmentDistance: r - g.startOffset },
358
- completed: !0
359
- };
360
- }
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
367
- );
368
- return {
369
- axleState: { ...t, ...f },
370
- execution: { currentSegmentIndex: c, segmentDistance: g.length },
371
- completed: !0
372
- };
373
- }
374
- c = m, a = 0;
375
- }
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),
381
- a
382
- );
383
- return {
384
- axleState: { ...t, ...d },
385
- execution: { currentSegmentIndex: c, segmentDistance: a },
386
- completed: !1
387
- };
388
- }
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) {
442
- const l = q(
443
- c,
444
- r.fromOffset,
445
- r.fromIsPercentage,
446
- 1,
447
- // Default: 100% = 1.0
448
- n.wheelbase
449
- ), u = z(
450
- a,
451
- r.toOffset,
452
- r.toIsPercentage,
453
- 0,
454
- n.wheelbase
455
- ), d = A(
456
- c,
457
- a,
458
- n,
459
- !1,
460
- // willFlip is always false now
461
- {
462
- fromOffset: l,
463
- fromIsPercentage: !1,
464
- // Already resolved to absolute
465
- toOffset: u,
466
- toIsPercentage: !1
467
- // Already resolved to absolute
468
- }
469
- ), g = N(d);
470
- o.set(i.curveIndex, { bezier: d, arcLengthTable: g });
471
- }
472
- }
473
- }
474
- return o;
475
- }
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;
480
- if (l <= 0) return null;
481
- const u = e.isPercentage ? e.targetOffset * l : Math.min(e.targetOffset, l), d = Q(
482
- n,
483
- { lineId: t.rear.lineId, offset: t.rear.absoluteOffset },
484
- e.targetLineId,
485
- u,
486
- !1
487
- );
488
- if (!d) return null;
489
- const g = U(d, i, o, r);
490
- return { path: d, curveDataMap: g };
491
- }
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({
495
- vehicleId: t.vehicle.id,
496
- command: o,
497
- finalPosition: {
498
- lineId: t.vehicle.rear.lineId,
499
- absoluteOffset: t.vehicle.rear.absoluteOffset,
500
- position: t.vehicle.rear.position
501
- },
502
- payload: o.payload
503
- }), {
504
- handled: !0,
505
- vehicle: { ...t.vehicle, state: "waiting" },
506
- newExecution: s,
507
- // Keep execution state for resume
508
- isWaiting: !0
509
- };
510
- }
1
+ import { PathEngine as i, arcLengthToSegmentPosition as n, buildArcLengthTable as a, buildGraph as o, calculateBezierArcLength as l, calculateFrontAxlePosition as r, calculateInitialAxlePositions as c, calculatePositionOnCurve as s, calculatePositionOnLine as g, c as h, createBezierCurve as P, createInitialMovementState as u, distance as L, distanceToT as f, findPath as m, getArcLength as v, getCumulativeArcLength as A, getLineLength as O, getPointOnBezier as d, getPointOnLine as z, getPointOnLineByOffset as T, getPositionFromOffset as p, handleArrival as x, initializeAllVehicles as B, initializeMovingVehicle as C, i as b, moveVehicle as F, normalize as V, prepareCommandPath as I, resolveFromLineOffset as M, resolveToLineOffset as S, updateAxlePosition as y } from "./vehicle-path.js";
511
2
  export {
512
- _ as arcLengthToSegmentPosition,
513
- N as buildArcLengthTable,
514
- tt as buildGraph,
515
- G as calculateBezierArcLength,
516
- et as calculateFrontAxlePosition,
517
- nt as calculateInitialFrontPosition,
518
- E as calculatePositionOnCurve,
519
- O as calculatePositionOnLine,
520
- K as calculateTangentLength,
521
- A as createBezierCurve,
522
- J as createInitialMovementState,
523
- y as distance,
524
- $ as distanceToT,
525
- Q as findPath,
526
- Z as getArcLength,
527
- W as getCumulativeArcLength,
528
- F as getLineLength,
529
- w as getPointOnBezier,
530
- R as getPointOnLine,
531
- D as getPointOnLineByOffset,
532
- V as getPositionFromOffset,
533
- ct as handleArrival,
534
- ot as initializeAllVehicles,
535
- H as initializeMovingVehicle,
536
- Y as isPointNearPoint,
537
- st as moveVehicle,
538
- P as normalize,
539
- rt as prepareCommandPath,
540
- q as resolveFromLineOffset,
541
- z as resolveToLineOffset,
542
- b as updateAxlePosition
3
+ i as PathEngine,
4
+ n as arcLengthToSegmentPosition,
5
+ a as buildArcLengthTable,
6
+ o as buildGraph,
7
+ l as calculateBezierArcLength,
8
+ r as calculateFrontAxlePosition,
9
+ c as calculateInitialAxlePositions,
10
+ s as calculatePositionOnCurve,
11
+ g as calculatePositionOnLine,
12
+ h as calculateTangentLength,
13
+ P as createBezierCurve,
14
+ u as createInitialMovementState,
15
+ L as distance,
16
+ f as distanceToT,
17
+ m as findPath,
18
+ v as getArcLength,
19
+ A as getCumulativeArcLength,
20
+ O as getLineLength,
21
+ d as getPointOnBezier,
22
+ z as getPointOnLine,
23
+ T as getPointOnLineByOffset,
24
+ p as getPositionFromOffset,
25
+ x as handleArrival,
26
+ B as initializeAllVehicles,
27
+ C as initializeMovingVehicle,
28
+ b as isPointNearPoint,
29
+ F as moveVehicle,
30
+ V as normalize,
31
+ I as prepareCommandPath,
32
+ M as resolveFromLineOffset,
33
+ S as resolveToLineOffset,
34
+ y as updateAxlePosition
543
35
  };
package/dist/index.d.ts CHANGED
@@ -1,45 +1,15 @@
1
1
  /**
2
2
  * VehiclePath - Vehicle motion simulator library
3
3
  *
4
- * A library for simulating dual-axle vehicle movement along paths
4
+ * Core library for simulating multi-axle vehicle movement along paths
5
5
  * composed of lines and Bezier curves.
6
- *
7
- * @example
8
- * ```typescript
9
- * import { useVehicleSimulation } from 'vehicle-path'
10
- *
11
- * const sim = useVehicleSimulation({ wheelbase: 30 })
12
- * sim.addLine({ id: 'line1', start: [0, 0], end: [400, 0] })
13
- * sim.addVehicles({ id: 'v1', lineId: 'line1', position: 0 })
14
- * sim.goto('v1', 'line1', 1.0)
15
- * sim.prepare()
16
- * sim.tick(5)
17
- * ```
18
6
  */
19
7
  export type { Point, Line, BezierCurve, Curve } from './core/types/geometry';
20
8
  export type { VehicleState, VehicleStart, Vehicle, AxleState, GotoCommand, GotoCompletionInfo, GotoCompletionCallback } from './core/types/vehicle';
21
- export type { CurveData, PathExecutionState, VehicleMovementState, MovementConfig, SceneContext } from './core/types/movement';
9
+ export type { CurveData, AxleExecutionState, PathExecutionState, VehicleMovementState, MovementConfig, SceneContext } from './core/types/movement';
22
10
  export type { TangentMode } from './core/types/config';
23
11
  export type { CoordinateInput, SceneLineInput, SceneConnectionInput, SceneConfig, VehicleInput, VehicleUpdateInput, ConnectionUpdateInput, GotoInput, GotoCommandInput, MovementCommandInput, SimulationConfig } from './core/types/api';
24
12
  export { buildGraph, findPath, calculateBezierArcLength, resolveFromLineOffset, resolveToLineOffset, type Graph, type GraphEdge, type PathSegment, type PathResult, type VehiclePosition } from './core/algorithms/pathFinding';
25
- 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 './core/algorithms/vehicleMovement';
13
+ export { initializeMovingVehicle, createInitialMovementState, initializeAllVehicles, calculateInitialAxlePositions, type InitializationResult, updateAxlePosition, calculatePositionOnLine, calculatePositionOnCurve, calculateFrontAxlePosition, getCumulativeArcLength, arcLengthToSegmentPosition, prepareCommandPath, type PreparedPath, handleArrival, type SegmentCompletionContext, type SegmentCompletionResult, type SegmentVehicleState, moveVehicle, getPositionFromOffset, getLineLength } from './core/algorithms/vehicleMovement';
14
+ export { PathEngine, type PathEngineConfig, type VehiclePathState, type PathExecution } from './core/engine';
26
15
  export { distance, normalize, getPointOnLine, getPointOnLineByOffset, getPointOnBezier, createBezierCurve, buildArcLengthTable, distanceToT, getArcLength, type ArcLengthEntry, type CurveOffsetOptions } from './core/algorithms/math';
27
- export { VehicleEventEmitter, type VehicleEventMap, type VehicleEventType, type VehicleEventCallback, type VehiclePositionUpdate, type Unsubscribe, type CommandStartInfo } from './utils/event-emitter';
28
- export { parseSceneDSL, parseVehiclesDSL, parseMovementDSL, parseAllDSL, generateSceneDSL, generateVehiclesDSL, generateMovementDSL, type ParseResult, type MovementCommand } from './utils/dsl-parser';
29
- export { createAnimationLoop, useAnimationLoop, type AnimationLoopOptions, type AnimationLoopControls } from './utils/animation-loop';
30
- export { validateAndCreateVehicles, getNextStartVehicleId, getNextGotoVehicleId } from './utils/vehicle-helpers';
31
- export { useVehicleSimulation, type UseVehicleSimulationProps, type UseVehicleSimulationResult, type SimulationWarning, type SimulationResult } from './react/hooks/useVehicleSimulation';
32
- export { useScene, type UseSceneResult } from './react/hooks/useScene';
33
- export { useVehicles, type UseVehiclesResult, type UseVehiclesProps } from './react/hooks/useVehicles';
34
- export { useMovementQueue, type UseMovementQueueResult, type UseMovementQueueProps } from './react/hooks/useMovementQueue';
35
- export { useAnimation, type UseAnimationProps } from './react/hooks/useAnimation';
36
- /** @deprecated Use useMovementQueue instead */
37
- export { useMovementQueue as useMovement } from './react/hooks/useMovementQueue';
38
- export type { UseMovementQueueResult as UseMovementResult } from './react/hooks/useMovementQueue';
39
- export type { UseMovementQueueProps as UseMovementProps } from './react/hooks/useMovementQueue';
40
- /** @deprecated Use useAnimation instead */
41
- export { useAnimation as useVehicleMovement } from './react/hooks/useAnimation';
42
- export { useSceneDefinition } from './react/dsl-hooks/useSceneDefinition';
43
- export { useInitialMovement } from './react/dsl-hooks/useInitialMovement';
44
- export { useMovementSequence } from './react/dsl-hooks/useMovementSequence';
45
- export { useVehicleEventEmitter, useCreateVehicleEventEmitter, useVehicleEvent, VehicleEventContext, VehicleEventProvider, type VehicleEventProviderProps } from './react/providers/useVehicleEvents';
@@ -18,13 +18,11 @@ export interface CommandStartInfo {
18
18
  */
19
19
  export interface VehiclePositionUpdate {
20
20
  vehicleId: string;
21
- /** Rear axle position */
22
- rear: Point;
23
- /** Front axle position */
24
- front: Point;
25
- /** Center point between rear and front axles */
21
+ /** Posisi semua axle, axles[0] = terdepan */
22
+ axles: Point[];
23
+ /** Center vehicle (rata-rata semua axle) */
26
24
  center: Point;
27
- /** Angle in radians from rear to front (heading direction) */
25
+ /** Angle dari axle paling belakang ke terdepan */
28
26
  angle: number;
29
27
  }
30
28
  /**