vehicle-path 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.
package/README.md ADDED
@@ -0,0 +1,293 @@
1
+ # VehiclePath
2
+
3
+ An interactive web-based vehicle motion simulator that visualizes dual-axle vehicle movement along complex paths composed of lines and Bezier curves. The system accurately tracks both rear and front axles with proper wheelbase constraints.
4
+
5
+ ## Features
6
+
7
+ - **Interactive Canvas Drawing** - Create lines and Bezier curves with mouse controls
8
+ - **Dual-Axle Vehicle Tracking** - Track both front (F) and rear (R) axles with configurable wheelbase
9
+ - **Text-based Scene Definition** - Define scenes using intuitive DSL syntax
10
+ - **Command-based Movement** - Queue goto commands with `--wait` and `--payload` options
11
+ - **Arc-Length Parameterization** - Accurate curve traversal with constant speed
12
+ - **Event System** - Observer pattern for vehicle events (commandComplete, positionUpdate, stateChange)
13
+ - **Playback Controls** - Run, pause, and reset animations
14
+ - **Real-time Visualization** - Canvas rendering with endpoints, curves, and moving vehicles
15
+
16
+ ## Quick Start
17
+
18
+ ```bash
19
+ # Install dependencies
20
+ npm install
21
+
22
+ # Start development server
23
+ npm run dev
24
+
25
+ # Run tests
26
+ npm test
27
+
28
+ # Build for production
29
+ npm run build
30
+ ```
31
+
32
+ ## Scene Definition DSL
33
+
34
+ ### Lines
35
+ ```
36
+ line001 : (100, 100) -> (500, 100)
37
+ line002 : (500, 100) -> (500, 400)
38
+ ```
39
+
40
+ ### Curves (connect lines)
41
+ ```
42
+ line001 -> line002
43
+ line001 80% -> line002 30%
44
+ ```
45
+
46
+ ### Vehicle Start Positions
47
+ ```
48
+ v1 start line001 0%
49
+ v2 start line002 50
50
+ ```
51
+
52
+ ### Movement Commands
53
+ ```
54
+ v1 goto line002 100%
55
+ v1 goto line001 50% --wait
56
+ v1 goto line002 0% --payload {"orderId":"123"}
57
+ ```
58
+
59
+ ## Architecture
60
+
61
+ ```
62
+ src/
63
+ ├── components/
64
+ │ ├── Canvas.tsx # Interactive canvas for drawing
65
+ │ └── Controls.tsx # Control panel with parameters
66
+ ├── hooks/
67
+ │ ├── useCanvasInteraction.ts # Mouse/drag handling
68
+ │ ├── useSceneDefinition.ts # Lines/curves state
69
+ │ ├── useInitialMovement.ts # Vehicle start positions
70
+ │ ├── useMovementSequence.ts # Goto command queuing
71
+ │ ├── useVehicleMovement.ts # Animation loop
72
+ │ └── useVehicleEvents.ts # Event subscription
73
+ ├── types/
74
+ │ ├── core.ts # Point, Line, Curve
75
+ │ ├── vehicle.ts # Vehicle, AxleState, GotoCommand
76
+ │ ├── movement.ts # MovementConfig, PathExecutionState
77
+ │ └── ui.ts # DrawMode, TangentMode
78
+ └── utils/
79
+ ├── pathFinding.ts # Graph-based path finding
80
+ ├── textParser.ts # DSL parsing
81
+ ├── VehicleEventEmitter.ts # Event system
82
+ └── vehicleMovement/ # Core movement algorithms
83
+ ├── initialize.ts
84
+ ├── positionUpdate.ts
85
+ ├── arcLengthTracking.ts
86
+ ├── pathPreparation.ts
87
+ └── segmentTransition.ts
88
+ ```
89
+
90
+ ## Core Concepts
91
+
92
+ ### Dual-Axle Tracking
93
+
94
+ The system tracks two axle positions:
95
+ - **Rear Axle (R)** - The reference point that follows the path exactly
96
+ - **Front Axle (F)** - Maintains constant wheelbase distance from R
97
+
98
+ ```
99
+ R ----[wheelbase]---- F
100
+ (30-60 pixels)
101
+ ```
102
+
103
+ ### Arc-Length Parameterization
104
+
105
+ Bezier curves are pre-computed with arc-length lookup tables for:
106
+ - Constant speed movement along curves
107
+ - Accurate position calculation at any distance
108
+ - Smooth transitions between segments
109
+
110
+ ### Event System
111
+
112
+ Subscribe to vehicle events using the observer pattern:
113
+
114
+ ```typescript
115
+ // Using React hook
116
+ useVehicleEvent('positionUpdate', (data) => {
117
+ console.log(`Center: (${data.center.x}, ${data.center.y})`)
118
+ console.log(`Angle: ${data.angle} radians`)
119
+ })
120
+
121
+ // Manual subscription
122
+ const unsubscribe = emitter.on('commandComplete', (info) => {
123
+ console.log(`Vehicle ${info.vehicleId} arrived`)
124
+ console.log(`Payload:`, info.payload)
125
+ })
126
+ ```
127
+
128
+ **Available Events:**
129
+ | Event | Data | Description |
130
+ |-------|------|-------------|
131
+ | `commandComplete` | `GotoCompletionInfo` | Fired when vehicle reaches destination |
132
+ | `positionUpdate` | `VehiclePositionUpdate` | Fired each frame with position/angle |
133
+ | `stateChange` | `{vehicleId, from, to}` | Fired when vehicle state changes |
134
+
135
+ ### Manual Control with `--wait`
136
+
137
+ Pause vehicle after command completion:
138
+
139
+ ```
140
+ v1 goto station-A 100% --wait
141
+ v1 goto station-B 0%
142
+ ```
143
+
144
+ Then resume programmatically:
145
+
146
+ ```typescript
147
+ const { continueVehicle } = useVehicleMovement({...})
148
+
149
+ // After processing...
150
+ continueVehicle('v1')
151
+ ```
152
+
153
+ ### Payload System
154
+
155
+ Attach custom data to commands:
156
+
157
+ ```
158
+ v1 goto pickup 100% --wait --payload {"orderId":"order-123","priority":1}
159
+ ```
160
+
161
+ Access in callback:
162
+
163
+ ```typescript
164
+ emitter.on('commandComplete', (info) => {
165
+ if (info.payload) {
166
+ const { orderId, priority } = info.payload as OrderPayload
167
+ // Process order...
168
+ }
169
+ })
170
+ ```
171
+
172
+ ## API Reference
173
+
174
+ ### useVehicleMovement
175
+
176
+ ```typescript
177
+ const {
178
+ movingVehicles, // Current vehicle states
179
+ playbackState, // 'stopped' | 'running' | 'paused'
180
+ handleRun, // Start animation
181
+ handlePause, // Pause animation
182
+ handleReset, // Reset to initial positions
183
+ continueVehicle // Resume waiting vehicle
184
+ } = useVehicleMovement({
185
+ vehicles, // Initial vehicle configs
186
+ lines, // Line definitions
187
+ vehicleQueues, // Map<vehicleId, GotoCommand[]>
188
+ velocity, // Pixels per frame
189
+ wheelbase, // Distance R to F
190
+ tangentMode, // 'smooth' | 'linear'
191
+ curves, // Curve definitions
192
+ eventEmitter // Optional VehicleEventEmitter
193
+ })
194
+ ```
195
+
196
+ ### VehicleEventEmitter
197
+
198
+ ```typescript
199
+ const emitter = new VehicleEventEmitter()
200
+
201
+ // Subscribe
202
+ const unsubscribe = emitter.on('positionUpdate', callback)
203
+
204
+ // Emit
205
+ emitter.emit('positionUpdate', data)
206
+
207
+ // Unsubscribe all
208
+ emitter.off('positionUpdate') // Specific event
209
+ emitter.off() // All events
210
+
211
+ // Check listeners
212
+ emitter.listenerCount('positionUpdate')
213
+ ```
214
+
215
+ ### GotoCommand
216
+
217
+ ```typescript
218
+ interface GotoCommand {
219
+ vehicleId: string
220
+ targetLineId: string
221
+ targetOffset: number
222
+ isPercentage: boolean
223
+ awaitConfirmation?: boolean // --wait flag
224
+ payload?: unknown // --payload JSON
225
+ }
226
+ ```
227
+
228
+ ### VehiclePositionUpdate
229
+
230
+ ```typescript
231
+ interface VehiclePositionUpdate {
232
+ vehicleId: string
233
+ rear: Point // Rear axle position
234
+ front: Point // Front axle position
235
+ center: Point // Midpoint between axles
236
+ angle: number // Heading in radians
237
+ }
238
+ ```
239
+
240
+ ## Testing
241
+
242
+ ```bash
243
+ # Run all tests
244
+ npm test
245
+
246
+ # Run with UI
247
+ npm run test:ui
248
+
249
+ # Generate coverage report
250
+ npm run test:coverage
251
+ ```
252
+
253
+ Test files are located in `src/utils/vehicleMovement/__tests__/`:
254
+ - `arcLengthTracking.test.ts` - Arc-length calculations
255
+ - `dualAxleMovement.test.ts` - Dual-axle scenarios
256
+ - `initialize.test.ts` - Initialization logic
257
+ - `pathPreparation.test.ts` - Path preparation
258
+ - `positionUpdate.test.ts` - Position updates
259
+ - `userScenario.test.ts` - End-to-end scenarios
260
+
261
+ ## Configuration
262
+
263
+ ### Tangent Modes
264
+
265
+ Control curve smoothness:
266
+ - **smooth** - Bezier curves with smooth tangents
267
+ - **linear** - Sharp corners at connection points
268
+
269
+ ### Parameters
270
+
271
+ | Parameter | Default | Description |
272
+ |-----------|---------|-------------|
273
+ | `wheelbase` | 30-60 | Distance between R and F axles |
274
+ | `velocity` | 1-5 | Movement speed (pixels/frame) |
275
+
276
+ ## Tech Stack
277
+
278
+ - **React 19** - UI framework
279
+ - **TypeScript 5.9** - Type safety
280
+ - **Vite 7** - Build tool
281
+ - **Vitest** - Testing framework
282
+ - **Canvas API** - Rendering
283
+
284
+ ## Documentation
285
+
286
+ Additional documentation in `/docs`:
287
+ - `DEBUG_GUIDE.md` - Debugging vehicle movement
288
+ - `HOOKS.md` - Custom hooks reference
289
+ - `UI.md` - UI architecture
290
+
291
+ ## License
292
+
293
+ MIT
@@ -0,0 +1,31 @@
1
+ import type { Point, Line, Curve } from '../types/core';
2
+ import type { DrawMode } from '../types/ui';
3
+ interface UseCanvasInteractionProps {
4
+ canvasRef: React.RefObject<HTMLCanvasElement | null>;
5
+ containerRef: React.RefObject<HTMLDivElement | null>;
6
+ drawMode: DrawMode;
7
+ lines: Line[];
8
+ curves: Curve[];
9
+ setLines: (lines: Line[]) => void;
10
+ setCurves: (curves: Curve[]) => void;
11
+ lineCounterRef: React.MutableRefObject<number>;
12
+ }
13
+ export declare function useCanvasInteraction({ canvasRef, containerRef, drawMode, lines, curves, setLines, setCurves, lineCounterRef }: UseCanvasInteractionProps): {
14
+ handleMouseDown: (e: React.MouseEvent<HTMLCanvasElement>) => void;
15
+ handleMouseMove: (e: React.MouseEvent<HTMLCanvasElement>) => void;
16
+ handleMouseUp: () => void;
17
+ tempLine: {
18
+ start: Point;
19
+ current: Point;
20
+ } | null;
21
+ hoveredEndpoint: {
22
+ lineId: string;
23
+ endpoint: "start" | "end";
24
+ } | null;
25
+ curveStart: {
26
+ lineId: string;
27
+ endpoint: "start" | "end";
28
+ } | null;
29
+ mousePos: Point;
30
+ };
31
+ export {};
@@ -0,0 +1,16 @@
1
+ import type { Line } from '../types/core';
2
+ import type { Vehicle } from '../types/vehicle';
3
+ interface UseInitialMovementProps {
4
+ lines: Line[];
5
+ wheelbase: number;
6
+ }
7
+ export declare function useInitialMovement({ lines, wheelbase }: UseInitialMovementProps): {
8
+ vehicles: Vehicle[];
9
+ initialMovementText: string;
10
+ movementError: string | null;
11
+ isDebouncing: boolean;
12
+ debounceKey: number;
13
+ setInitialMovementText: import("react").Dispatch<import("react").SetStateAction<string>>;
14
+ handleAddStartCommand: () => void;
15
+ };
16
+ export {};
@@ -0,0 +1,17 @@
1
+ import type { Line } from '../types/core';
2
+ import type { Vehicle, GotoCommand } from '../types/vehicle';
3
+ interface UseMovementSequenceProps {
4
+ lines: Line[];
5
+ vehicles: Vehicle[];
6
+ }
7
+ export declare function useMovementSequence({ lines, vehicles }: UseMovementSequenceProps): {
8
+ movementSequenceText: string;
9
+ gotoCommands: GotoCommand[];
10
+ vehicleQueues: Map<string, GotoCommand[]>;
11
+ sequenceError: string | null;
12
+ isDebouncing: boolean;
13
+ debounceKey: number;
14
+ setMovementSequenceText: import("react").Dispatch<import("react").SetStateAction<string>>;
15
+ handleAddGotoCommand: () => void;
16
+ };
17
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { Line, Curve } from '../types/core';
2
+ export declare function useSceneDefinition(): {
3
+ lines: Line[];
4
+ curves: Curve[];
5
+ sceneDefinitionText: string;
6
+ sceneError: string | null;
7
+ isDebouncing: boolean;
8
+ debounceKey: number;
9
+ setLines: import("react").Dispatch<import("react").SetStateAction<Line[]>>;
10
+ setCurves: import("react").Dispatch<import("react").SetStateAction<Curve[]>>;
11
+ setSceneDefinitionText: import("react").Dispatch<import("react").SetStateAction<string>>;
12
+ };
@@ -0,0 +1,31 @@
1
+ import { VehicleEventEmitter, type VehicleEventType, type VehicleEventCallback, type VehicleEventMap, type VehiclePositionUpdate } from '../utils/VehicleEventEmitter';
2
+ /**
3
+ * React context for VehicleEventEmitter
4
+ */
5
+ export declare const VehicleEventContext: import("react").Context<VehicleEventEmitter | null>;
6
+ /**
7
+ * Hook to access the VehicleEventEmitter instance from context
8
+ * @returns VehicleEventEmitter instance
9
+ * @throws Error if used outside of VehicleEventProvider
10
+ */
11
+ export declare function useVehicleEventEmitter(): VehicleEventEmitter;
12
+ /**
13
+ * Hook to create a new VehicleEventEmitter instance (for provider)
14
+ * @returns VehicleEventEmitter instance (stable reference)
15
+ */
16
+ export declare function useCreateVehicleEventEmitter(): VehicleEventEmitter;
17
+ /**
18
+ * Hook to subscribe to a vehicle event with automatic cleanup
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * useVehicleEvent('commandComplete', (info) => {
23
+ * console.log(`Vehicle ${info.vehicleId} arrived!`)
24
+ * if (info.payload) {
25
+ * // Handle payload
26
+ * }
27
+ * })
28
+ * ```
29
+ */
30
+ export declare function useVehicleEvent<K extends VehicleEventType>(event: K, callback: VehicleEventCallback<K>, deps?: React.DependencyList): void;
31
+ export type { VehicleEventEmitter, VehicleEventType, VehicleEventCallback, VehicleEventMap, VehiclePositionUpdate };
@@ -0,0 +1,24 @@
1
+ import type { Line } from '../types/core';
2
+ import type { Vehicle, GotoCommand } from '../types/vehicle';
3
+ import type { TangentMode } from '../types/ui';
4
+ import type { VehicleEventEmitter } from '../utils/VehicleEventEmitter';
5
+ interface UseVehicleMovementProps {
6
+ vehicles: Vehicle[];
7
+ lines: Line[];
8
+ vehicleQueues: Map<string, GotoCommand[]>;
9
+ velocity: number;
10
+ wheelbase: number;
11
+ tangentMode: TangentMode;
12
+ curves: import('../types/core').Curve[];
13
+ eventEmitter?: VehicleEventEmitter;
14
+ }
15
+ type PlaybackState = 'stopped' | 'running' | 'paused';
16
+ export declare function useVehicleMovement({ vehicles, lines, vehicleQueues, velocity, wheelbase, tangentMode, curves, eventEmitter }: UseVehicleMovementProps): {
17
+ movingVehicles: Vehicle[];
18
+ playbackState: PlaybackState;
19
+ handleRun: () => void;
20
+ handlePause: () => void;
21
+ handleReset: () => void;
22
+ continueVehicle: (vehicleId: string) => boolean;
23
+ };
24
+ export {};
@@ -0,0 +1,28 @@
1
+ /**
2
+ * VehiclePath - Vehicle motion simulator library
3
+ *
4
+ * A library for simulating dual-axle vehicle movement along paths
5
+ * composed of lines and Bezier curves.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import {
10
+ * useVehicleMovement,
11
+ * VehicleEventEmitter,
12
+ * parseSceneDefinition
13
+ * } from 'vehicle-path'
14
+ * import type { Point, Line, Vehicle } from 'vehicle-path'
15
+ * ```
16
+ */
17
+ export type { Point, Line, BezierCurve, Curve, VehicleState, VehicleStart, Vehicle, AxleState, GotoCommand, GotoCompletionInfo, GotoCompletionCallback, CurveData, PathExecutionState, VehicleMovementState, MovementConfig, SceneDefinition, SceneContext, DrawMode, TangentMode } from './types';
18
+ export { useVehicleMovement } from './hooks/useVehicleMovement';
19
+ export { useVehicleEventEmitter, useCreateVehicleEventEmitter, useVehicleEvent, VehicleEventContext } from './hooks/useVehicleEvents';
20
+ export { useSceneDefinition } from './hooks/useSceneDefinition';
21
+ export { useInitialMovement } from './hooks/useInitialMovement';
22
+ export { useMovementSequence } from './hooks/useMovementSequence';
23
+ export { useCanvasInteraction } from './hooks/useCanvasInteraction';
24
+ export { VehicleEventEmitter, type VehicleEventMap, type VehicleEventType, type VehicleEventCallback, type VehiclePositionUpdate, type Unsubscribe } from './utils/VehicleEventEmitter';
25
+ export { parseSceneDefinition, generateSceneDefinition, parseVehicleStarts, generateVehicleStarts, parseGotoCommands, generateGotoCommands } from './utils/textParser';
26
+ export { buildGraph, findPath, canReachTarget, getReachableCurves, calculateBezierArcLength, resolveOffset, resolveFromLineOffset, resolveToLineOffset, type Graph, type GraphEdge, type PathSegment, type PathResult, type VehiclePosition } from './utils/pathFinding';
27
+ export { initializeMovingVehicle, createInitialMovementState, initializeAllVehicles, calculateInitialFrontPosition, type InitializationResult, updateAxlePosition, calculatePositionOnLine, calculatePositionOnCurve, calculateFrontAxlePosition, getCumulativeArcLength, arcLengthToSegmentPosition, prepareCommandPath, type PreparedPath, checkRearCompletion, handleArrival, type SegmentCompletionContext, type SegmentCompletionResult, type SegmentVehicleState, getPositionFromOffset, getLineLength } from './utils/vehicleMovement';
28
+ export { distance, normalize, getPointOnLine, getPointOnLineByOffset, getPointOnBezier, createBezierCurve, buildArcLengthTable, distanceToT, getArcLength, type ArcLengthEntry, type CurveOffsetOptions } from './utils/math';
@@ -0,0 +1,28 @@
1
+ /**
2
+ * VehiclePath - Vehicle motion simulator library
3
+ *
4
+ * A library for simulating dual-axle vehicle movement along paths
5
+ * composed of lines and Bezier curves.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import {
10
+ * useVehicleMovement,
11
+ * VehicleEventEmitter,
12
+ * parseSceneDefinition
13
+ * } from 'vehicle-path'
14
+ * import type { Point, Line, Vehicle } from 'vehicle-path'
15
+ * ```
16
+ */
17
+ export type { Point, Line, BezierCurve, Curve, VehicleState, VehicleStart, Vehicle, AxleState, GotoCommand, GotoCompletionInfo, GotoCompletionCallback, CurveData, PathExecutionState, VehicleMovementState, MovementConfig, SceneDefinition, SceneContext, DrawMode, TangentMode } from './types';
18
+ export { useVehicleMovement } from './hooks/useVehicleMovement';
19
+ export { useVehicleEventEmitter, useCreateVehicleEventEmitter, useVehicleEvent, VehicleEventContext } from './hooks/useVehicleEvents';
20
+ export { useSceneDefinition } from './hooks/useSceneDefinition';
21
+ export { useInitialMovement } from './hooks/useInitialMovement';
22
+ export { useMovementSequence } from './hooks/useMovementSequence';
23
+ export { useCanvasInteraction } from './hooks/useCanvasInteraction';
24
+ export { VehicleEventEmitter, type VehicleEventMap, type VehicleEventType, type VehicleEventCallback, type VehiclePositionUpdate, type Unsubscribe } from './utils/VehicleEventEmitter';
25
+ export { parseSceneDefinition, generateSceneDefinition, parseVehicleStarts, generateVehicleStarts, parseGotoCommands, generateGotoCommands } from './utils/textParser';
26
+ export { buildGraph, findPath, canReachTarget, getReachableCurves, calculateBezierArcLength, resolveOffset, resolveFromLineOffset, resolveToLineOffset, type Graph, type GraphEdge, type PathSegment, type PathResult, type VehiclePosition } from './utils/pathFinding';
27
+ export { initializeMovingVehicle, createInitialMovementState, initializeAllVehicles, calculateInitialFrontPosition, type InitializationResult, updateAxlePosition, calculatePositionOnLine, calculatePositionOnCurve, calculateFrontAxlePosition, getCumulativeArcLength, arcLengthToSegmentPosition, prepareCommandPath, type PreparedPath, checkRearCompletion, handleArrival, type SegmentCompletionContext, type SegmentCompletionResult, type SegmentVehicleState, getPositionFromOffset, getLineLength } from './utils/vehicleMovement';
28
+ export { distance, normalize, getPointOnLine, getPointOnLineByOffset, getPointOnBezier, createBezierCurve, buildArcLengthTable, distanceToT, getArcLength, type ArcLengthEntry, type CurveOffsetOptions } from './utils/math';
@@ -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,12 @@
1
+ /**
2
+ * Re-export all types from a single entry point
3
+ *
4
+ * Usage:
5
+ * import type { Point, Line, Vehicle } from '../types'
6
+ * // or
7
+ * import type { Point } from '../types/core'
8
+ */
9
+ export type { Point, Line, BezierCurve, Curve } from './core';
10
+ export type { VehicleState, VehicleStart, Vehicle, AxleState, GotoCommand, GotoCompletionInfo, GotoCompletionCallback } from './vehicle';
11
+ export type { CurveData, PathExecutionState, VehicleMovementState, MovementConfig, SceneDefinition, SceneContext } from './movement';
12
+ export type { DrawMode, TangentMode } from './ui';
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Movement and animation state types
3
+ */
4
+ import type { Line, Curve, BezierCurve } from './core';
5
+ import type { Vehicle, VehicleStart } from './vehicle';
6
+ import type { TangentMode } from './ui';
7
+ export type { PathResult } from '../utils/pathFinding';
8
+ export type { ArcLengthEntry } from '../utils/math';
9
+ /**
10
+ * Bezier curve data with arc-length lookup table for animation
11
+ */
12
+ export interface CurveData {
13
+ bezier: BezierCurve;
14
+ arcLengthTable: import('../utils/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('../utils/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 definition (parsed from text input)
49
+ */
50
+ export interface SceneDefinition {
51
+ lines: Line[];
52
+ curves: Curve[];
53
+ vehicles: VehicleStart[];
54
+ }
55
+ /**
56
+ * Scene context for path preparation and movement calculations
57
+ * Bundles commonly-passed together dependencies
58
+ */
59
+ export interface SceneContext {
60
+ config: MovementConfig;
61
+ graph: import('../utils/pathFinding').Graph;
62
+ linesMap: Map<string, Line>;
63
+ curves: Curve[];
64
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * UI-related types for canvas and controls
3
+ */
4
+ /**
5
+ * Drawing mode for canvas interaction
6
+ */
7
+ export type DrawMode = 'line' | 'curve' | 'drag';
8
+ /**
9
+ * Tangent calculation mode for bezier curves
10
+ * - proportional-40: 40% of distance for tangent length
11
+ * - magic-55: 55.22% of distance (approximates circular arc)
12
+ */
13
+ export type TangentMode = 'proportional-40' | 'magic-55';
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Vehicle-related types
3
+ */
4
+ import type { Point } from './core';
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;