vehicle-path2 1.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 (42) hide show
  1. package/README.md +160 -0
  2. package/dist/animation-loop-bZEm2pMN.js +37 -0
  3. package/dist/animation-loop-fC2LjxCd.cjs +1 -0
  4. package/dist/core/algorithms/math.d.ts +35 -0
  5. package/dist/core/algorithms/pathFinding.d.ts +62 -0
  6. package/dist/core/algorithms/vehicleMovement.d.ts +174 -0
  7. package/dist/core/index.d.ts +20 -0
  8. package/dist/core/types/api.d.ts +185 -0
  9. package/dist/core/types/config.d.ts +9 -0
  10. package/dist/core/types/geometry.d.ts +26 -0
  11. package/dist/core/types/movement.d.ts +56 -0
  12. package/dist/core/types/vehicle.d.ts +65 -0
  13. package/dist/core.cjs +1 -0
  14. package/dist/core.js +551 -0
  15. package/dist/index.d.ts +45 -0
  16. package/dist/react/dsl-hooks/useInitialMovement.d.ts +24 -0
  17. package/dist/react/dsl-hooks/useMovementSequence.d.ts +27 -0
  18. package/dist/react/dsl-hooks/useSceneDefinition.d.ts +22 -0
  19. package/dist/react/hooks/useAnimation.d.ts +43 -0
  20. package/dist/react/hooks/useMovementQueue.d.ts +52 -0
  21. package/dist/react/hooks/useScene.d.ts +78 -0
  22. package/dist/react/hooks/useVehicleSimulation.d.ts +126 -0
  23. package/dist/react/hooks/useVehicles.d.ts +55 -0
  24. package/dist/react/index.d.ts +48 -0
  25. package/dist/react/providers/useVehicleEvents.d.ts +78 -0
  26. package/dist/react.cjs +1 -0
  27. package/dist/react.js +18 -0
  28. package/dist/useVehicleEvents-B2JQFNjc.js +923 -0
  29. package/dist/useVehicleEvents-CBymulau.cjs +3 -0
  30. package/dist/utils/animation-loop.d.ts +105 -0
  31. package/dist/utils/dsl-parser.d.ts +152 -0
  32. package/dist/utils/event-emitter.d.ts +94 -0
  33. package/dist/utils/index.d.ts +15 -0
  34. package/dist/utils/type-converters.d.ts +38 -0
  35. package/dist/utils/vehicle-helpers.d.ts +8 -0
  36. package/dist/utils.cjs +1 -0
  37. package/dist/utils.js +17 -0
  38. package/dist/vehicle-helpers-DIcksrtO.cjs +7 -0
  39. package/dist/vehicle-helpers-_72KxCqO.js +276 -0
  40. package/dist/vehicle-path.cjs +1 -0
  41. package/dist/vehicle-path.js +62 -0
  42. package/package.json +103 -0
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Core geometry types for the bezier-path system
3
+ */
4
+ export interface Point {
5
+ x: number;
6
+ y: number;
7
+ }
8
+ export interface Line {
9
+ id: string;
10
+ start: Point;
11
+ end: Point;
12
+ }
13
+ export interface BezierCurve {
14
+ p0: Point;
15
+ p1: Point;
16
+ p2: Point;
17
+ p3: Point;
18
+ }
19
+ export interface Curve {
20
+ fromLineId: string;
21
+ toLineId: string;
22
+ fromOffset?: number;
23
+ fromIsPercentage?: boolean;
24
+ toOffset?: number;
25
+ toIsPercentage?: boolean;
26
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Movement and animation state types
3
+ */
4
+ import type { Line, Curve, BezierCurve } from './geometry';
5
+ import type { Vehicle } from './vehicle';
6
+ import type { TangentMode } from './config';
7
+ export type { PathResult } from '../algorithms/pathFinding';
8
+ export type { ArcLengthEntry } from '../algorithms/math';
9
+ /**
10
+ * Bezier curve data with arc-length lookup table for animation
11
+ */
12
+ export interface CurveData {
13
+ bezier: BezierCurve;
14
+ arcLengthTable: import('../algorithms/math').ArcLengthEntry[];
15
+ }
16
+ /**
17
+ * Execution state for a single axle (Front or Rear)
18
+ */
19
+ export interface AxleExecutionState {
20
+ currentSegmentIndex: number;
21
+ segmentDistance: number;
22
+ }
23
+ /**
24
+ * State for path execution during animation
25
+ */
26
+ export interface PathExecutionState {
27
+ path: import('../algorithms/pathFinding').PathResult;
28
+ curveDataMap: Map<number, CurveData>;
29
+ currentCommandIndex: number;
30
+ rear: AxleExecutionState;
31
+ front: AxleExecutionState;
32
+ }
33
+ /**
34
+ * Movement state container for a vehicle
35
+ */
36
+ export interface VehicleMovementState {
37
+ vehicle: Vehicle;
38
+ execution: PathExecutionState | null;
39
+ }
40
+ /**
41
+ * Configuration for vehicle movement
42
+ */
43
+ export interface MovementConfig {
44
+ wheelbase: number;
45
+ tangentMode: TangentMode;
46
+ }
47
+ /**
48
+ * Scene context for path preparation and movement calculations
49
+ * Bundles commonly-passed together dependencies
50
+ */
51
+ export interface SceneContext {
52
+ config: MovementConfig;
53
+ graph: import('../algorithms/pathFinding').Graph;
54
+ linesMap: Map<string, Line>;
55
+ curves: Curve[];
56
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Vehicle-related types
3
+ */
4
+ import type { Point } from './geometry';
5
+ /**
6
+ * Animation state for a vehicle
7
+ */
8
+ export type VehicleState = 'idle' | 'moving' | 'waiting';
9
+ /**
10
+ * Vehicle start position (input from text parsing)
11
+ */
12
+ export interface VehicleStart {
13
+ vehicleId: string;
14
+ lineId: string;
15
+ offset: number;
16
+ isPercentage: boolean;
17
+ }
18
+ /**
19
+ * State for a single axle (Front or Rear)
20
+ */
21
+ export interface AxleState {
22
+ lineId: string;
23
+ position: Point;
24
+ absoluteOffset: number;
25
+ }
26
+ /**
27
+ * Vehicle with runtime state (used during animation)
28
+ */
29
+ export interface Vehicle {
30
+ id: string;
31
+ lineId: string;
32
+ offset: number;
33
+ isPercentage: boolean;
34
+ state: VehicleState;
35
+ rear: AxleState;
36
+ front: AxleState;
37
+ }
38
+ /**
39
+ * Command to move a vehicle to a target position
40
+ */
41
+ export interface GotoCommand {
42
+ vehicleId: string;
43
+ targetLineId: string;
44
+ targetOffset: number;
45
+ isPercentage: boolean;
46
+ awaitConfirmation?: boolean;
47
+ payload?: unknown;
48
+ }
49
+ /**
50
+ * Information provided when a goto command completes
51
+ */
52
+ export interface GotoCompletionInfo {
53
+ vehicleId: string;
54
+ command: GotoCommand;
55
+ finalPosition: {
56
+ lineId: string;
57
+ absoluteOffset: number;
58
+ position: Point;
59
+ };
60
+ payload?: unknown;
61
+ }
62
+ /**
63
+ * Callback type for goto command completion
64
+ */
65
+ export type GotoCompletionCallback = (info: GotoCompletionInfo) => void;
package/dist/core.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function p(e,t){const s=t.x-e.x,n=t.y-e.y;return Math.sqrt(s*s+n*n)}function P(e,t){const s=t.x-e.x,n=t.y-e.y,o=Math.sqrt(s*s+n*n);return o===0?{x:0,y:0}:{x:s/o,y:n/o}}function V(e,t){return t*(e==="proportional-40"?.4:.5522)}function C(e,t,s,n=!1,o){const{wheelbase:c,tangentMode:r}=s;let i;o?.fromOffset!==void 0?i=D(e,o.fromOffset,o.fromIsPercentage??!1):i=e.end;let l;o?.toOffset!==void 0?l=D(t,o.toOffset,o.toIsPercentage??!1):l=t.start;const d=P(e.start,e.end),f=n?{x:i.x-d.x*c,y:i.y-d.y*c}:i,u=P(e.start,e.end),g=P(t.start,t.end),I=p(f,l),v=V(r,I),a=n?{x:f.x-u.x*v,y:f.y-u.y*v}:{x:f.x+u.x*v,y:f.y+u.y*v},m={x:l.x-g.x*v,y:l.y-g.y*v};return{p0:f,p1:a,p2:m,p3:l}}function B(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 D(e,t,s){const n=p(e.start,e.end);let o;return s?o=t/100:o=n>0?t/n:0,o=Math.max(0,Math.min(1,o)),B(e,o)}function w(e,t){const{p0:s,p1:n,p2:o,p3:c}=e,r=1-t,i=r*r,l=i*r,d=t*t,f=d*t;return{x:l*s.x+3*i*t*n.x+3*r*d*o.x+f*c.x,y:l*s.y+3*i*t*n.y+3*r*d*o.y+f*c.y}}function H(e,t,s=10){return p(e,t)<=s}function q(e,t=100){const s=[{t:0,distance:0}];let n=e.p0,o=0;for(let c=1;c<=t;c++){const r=c/t,i=w(e,r);o+=p(n,i),s.push({t:r,distance:o}),n=i}return s}function F(e,t){if(t<=0)return 0;const s=e[e.length-1].distance;if(t>=s)return 1;let n=0,o=e.length-1;for(;n<o-1;){const f=Math.floor((n+o)/2);e[f].distance<t?n=f:o=f}const c=e[n].distance,r=e[o].distance,i=e[n].t,l=e[o].t;if(r===c)return i;const d=(t-c)/(r-c);return i+d*(l-i)}function J(e){return e[e.length-1].distance}function j(e,t=100){let s=0,n=e.p0;for(let o=1;o<=t;o++){const c=o/t,r=w(e,c);s+=p(n,r),n=r}return s}function S(e,t,s,n,o){const c=p(e.start,e.end),r=c-o;if(r<=0)return c;let i;if(t===void 0)i=n;else if(s)i=t;else return Math.max(o,Math.min(t,c));return o+i/100*r}function T(e,t,s,n,o){const r=p(e.start,e.end)-o;if(r<=0)return 0;let i;if(t===void 0)i=n;else if(s)i=t;else return Math.max(0,Math.min(t,r));return i/100*r}function U(e,t,s){const n=new Map,o=new Map,c=new Map;for(const r of e)o.set(r.id,r),c.set(r.id,p(r.start,r.end)),n.set(r.id,[]);for(let r=0;r<t.length;r++){const i=t[r],l=o.get(i.fromLineId),d=o.get(i.toLineId);if(!l||!d)continue;const f=S(l,i.fromOffset,i.fromIsPercentage,100,s.wheelbase),u=T(d,i.toOffset,i.toIsPercentage,0,s.wheelbase),g=C(l,d,s,!1,{fromOffset:f,fromIsPercentage:!1,toOffset:u,toIsPercentage:!1}),I=j(g),v={curveIndex:r,fromLineId:i.fromLineId,toLineId:i.toLineId,fromOffset:f,toOffset:u,curveLength:I};n.get(i.fromLineId).push(v)}return{adjacency:n,lines:o,lineLengths:c}}function K(e,t,s,n,o=!1){const{adjacency:c,lines:r,lineLengths:i}=e;if(!r.get(s))return null;const d=i.get(s),f=o?n/100*d:n,u=[],g=new Map,I=(a,m)=>`${a}:${Math.round(m)}`;if(t.lineId===s&&f>=t.offset){const a=f-t.offset;return{segments:[{type:"line",lineId:t.lineId,startOffset:t.offset,endOffset:f,length:a}],totalDistance:a}}const v=c.get(t.lineId)||[];for(const a of v){if(a.fromOffset<t.offset)continue;const m=a.fromOffset-t.offset,L=m+a.curveLength,x={type:"line",lineId:t.lineId,startOffset:t.offset,endOffset:a.fromOffset,length:m},h={type:"curve",curveIndex:a.curveIndex,startOffset:0,endOffset:a.curveLength,length:a.curveLength};u.push({lineId:a.toLineId,entryOffset:a.toOffset,totalDistance:L,path:[x,h]})}for(u.sort((a,m)=>a.totalDistance-m.totalDistance);u.length>0;){const a=u.shift(),m=I(a.lineId,a.entryOffset),L=g.get(m);if(L!==void 0&&L<=a.totalDistance)continue;if(g.set(m,a.totalDistance),a.lineId===s){const h=Math.abs(f-a.entryOffset);if(f>=a.entryOffset){const y={type:"line",lineId:s,startOffset:a.entryOffset,endOffset:f,length:h};return{segments:[...a.path,y],totalDistance:a.totalDistance+h}}}const x=c.get(a.lineId)||[];for(const h of x){if(h.fromOffset<a.entryOffset)continue;const y=h.fromOffset-a.entryOffset,A=a.totalDistance+y+h.curveLength,W=I(h.toLineId,h.toOffset),z=g.get(W);if(z!==void 0&&z<=A)continue;const _={type:"line",lineId:a.lineId,startOffset:a.entryOffset,endOffset:h.fromOffset,length:y},E={type:"curve",curveIndex:h.curveIndex,startOffset:0,endOffset:h.curveLength,length:h.curveLength};u.push({lineId:h.toLineId,entryOffset:h.toOffset,totalDistance:A,path:[...a.path,_,E]})}u.sort((h,y)=>h.totalDistance-y.totalDistance)}return null}function b(e,t){const s=Math.sqrt(Math.pow(e.end.x-e.start.x,2)+Math.pow(e.end.y-e.start.y,2)),n=s>0?t/s: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 G(e){return Math.sqrt(Math.pow(e.end.x-e.start.x,2)+Math.pow(e.end.y-e.start.y,2))}function N(e,t,s){let n=0;for(let o=0;o<t;o++)n+=e.segments[o].length;return n+=s,n}function $(e,t){let s=0;for(let n=0;n<e.segments.length;n++){const o=e.segments[n],c=s+o.length;if(t<c)return{segmentIndex:n,segmentDistance:t-s};if(t===c)return n+1<e.segments.length?{segmentIndex:n+1,segmentDistance:0}:{segmentIndex:n,segmentDistance:o.length};s+=o.length}return null}function k(e,t,s,n){const c=N(e,t,s)+n;return $(e,c)}function X(e,t,s,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+s;c=Math.min(c,o);const r=b(n,c);return{lineId:e,position:r,absoluteOffset:c}}function Q(e,t){return{...e,state:"idle"}}function R(e){return{vehicle:e,execution:null}}function Y(e,t){const s=[],n=new Map;for(const o of e){if(!t.get(o.lineId))continue;const r=Q(o);s.push(r);const i=R(r);n.set(o.id,i)}return{movingVehicles:s,stateMap:n}}function O(e,t){return{position:b(e,t),lineId:e.id,absoluteOffset:t}}function M(e,t){const s=F(e.arcLengthTable,t);return{position:w(e.bezier,s)}}function Z(e,t,s,n,o,c,r){const i=s.segments[t.currentSegmentIndex],l=t.segmentDistance+n;if(l>=i.length){const f=l-i.length,u=t.currentSegmentIndex+1;if(u>=s.segments.length){if(r!==void 0&&i.type==="line"){const a=o.get(i.lineId),m=i.startOffset+l;if(m<=r){const x=O(a,m);return{axleState:{...e,...x},execution:{...t,segmentDistance:l},completed:!1}}const L=O(a,r);return{axleState:{...e,...L},execution:{...t,segmentDistance:r-i.startOffset},completed:!0}}const v=i.type==="line"?O(o.get(i.lineId),i.endOffset):M(c.get(i.curveIndex),i.length);return{axleState:{...e,...v},execution:{...t,segmentDistance:i.length},completed:!0}}const g=s.segments[u],I=g.type==="line"?O(o.get(g.lineId),g.startOffset+f):M(c.get(g.curveIndex),f);return{axleState:{...e,...I},execution:{currentSegmentIndex:u,segmentDistance:f},completed:!1}}const d=i.type==="line"?O(o.get(i.lineId),i.startOffset+l):M(c.get(i.curveIndex),l);return{axleState:{...e,...d},execution:{...t,segmentDistance:l},completed:!1}}function ee(e,t,s,n){const o=new Map;for(const c of e.segments)if(c.type==="curve"&&c.curveIndex!==void 0){const r=t[c.curveIndex];if(r){const i=s.get(r.fromLineId),l=s.get(r.toLineId);if(i&&l){const d=S(i,r.fromOffset,r.fromIsPercentage,100,n.wheelbase),f=T(l,r.toOffset,r.toIsPercentage,0,n.wheelbase),u=C(i,l,n,!1,{fromOffset:d,fromIsPercentage:!1,toOffset:f,toIsPercentage:!1}),g=q(u);o.set(c.curveIndex,{bezier:u,arcLengthTable:g})}}}return o}function te(e,t,s){const{graph:n,linesMap:o,curves:c,config:r}=s,i=o.get(t.targetLineId);if(!i)return null;const d=G(i)-r.wheelbase;if(d<=0)return null;const f=t.isPercentage?t.targetOffset/100*d:Math.min(t.targetOffset,d),u=K(n,{lineId:e.rear.lineId,offset:e.rear.absoluteOffset},t.targetLineId,f,!1);if(!u)return null;const g=ee(u,c,o,r);return{path:u,curveDataMap:g}}function ne(e,t){const s=e.execution,n=t.vehicleQueues.get(e.vehicle.id),o=n?.[s.currentCommandIndex];if(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}),o?.awaitConfirmation)return{handled:!0,vehicle:{...e.vehicle,state:"waiting"},newExecution:s,isWaiting:!0};const c=s.currentCommandIndex+1;if(n&&c<n.length){const i=n[c],l=t.graphRef.current;if(l){const d={graph:l,linesMap:t.linesMap,curves:t.curves,config:t.config},f=t.prepareCommandPath(e.vehicle,i,d);if(f){const u=k(f.path,0,0,t.config.wheelbase);t.onCommandStart&&t.onCommandStart({vehicleId:e.vehicle.id,command:i,commandIndex:c,startPosition:{lineId:e.vehicle.rear.lineId,absoluteOffset:e.vehicle.rear.absoluteOffset,position:e.vehicle.rear.position}});const g={path:f.path,curveDataMap:f.curveDataMap,currentCommandIndex:c,rear:{currentSegmentIndex:0,segmentDistance:0},front:u?{currentSegmentIndex:u.segmentIndex,segmentDistance:u.segmentDistance}:{currentSegmentIndex:0,segmentDistance:0}};return{handled:!0,vehicle:{...e.vehicle,state:"moving"},newExecution:g}}}}return{handled:!0,vehicle:{...e.vehicle,state:"idle"},newExecution:null}}exports.arcLengthToSegmentPosition=$;exports.buildArcLengthTable=q;exports.buildGraph=U;exports.calculateBezierArcLength=j;exports.calculateFrontAxlePosition=k;exports.calculateInitialFrontPosition=X;exports.calculatePositionOnCurve=M;exports.calculatePositionOnLine=O;exports.calculateTangentLength=V;exports.createBezierCurve=C;exports.createInitialMovementState=R;exports.distance=p;exports.distanceToT=F;exports.findPath=K;exports.getArcLength=J;exports.getCumulativeArcLength=N;exports.getLineLength=G;exports.getPointOnBezier=w;exports.getPointOnLine=B;exports.getPointOnLineByOffset=D;exports.getPositionFromOffset=b;exports.handleArrival=ne;exports.initializeAllVehicles=Y;exports.initializeMovingVehicle=Q;exports.isPointNearPoint=H;exports.normalize=P;exports.prepareCommandPath=te;exports.resolveFromLineOffset=S;exports.resolveToLineOffset=T;exports.updateAxlePosition=Z;