vehicle-path2 2.3.0 → 2.4.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.
@@ -0,0 +1,31 @@
1
+ import type { Point, Line, Curve } from '../types/geometry';
2
+ /**
3
+ * Project a point onto a line segment.
4
+ *
5
+ * Returns:
6
+ * - offset: absolute distance from line.start along the line (clamped to [0, lineLength])
7
+ * - distance: perpendicular distance from point to the nearest point on the line
8
+ */
9
+ export declare function projectPointOnLine(point: Point, line: Line): {
10
+ offset: number;
11
+ distance: number;
12
+ };
13
+ /**
14
+ * Compute the valid [min, max] offset range for placing the rear axle of a
15
+ * multi-axle vehicle on a line.
16
+ *
17
+ * - min is always 0 (rear axle at line start)
18
+ * - max is lineLength - totalAxleSpacing (so all axles fit on the line)
19
+ * - If the vehicle is too long for the line, returns [0, 0]
20
+ */
21
+ export declare function getValidRearOffsetRange(line: Line, axleSpacings: number[]): [number, number];
22
+ /**
23
+ * Compute the minimum length a line must have so that all attached curve
24
+ * offsets (fromOffset / toOffset) remain within valid bounds.
25
+ *
26
+ * Only absolute offsets contribute to the minimum — percentage-based offsets
27
+ * scale with the line and therefore impose no hard minimum.
28
+ *
29
+ * Returns 0 if no curves are attached or all offsets are percentage-based.
30
+ */
31
+ export declare function computeMinLineLength(lineId: string, curves: Curve[]): number;
@@ -20,3 +20,4 @@ export { initializeMovingVehicle, createInitialMovementState, initializeAllVehic
20
20
  export { PathEngine, type PathEngineConfig, type VehiclePathState, type PathExecution } from './engine';
21
21
  export { distance, normalize, getPointOnLine, getPointOnLineByOffset, getPointOnBezier, createBezierCurve, buildArcLengthTable, distanceToT, getArcLength, calculateTangentLength, isPointNearPoint, type ArcLengthEntry, type CurveOffsetOptions } from './algorithms/math';
22
22
  export { serializeScene, deserializeScene, type SceneSnapshot } from './snapshot';
23
+ export { projectPointOnLine, getValidRearOffsetRange, computeMinLineLength } from './algorithms/geometry';
package/dist/core.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-BUYdltrL.cjs");function o(r,n,t){const a={lines:r,curves:n.map(i=>({id:i.id,fromLineId:i.fromLineId,toLineId:i.toLineId,fromOffset:i.fromOffset,fromIsPercentage:i.fromIsPercentage??!1,toOffset:i.toOffset,toIsPercentage:i.toIsPercentage??!1})),vehicles:t.map(i=>({id:i.id,lineId:i.axles[0].lineId,axles:i.axles.map(l=>({offset:l.offset})),axleSpacings:i.axleSpacings,isPercentage:i.isPercentage??!1}))};return JSON.stringify(a,null,2)}function s(r){let n;try{n=JSON.parse(r)}catch{throw new Error("deserializeScene: invalid JSON")}if(!n||typeof n!="object"||Array.isArray(n))throw new Error("deserializeScene: expected a JSON object");const t=n;if(!Array.isArray(t.lines))throw new Error('deserializeScene: missing "lines"');if(!Array.isArray(t.curves))throw new Error('deserializeScene: missing "curves"');if(!Array.isArray(t.vehicles))throw new Error('deserializeScene: missing "vehicles"');return{lines:t.lines,curves:t.curves,vehicles:t.vehicles}}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;exports.deserializeScene=s;exports.serializeScene=o;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-BUYdltrL.cjs");function f(a,t,i){const r={lines:a,curves:t.map(n=>({id:n.id,fromLineId:n.fromLineId,toLineId:n.toLineId,fromOffset:n.fromOffset,fromIsPercentage:n.fromIsPercentage??!1,toOffset:n.toOffset,toIsPercentage:n.toIsPercentage??!1})),vehicles:i.map(n=>({id:n.id,lineId:n.axles[0].lineId,axles:n.axles.map(o=>({offset:o.offset})),axleSpacings:n.axleSpacings,isPercentage:n.isPercentage??!1}))};return JSON.stringify(r,null,2)}function g(a){let t;try{t=JSON.parse(a)}catch{throw new Error("deserializeScene: invalid JSON")}if(!t||typeof t!="object"||Array.isArray(t))throw new Error("deserializeScene: expected a JSON object");const i=t;if(!Array.isArray(i.lines))throw new Error('deserializeScene: missing "lines"');if(!Array.isArray(i.curves))throw new Error('deserializeScene: missing "curves"');if(!Array.isArray(i.vehicles))throw new Error('deserializeScene: missing "vehicles"');return{lines:i.lines,curves:i.curves,vehicles:i.vehicles}}function h(a,t){const i=t.end.x-t.start.x,r=t.end.y-t.start.y,n=i*i+r*r;if(n===0)return{offset:0,distance:Math.sqrt((a.x-t.start.x)**2+(a.y-t.start.y)**2)};const o=Math.max(0,Math.min(1,((a.x-t.start.x)*i+(a.y-t.start.y)*r)/n)),s=t.start.x+o*i,c=t.start.y+o*r,l=Math.sqrt((a.x-s)**2+(a.y-c)**2);return{offset:o*Math.sqrt(n),distance:l}}function d(a,t){const i=e.getLineLength(a),r=t.reduce((o,s)=>o+s,0);return[0,Math.max(0,i-r)]}function u(a,t){let i=0;for(const r of t)r.fromLineId===a&&!r.fromIsPercentage&&r.fromOffset!==void 0&&(i=Math.max(i,r.fromOffset)),r.toLineId===a&&!r.toIsPercentage&&r.toOffset!==void 0&&(i=Math.max(i,r.toOffset));return i}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;exports.computeMinLineLength=u;exports.deserializeScene=g;exports.getValidRearOffsetRange=d;exports.projectPointOnLine=h;exports.serializeScene=f;
package/dist/core.js CHANGED
@@ -1,78 +1,107 @@
1
- import { P as f, a as g, b as h, c as d, d as u, e as m, f as P, g as A, h as v, i as L, j as O, k as p, l as S, m as z, n as y, o as w, p as x, q as I, r as b, s as E, t as T, u as B, v as C, w as N, x as j, y as J, z as F, A as V, B as M, C as k, D as q, E as D } from "./index-D-HctiIv.js";
2
- function n(s, a, i) {
3
- const r = {
4
- lines: s,
5
- curves: a.map((e) => ({
6
- id: e.id,
7
- fromLineId: e.fromLineId,
8
- toLineId: e.toLineId,
9
- fromOffset: e.fromOffset,
10
- fromIsPercentage: e.fromIsPercentage ?? !1,
11
- toOffset: e.toOffset,
12
- toIsPercentage: e.toIsPercentage ?? !1
1
+ import { g as f } from "./index-wjEuFiRl.js";
2
+ import { P as y, a as v, b as A, c as p, d as S, e as I, f as z, h as w, i as M, j as b, k as j, l as E, m as T, n as q, o as B, p as C, q as N, r as J, s as V, t as F, u as R, v as k, w as D, x as G, y as X, z as Y, A as H, B as K, C as Q, D as U, E as W } from "./index-wjEuFiRl.js";
3
+ function h(r, e, t) {
4
+ const a = {
5
+ lines: r,
6
+ curves: e.map((s) => ({
7
+ id: s.id,
8
+ fromLineId: s.fromLineId,
9
+ toLineId: s.toLineId,
10
+ fromOffset: s.fromOffset,
11
+ fromIsPercentage: s.fromIsPercentage ?? !1,
12
+ toOffset: s.toOffset,
13
+ toIsPercentage: s.toIsPercentage ?? !1
13
14
  })),
14
- vehicles: i.map((e) => ({
15
- id: e.id,
16
- lineId: e.axles[0].lineId,
17
- axles: e.axles.map((t) => ({ offset: t.offset })),
18
- axleSpacings: e.axleSpacings,
19
- isPercentage: e.isPercentage ?? !1
15
+ vehicles: t.map((s) => ({
16
+ id: s.id,
17
+ lineId: s.axles[0].lineId,
18
+ axles: s.axles.map((n) => ({ offset: n.offset })),
19
+ axleSpacings: s.axleSpacings,
20
+ isPercentage: s.isPercentage ?? !1
20
21
  }))
21
22
  };
22
- return JSON.stringify(r, null, 2);
23
+ return JSON.stringify(a, null, 2);
23
24
  }
24
- function o(s) {
25
- let a;
25
+ function m(r) {
26
+ let e;
26
27
  try {
27
- a = JSON.parse(s);
28
+ e = JSON.parse(r);
28
29
  } catch {
29
30
  throw new Error("deserializeScene: invalid JSON");
30
31
  }
31
- if (!a || typeof a != "object" || Array.isArray(a))
32
+ if (!e || typeof e != "object" || Array.isArray(e))
32
33
  throw new Error("deserializeScene: expected a JSON object");
33
- const i = a;
34
- if (!Array.isArray(i.lines)) throw new Error('deserializeScene: missing "lines"');
35
- if (!Array.isArray(i.curves)) throw new Error('deserializeScene: missing "curves"');
36
- if (!Array.isArray(i.vehicles)) throw new Error('deserializeScene: missing "vehicles"');
34
+ const t = e;
35
+ if (!Array.isArray(t.lines)) throw new Error('deserializeScene: missing "lines"');
36
+ if (!Array.isArray(t.curves)) throw new Error('deserializeScene: missing "curves"');
37
+ if (!Array.isArray(t.vehicles)) throw new Error('deserializeScene: missing "vehicles"');
37
38
  return {
38
- lines: i.lines,
39
- curves: i.curves,
40
- vehicles: i.vehicles
39
+ lines: t.lines,
40
+ curves: t.curves,
41
+ vehicles: t.vehicles
41
42
  };
42
43
  }
44
+ function u(r, e) {
45
+ const t = e.end.x - e.start.x, a = e.end.y - e.start.y, s = t * t + a * a;
46
+ if (s === 0)
47
+ return { offset: 0, distance: Math.sqrt(
48
+ (r.x - e.start.x) ** 2 + (r.y - e.start.y) ** 2
49
+ ) };
50
+ const n = Math.max(
51
+ 0,
52
+ Math.min(
53
+ 1,
54
+ ((r.x - e.start.x) * t + (r.y - e.start.y) * a) / s
55
+ )
56
+ ), i = e.start.x + n * t, o = e.start.y + n * a, c = Math.sqrt((r.x - i) ** 2 + (r.y - o) ** 2);
57
+ return { offset: n * Math.sqrt(s), distance: c };
58
+ }
59
+ function x(r, e) {
60
+ const t = f(r), a = e.reduce((n, i) => n + i, 0);
61
+ return [0, Math.max(0, t - a)];
62
+ }
63
+ function P(r, e) {
64
+ let t = 0;
65
+ for (const a of e)
66
+ a.fromLineId === r && !a.fromIsPercentage && a.fromOffset !== void 0 && (t = Math.max(t, a.fromOffset)), a.toLineId === r && !a.toIsPercentage && a.toOffset !== void 0 && (t = Math.max(t, a.toOffset));
67
+ return t;
68
+ }
43
69
  export {
44
- f as PathEngine,
45
- g as arcLengthToSegmentPosition,
46
- h as buildArcLengthTable,
47
- d as buildGraph,
48
- u as calculateBezierArcLength,
49
- m as calculateFrontAxlePosition,
50
- P as calculateInitialAxlePositions,
51
- A as calculatePositionOnCurve,
52
- v as calculatePositionOnLine,
53
- L as calculateTangentLength,
54
- O as createBezierCurve,
55
- p as createInitialMovementState,
56
- o as deserializeScene,
57
- S as distance,
58
- z as distanceToT,
59
- y as findPath,
60
- w as getArcLength,
61
- x as getCumulativeArcLength,
62
- I as getLineLength,
63
- b as getPointOnBezier,
64
- E as getPointOnLine,
65
- T as getPointOnLineByOffset,
66
- B as getPositionFromOffset,
67
- C as handleArrival,
68
- N as initializeAllVehicles,
69
- j as initializeMovingVehicle,
70
- J as isPointNearPoint,
71
- F as moveVehicle,
72
- V as normalize,
73
- M as prepareCommandPath,
74
- k as resolveFromLineOffset,
75
- q as resolveToLineOffset,
76
- n as serializeScene,
77
- D as updateAxlePosition
70
+ y as PathEngine,
71
+ v as arcLengthToSegmentPosition,
72
+ A as buildArcLengthTable,
73
+ p as buildGraph,
74
+ S as calculateBezierArcLength,
75
+ I as calculateFrontAxlePosition,
76
+ z as calculateInitialAxlePositions,
77
+ w as calculatePositionOnCurve,
78
+ M as calculatePositionOnLine,
79
+ b as calculateTangentLength,
80
+ P as computeMinLineLength,
81
+ j as createBezierCurve,
82
+ E as createInitialMovementState,
83
+ m as deserializeScene,
84
+ T as distance,
85
+ q as distanceToT,
86
+ B as findPath,
87
+ C as getArcLength,
88
+ N as getCumulativeArcLength,
89
+ f as getLineLength,
90
+ J as getPointOnBezier,
91
+ V as getPointOnLine,
92
+ F as getPointOnLineByOffset,
93
+ R as getPositionFromOffset,
94
+ x as getValidRearOffsetRange,
95
+ k as handleArrival,
96
+ D as initializeAllVehicles,
97
+ G as initializeMovingVehicle,
98
+ X as isPointNearPoint,
99
+ Y as moveVehicle,
100
+ H as normalize,
101
+ K as prepareCommandPath,
102
+ u as projectPointOnLine,
103
+ Q as resolveFromLineOffset,
104
+ U as resolveToLineOffset,
105
+ h as serializeScene,
106
+ W as updateAxlePosition
78
107
  };
@@ -689,17 +689,17 @@ export {
689
689
  F as d,
690
690
  re as e,
691
691
  H as f,
692
- S as g,
693
- M as h,
694
- k as i,
695
- z as j,
696
- U as k,
697
- y as l,
698
- _ as m,
699
- G as n,
700
- se as o,
701
- Q as p,
702
- O as q,
692
+ O as g,
693
+ S as h,
694
+ M as i,
695
+ k as j,
696
+ z as k,
697
+ U as l,
698
+ y as m,
699
+ _ as n,
700
+ G as o,
701
+ se as p,
702
+ Q as q,
703
703
  b as r,
704
704
  K as s,
705
705
  V as t,
@@ -1,7 +1,7 @@
1
- import { P as t, a as i, b as s, c as n, d as o, e as l, f as r, g as c, h as g, j as h, k as P, l as u, m as L, n as f, o as m, p as v, q as A, r as d, s as O, t as z, u as p, v as x, w as B, x as C, z as T, A as b, B as F, C as V, D as E, E as I } from "./index-D-HctiIv.js";
1
+ import { P as i, a as t, b as s, c as n, d as o, e as l, f as r, h as c, i as g, k as h, l as P, m as u, n as L, o as f, p as m, q as v, g as A, r as d, s as O, t as z, u as p, v as x, w as B, x as C, z as T, A as b, B as F, C as V, D as E, E as I } from "./index-wjEuFiRl.js";
2
2
  export {
3
- t as PathEngine,
4
- i as arcLengthToSegmentPosition,
3
+ i as PathEngine,
4
+ t as arcLengthToSegmentPosition,
5
5
  s as buildArcLengthTable,
6
6
  n as buildGraph,
7
7
  o as calculateBezierArcLength,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vehicle-path2",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
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",