@rxflow/manhattan 0.0.1-alpha.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 (140) hide show
  1. package/README.md +35 -0
  2. package/cjs/geometry/Line.d.ts +21 -0
  3. package/cjs/geometry/Line.d.ts.map +1 -0
  4. package/cjs/geometry/Line.js +88 -0
  5. package/cjs/geometry/Point.d.ts +49 -0
  6. package/cjs/geometry/Point.d.ts.map +1 -0
  7. package/cjs/geometry/Point.js +94 -0
  8. package/cjs/geometry/Rectangle.d.ts +41 -0
  9. package/cjs/geometry/Rectangle.d.ts.map +1 -0
  10. package/cjs/geometry/Rectangle.js +65 -0
  11. package/cjs/geometry/index.d.ts +4 -0
  12. package/cjs/geometry/index.d.ts.map +1 -0
  13. package/cjs/geometry/index.js +26 -0
  14. package/cjs/getManHattanPath.d.ts +60 -0
  15. package/cjs/getManHattanPath.d.ts.map +1 -0
  16. package/cjs/getManHattanPath.js +285 -0
  17. package/cjs/index.d.ts +16 -0
  18. package/cjs/index.d.ts.map +1 -0
  19. package/cjs/index.js +117 -0
  20. package/cjs/obstacle/ObstacleMap.d.ts +28 -0
  21. package/cjs/obstacle/ObstacleMap.d.ts.map +1 -0
  22. package/cjs/obstacle/ObstacleMap.js +171 -0
  23. package/cjs/obstacle/index.d.ts +2 -0
  24. package/cjs/obstacle/index.d.ts.map +1 -0
  25. package/cjs/obstacle/index.js +12 -0
  26. package/cjs/options/defaults.d.ts +16 -0
  27. package/cjs/options/defaults.d.ts.map +1 -0
  28. package/cjs/options/defaults.js +39 -0
  29. package/cjs/options/index.d.ts +4 -0
  30. package/cjs/options/index.d.ts.map +1 -0
  31. package/cjs/options/index.js +38 -0
  32. package/cjs/options/resolver.d.ts +10 -0
  33. package/cjs/options/resolver.d.ts.map +1 -0
  34. package/cjs/options/resolver.js +118 -0
  35. package/cjs/options/types.d.ts +156 -0
  36. package/cjs/options/types.d.ts.map +1 -0
  37. package/cjs/options/types.js +5 -0
  38. package/cjs/pathfinder/SortedSet.d.ts +35 -0
  39. package/cjs/pathfinder/SortedSet.d.ts.map +1 -0
  40. package/cjs/pathfinder/SortedSet.js +95 -0
  41. package/cjs/pathfinder/findRoute.d.ts +8 -0
  42. package/cjs/pathfinder/findRoute.d.ts.map +1 -0
  43. package/cjs/pathfinder/findRoute.js +156 -0
  44. package/cjs/pathfinder/index.d.ts +3 -0
  45. package/cjs/pathfinder/index.d.ts.map +1 -0
  46. package/cjs/pathfinder/index.js +19 -0
  47. package/cjs/svg/index.d.ts +2 -0
  48. package/cjs/svg/index.d.ts.map +1 -0
  49. package/cjs/svg/index.js +18 -0
  50. package/cjs/svg/pathConverter.d.ts +10 -0
  51. package/cjs/svg/pathConverter.d.ts.map +1 -0
  52. package/cjs/svg/pathConverter.js +105 -0
  53. package/cjs/utils/direction.d.ts +24 -0
  54. package/cjs/utils/direction.d.ts.map +1 -0
  55. package/cjs/utils/direction.js +54 -0
  56. package/cjs/utils/grid.d.ts +26 -0
  57. package/cjs/utils/grid.d.ts.map +1 -0
  58. package/cjs/utils/grid.js +78 -0
  59. package/cjs/utils/index.d.ts +6 -0
  60. package/cjs/utils/index.d.ts.map +1 -0
  61. package/cjs/utils/index.js +60 -0
  62. package/cjs/utils/node.d.ts +27 -0
  63. package/cjs/utils/node.d.ts.map +1 -0
  64. package/cjs/utils/node.js +36 -0
  65. package/cjs/utils/rect.d.ts +9 -0
  66. package/cjs/utils/rect.d.ts.map +1 -0
  67. package/cjs/utils/rect.js +103 -0
  68. package/cjs/utils/route.d.ts +19 -0
  69. package/cjs/utils/route.d.ts.map +1 -0
  70. package/cjs/utils/route.js +76 -0
  71. package/esm/geometry/Line.d.ts +21 -0
  72. package/esm/geometry/Line.d.ts.map +1 -0
  73. package/esm/geometry/Line.js +96 -0
  74. package/esm/geometry/Point.d.ts +49 -0
  75. package/esm/geometry/Point.d.ts.map +1 -0
  76. package/esm/geometry/Point.js +117 -0
  77. package/esm/geometry/Rectangle.d.ts +41 -0
  78. package/esm/geometry/Rectangle.d.ts.map +1 -0
  79. package/esm/geometry/Rectangle.js +81 -0
  80. package/esm/geometry/index.d.ts +4 -0
  81. package/esm/geometry/index.d.ts.map +1 -0
  82. package/esm/geometry/index.js +3 -0
  83. package/esm/getManHattanPath.d.ts +60 -0
  84. package/esm/getManHattanPath.d.ts.map +1 -0
  85. package/esm/getManHattanPath.js +291 -0
  86. package/esm/index.d.ts +16 -0
  87. package/esm/index.d.ts.map +1 -0
  88. package/esm/index.js +24 -0
  89. package/esm/obstacle/ObstacleMap.d.ts +28 -0
  90. package/esm/obstacle/ObstacleMap.d.ts.map +1 -0
  91. package/esm/obstacle/ObstacleMap.js +183 -0
  92. package/esm/obstacle/index.d.ts +2 -0
  93. package/esm/obstacle/index.d.ts.map +1 -0
  94. package/esm/obstacle/index.js +1 -0
  95. package/esm/options/defaults.d.ts +16 -0
  96. package/esm/options/defaults.d.ts.map +1 -0
  97. package/esm/options/defaults.js +33 -0
  98. package/esm/options/index.d.ts +4 -0
  99. package/esm/options/index.d.ts.map +1 -0
  100. package/esm/options/index.js +3 -0
  101. package/esm/options/resolver.d.ts +10 -0
  102. package/esm/options/resolver.d.ts.map +1 -0
  103. package/esm/options/resolver.js +114 -0
  104. package/esm/options/types.d.ts +156 -0
  105. package/esm/options/types.d.ts.map +1 -0
  106. package/esm/options/types.js +1 -0
  107. package/esm/pathfinder/SortedSet.d.ts +35 -0
  108. package/esm/pathfinder/SortedSet.d.ts.map +1 -0
  109. package/esm/pathfinder/SortedSet.js +110 -0
  110. package/esm/pathfinder/findRoute.d.ts +8 -0
  111. package/esm/pathfinder/findRoute.d.ts.map +1 -0
  112. package/esm/pathfinder/findRoute.js +189 -0
  113. package/esm/pathfinder/index.d.ts +3 -0
  114. package/esm/pathfinder/index.d.ts.map +1 -0
  115. package/esm/pathfinder/index.js +2 -0
  116. package/esm/svg/index.d.ts +2 -0
  117. package/esm/svg/index.d.ts.map +1 -0
  118. package/esm/svg/index.js +1 -0
  119. package/esm/svg/pathConverter.d.ts +10 -0
  120. package/esm/svg/pathConverter.d.ts.map +1 -0
  121. package/esm/svg/pathConverter.js +107 -0
  122. package/esm/utils/direction.d.ts +24 -0
  123. package/esm/utils/direction.d.ts.map +1 -0
  124. package/esm/utils/direction.js +46 -0
  125. package/esm/utils/grid.d.ts +26 -0
  126. package/esm/utils/grid.d.ts.map +1 -0
  127. package/esm/utils/grid.js +70 -0
  128. package/esm/utils/index.d.ts +6 -0
  129. package/esm/utils/index.d.ts.map +1 -0
  130. package/esm/utils/index.js +5 -0
  131. package/esm/utils/node.d.ts +27 -0
  132. package/esm/utils/node.d.ts.map +1 -0
  133. package/esm/utils/node.js +30 -0
  134. package/esm/utils/rect.d.ts +9 -0
  135. package/esm/utils/rect.d.ts.map +1 -0
  136. package/esm/utils/rect.js +121 -0
  137. package/esm/utils/route.d.ts +19 -0
  138. package/esm/utils/route.d.ts.map +1 -0
  139. package/esm/utils/route.js +80 -0
  140. package/package.json +43 -0
@@ -0,0 +1,189 @@
1
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
2
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
3
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
4
+ import { SortedSet } from "./SortedSet";
5
+ import { getGrid, align, round, getDirectionAngle, getDirectionChange, getGridOffsets, getRectPoints, getCost, getKey, reconstructRoute } from "../utils";
6
+
7
+ /**
8
+ * Find route between two points using A* algorithm
9
+ */
10
+ export function findRoute(sourceBBox, targetBBox, sourceAnchor, targetAnchor, map, options) {
11
+ var precision = options.precision;
12
+
13
+ // Round anchor points
14
+ var sourceEndpoint = round(sourceAnchor.clone(), precision);
15
+ var targetEndpoint = round(targetAnchor.clone(), precision);
16
+
17
+ // Get grid for this route
18
+ var grid = getGrid(options.step, sourceEndpoint, targetEndpoint);
19
+
20
+ // Get pathfinding points
21
+ var startPoint = sourceEndpoint;
22
+ var endPoint = targetEndpoint;
23
+
24
+ // Get start and end points around rectangles
25
+ var startPoints = getRectPoints(startPoint, sourceBBox, options.startDirections, grid, options);
26
+ var endPoints = getRectPoints(targetEndpoint, targetBBox, options.endDirections, grid, options);
27
+ console.log('[findRoute] Start points from getRectPoints:', startPoints.map(function (p) {
28
+ return "(".concat(p.x, ", ").concat(p.y, ")");
29
+ }));
30
+ console.log('[findRoute] End points from getRectPoints:', endPoints.map(function (p) {
31
+ return "(".concat(p.x, ", ").concat(p.y, ")");
32
+ }));
33
+
34
+ // Take into account only accessible rect points
35
+ startPoints = startPoints.filter(function (p) {
36
+ return map.isAccessible(p);
37
+ });
38
+ endPoints = endPoints.filter(function (p) {
39
+ return map.isAccessible(p);
40
+ });
41
+ console.log('[findRoute] Start points after filter:', startPoints.map(function (p) {
42
+ return "(".concat(p.x, ", ").concat(p.y, ")");
43
+ }));
44
+ console.log('[findRoute] End points after filter:', endPoints.map(function (p) {
45
+ return "(".concat(p.x, ", ").concat(p.y, ")");
46
+ }));
47
+
48
+ // Ensure we always have at least the anchor points
49
+ // This handles edge cases where anchor is on the node boundary
50
+ if (startPoints.length === 0) {
51
+ startPoints = [align(startPoint, grid, precision)];
52
+ }
53
+ if (endPoints.length === 0) {
54
+ endPoints = [align(endPoint, grid, precision)];
55
+ }
56
+
57
+ // Initialize A* data structures
58
+ var openSet = new SortedSet();
59
+ var points = new Map();
60
+ var parents = new Map();
61
+ var costs = new Map();
62
+
63
+ // Add all start points to open set
64
+ var _iterator = _createForOfIteratorHelper(startPoints),
65
+ _step;
66
+ try {
67
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
68
+ var _startPoint = _step.value;
69
+ var key = getKey(_startPoint);
70
+ openSet.add(key, getCost(_startPoint, endPoints));
71
+ points.set(key, _startPoint);
72
+ costs.set(key, 0);
73
+ }
74
+ } catch (err) {
75
+ _iterator.e(err);
76
+ } finally {
77
+ _iterator.f();
78
+ }
79
+ var previousRouteDirectionAngle = options.previousDirectionAngle;
80
+ var isPathBeginning = previousRouteDirectionAngle === undefined;
81
+
82
+ // Get directions with grid offsets
83
+ var directions = getGridOffsets(grid, options);
84
+ var numDirections = directions.length;
85
+
86
+ // Create set of end point keys for quick lookup
87
+ var endPointsKeys = new Set(endPoints.map(function (p) {
88
+ return getKey(p);
89
+ }));
90
+
91
+ // Check if start and end points are the same
92
+ var sameStartEndPoints = startPoints.length === endPoints.length && startPoints.every(function (sp, i) {
93
+ return sp.equals(endPoints[i]);
94
+ });
95
+
96
+ // Main A* loop
97
+ var loopsRemaining = options.maxLoopCount;
98
+ while (!openSet.isEmpty() && loopsRemaining > 0) {
99
+ // Get the closest item and mark it CLOSED
100
+ var currentKey = openSet.pop();
101
+ if (!currentKey) break;
102
+ var currentPoint = points.get(currentKey);
103
+ var currentParent = parents.get(currentKey);
104
+ var currentCost = costs.get(currentKey);
105
+ var isStartPoint = currentPoint.equals(startPoint);
106
+ var isRouteBeginning = currentParent === undefined;
107
+
108
+ // Calculate previous direction angle
109
+ var previousDirectionAngle = void 0;
110
+ if (!isRouteBeginning) {
111
+ previousDirectionAngle = getDirectionAngle(currentParent, currentPoint, numDirections, grid, options);
112
+ } else if (!isPathBeginning) {
113
+ previousDirectionAngle = previousRouteDirectionAngle;
114
+ } else if (!isStartPoint) {
115
+ previousDirectionAngle = getDirectionAngle(startPoint, currentPoint, numDirections, grid, options);
116
+ } else {
117
+ previousDirectionAngle = null;
118
+ }
119
+
120
+ // Check if we reached any endpoint
121
+ var skipEndCheck = isRouteBeginning && sameStartEndPoints;
122
+ if (!skipEndCheck && endPointsKeys.has(currentKey)) {
123
+ options.previousDirectionAngle = previousDirectionAngle;
124
+ return reconstructRoute(parents, points, currentPoint, startPoint, endPoint);
125
+ }
126
+
127
+ // Explore neighbors in all directions
128
+ var _iterator2 = _createForOfIteratorHelper(directions),
129
+ _step2;
130
+ try {
131
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
132
+ var _previousDirectionAng;
133
+ var direction = _step2.value;
134
+ var directionAngle = direction.angle;
135
+ var directionChange = getDirectionChange((_previousDirectionAng = previousDirectionAngle) !== null && _previousDirectionAng !== void 0 ? _previousDirectionAng : 0, directionAngle);
136
+
137
+ // Don't use the point if direction changed too rapidly
138
+ if (!(isPathBeginning && isStartPoint) && directionChange > options.maxDirectionChange) {
139
+ continue;
140
+ }
141
+
142
+ // Calculate neighbor point
143
+ var neighborPoint = align(currentPoint.clone().translate(direction.gridOffsetX || 0, direction.gridOffsetY || 0), grid, precision);
144
+ var neighborKey = getKey(neighborPoint);
145
+
146
+ // Skip if closed or not accessible
147
+ if (openSet.isClose(neighborKey) || !map.isAccessible(neighborPoint)) {
148
+ continue;
149
+ }
150
+
151
+ // Check if neighbor is an end point
152
+ if (endPointsKeys.has(neighborKey)) {
153
+ var isEndPoint = neighborPoint.equals(endPoint);
154
+ if (!isEndPoint) {
155
+ var endDirectionAngle = getDirectionAngle(neighborPoint, endPoint, numDirections, grid, options);
156
+ var endDirectionChange = getDirectionChange(directionAngle, endDirectionAngle);
157
+ if (endDirectionChange > options.maxDirectionChange) {
158
+ continue;
159
+ }
160
+ }
161
+ }
162
+
163
+ // Calculate costs
164
+ var neighborCost = direction.cost;
165
+ var neighborPenalty = isStartPoint ? 0 : options.penalties[directionChange] || 0;
166
+ var costFromStart = currentCost + neighborCost + neighborPenalty;
167
+
168
+ // Update if not in open set or found better path
169
+ if (!openSet.isOpen(neighborKey) || costFromStart < (costs.get(neighborKey) || Infinity)) {
170
+ points.set(neighborKey, neighborPoint);
171
+ parents.set(neighborKey, currentPoint);
172
+ costs.set(neighborKey, costFromStart);
173
+ openSet.add(neighborKey, costFromStart + getCost(neighborPoint, endPoints));
174
+ }
175
+ }
176
+ } catch (err) {
177
+ _iterator2.e(err);
178
+ } finally {
179
+ _iterator2.f();
180
+ }
181
+ loopsRemaining -= 1;
182
+ }
183
+
184
+ // No path found, try fallback
185
+ if (options.fallbackRoute) {
186
+ return options.fallbackRoute(startPoint, endPoint);
187
+ }
188
+ return null;
189
+ }
@@ -0,0 +1,3 @@
1
+ export { SortedSet } from './SortedSet';
2
+ export { findRoute } from './findRoute';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pathfinder/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { SortedSet } from "./SortedSet";
2
+ export { findRoute } from "./findRoute";
@@ -0,0 +1,2 @@
1
+ export { pointsToPath, snapPathToGrid } from './pathConverter';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1 @@
1
+ export { pointsToPath, snapPathToGrid } from "./pathConverter";
@@ -0,0 +1,10 @@
1
+ import { Point } from '../geometry';
2
+ /**
3
+ * Convert array of points to SVG path string
4
+ */
5
+ export declare function pointsToPath(points: Point[], precision: number, borderRadius?: number): string;
6
+ /**
7
+ * Snap path to grid by aligning consecutive points
8
+ */
9
+ export declare function snapPathToGrid(points: Point[], gridSize: number): Point[];
10
+ //# sourceMappingURL=pathConverter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathConverter.d.ts","sourceRoot":"","sources":["../../src/svg/pathConverter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAEnC;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAE,MAAU,GAAG,MAAM,CAgEjG;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,EAAE,CAgCzE"}
@@ -0,0 +1,107 @@
1
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
2
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
7
+ /**
8
+ * Convert array of points to SVG path string
9
+ */
10
+ export function pointsToPath(points, precision) {
11
+ var borderRadius = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
12
+ if (points.length === 0) {
13
+ return '';
14
+ }
15
+ var factor = Math.pow(10, precision);
16
+ var roundCoord = function roundCoord(value) {
17
+ return Math.round(value * factor) / factor;
18
+ };
19
+
20
+ // If no border radius or only 2 points, use simple line path
21
+ if (borderRadius === 0 || points.length <= 2) {
22
+ var _firstPoint = points[0];
23
+ var _path = "M ".concat(roundCoord(_firstPoint.x), " ").concat(roundCoord(_firstPoint.y));
24
+ for (var i = 1; i < points.length; i++) {
25
+ var point = points[i];
26
+ _path += " L ".concat(roundCoord(point.x), " ").concat(roundCoord(point.y));
27
+ }
28
+ return _path;
29
+ }
30
+
31
+ // Start with M (moveTo) command for first point
32
+ var firstPoint = points[0];
33
+ var path = "M ".concat(roundCoord(firstPoint.x), " ").concat(roundCoord(firstPoint.y));
34
+
35
+ // Process each segment with rounded corners
36
+ for (var _i = 1; _i < points.length - 1; _i++) {
37
+ var prev = points[_i - 1];
38
+ var current = points[_i];
39
+ var next = points[_i + 1];
40
+
41
+ // Calculate the distance from prev to current and current to next
42
+ var distToPrev = Math.sqrt(Math.pow(current.x - prev.x, 2) + Math.pow(current.y - prev.y, 2));
43
+ var distToNext = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));
44
+
45
+ // Use the smaller of borderRadius or half the segment length
46
+ var radius = Math.min(borderRadius, distToPrev / 2, distToNext / 2);
47
+
48
+ // Calculate the point before the corner (on the line from prev to current)
49
+ var beforeCornerRatio = (distToPrev - radius) / distToPrev;
50
+ var beforeCorner = {
51
+ x: prev.x + (current.x - prev.x) * beforeCornerRatio,
52
+ y: prev.y + (current.y - prev.y) * beforeCornerRatio
53
+ };
54
+
55
+ // Calculate the point after the corner (on the line from current to next)
56
+ var afterCornerRatio = radius / distToNext;
57
+ var afterCorner = {
58
+ x: current.x + (next.x - current.x) * afterCornerRatio,
59
+ y: current.y + (next.y - current.y) * afterCornerRatio
60
+ };
61
+
62
+ // Draw line to the point before corner
63
+ path += " L ".concat(roundCoord(beforeCorner.x), " ").concat(roundCoord(beforeCorner.y));
64
+
65
+ // Draw quadratic bezier curve for the rounded corner
66
+ path += " Q ".concat(roundCoord(current.x), " ").concat(roundCoord(current.y), " ").concat(roundCoord(afterCorner.x), " ").concat(roundCoord(afterCorner.y));
67
+ }
68
+
69
+ // Draw line to the last point
70
+ var lastPoint = points[points.length - 1];
71
+ path += " L ".concat(roundCoord(lastPoint.x), " ").concat(roundCoord(lastPoint.y));
72
+ return path;
73
+ }
74
+
75
+ /**
76
+ * Snap path to grid by aligning consecutive points
77
+ */
78
+ export function snapPathToGrid(points, gridSize) {
79
+ if (points.length <= 1) {
80
+ return points;
81
+ }
82
+ var snappedPoints = _toConsumableArray(points);
83
+
84
+ // Don't snap the first and last points (anchors)
85
+ // Don't snap the second and second-to-last points (extension points)
86
+ // Only snap intermediate segments
87
+ for (var i = 2; i < snappedPoints.length - 3; i++) {
88
+ var first = snappedPoints[i];
89
+ var second = snappedPoints[i + 1];
90
+ if (first.x === second.x) {
91
+ // Vertical line - snap X coordinate
92
+ var x = gridSize * Math.round(first.x / gridSize);
93
+ if (first.x !== x) {
94
+ first.x = x;
95
+ second.x = x;
96
+ }
97
+ } else if (first.y === second.y) {
98
+ // Horizontal line - snap Y coordinate
99
+ var y = gridSize * Math.round(first.y / gridSize);
100
+ if (first.y !== y) {
101
+ first.y = y;
102
+ second.y = y;
103
+ }
104
+ }
105
+ }
106
+ return snappedPoints;
107
+ }
@@ -0,0 +1,24 @@
1
+ import { Point } from '../geometry';
2
+ import type { ResolvedOptions } from '../options';
3
+ import type { Grid } from './grid';
4
+ /**
5
+ * Get direction angle from start point to end point
6
+ * Corrects for grid deformation between start and end
7
+ */
8
+ export declare function getDirectionAngle(start: Point, end: Point, directionCount: number, grid: Grid, options: ResolvedOptions): number;
9
+ /**
10
+ * Get the change in direction between two direction angles
11
+ */
12
+ export declare function getDirectionChange(angle1: number, angle2: number): number;
13
+ /**
14
+ * Fix direction offsets according to current grid
15
+ */
16
+ export declare function getGridOffsets(grid: Grid, options: ResolvedOptions): {
17
+ cost: number;
18
+ offsetX: number;
19
+ offsetY: number;
20
+ angle?: number | undefined;
21
+ gridOffsetX?: number | undefined;
22
+ gridOffsetY?: number | undefined;
23
+ }[];
24
+ //# sourceMappingURL=direction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"direction.d.ts","sourceRoot":"","sources":["../../src/utils/direction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAyBlC;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,KAAK,EACV,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,eAAe,GACvB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGzE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe;;;;;;;IASlE"}
@@ -0,0 +1,46 @@
1
+ import { Point } from "../geometry";
2
+ import { normalizeAngle } from "../options/resolver";
3
+ /**
4
+ * Fix angle end point to account for grid deformation
5
+ */
6
+ function fixAngleEnd(start, end, grid, options) {
7
+ var step = options.step;
8
+ var diffX = end.x - start.x;
9
+ var diffY = end.y - start.y;
10
+ var gridStepsX = diffX / grid.x;
11
+ var gridStepsY = diffY / grid.y;
12
+ var distanceX = gridStepsX * step;
13
+ var distanceY = gridStepsY * step;
14
+ return new Point(start.x + distanceX, start.y + distanceY);
15
+ }
16
+
17
+ /**
18
+ * Get direction angle from start point to end point
19
+ * Corrects for grid deformation between start and end
20
+ */
21
+ export function getDirectionAngle(start, end, directionCount, grid, options) {
22
+ var quadrant = 360 / directionCount;
23
+ var angleTheta = start.theta(fixAngleEnd(start, end, grid, options));
24
+ var normalizedAngle = normalizeAngle(angleTheta + quadrant / 2);
25
+ return quadrant * Math.floor(normalizedAngle / quadrant);
26
+ }
27
+
28
+ /**
29
+ * Get the change in direction between two direction angles
30
+ */
31
+ export function getDirectionChange(angle1, angle2) {
32
+ var change = Math.abs(angle1 - angle2);
33
+ return change > 180 ? 360 - change : change;
34
+ }
35
+
36
+ /**
37
+ * Fix direction offsets according to current grid
38
+ */
39
+ export function getGridOffsets(grid, options) {
40
+ var step = options.step;
41
+ options.directions.forEach(function (direction) {
42
+ direction.gridOffsetX = direction.offsetX / step * grid.x;
43
+ direction.gridOffsetY = direction.offsetY / step * grid.y;
44
+ });
45
+ return options.directions;
46
+ }
@@ -0,0 +1,26 @@
1
+ import { Point } from '../geometry';
2
+ /**
3
+ * Grid interface for dynamic grid system
4
+ */
5
+ export interface Grid {
6
+ source: Point;
7
+ x: number;
8
+ y: number;
9
+ }
10
+ /**
11
+ * Get grid size in x and y dimensions, adapted to source and target positions
12
+ */
13
+ export declare function getGrid(step: number, source: Point, target: Point): Grid;
14
+ /**
15
+ * Snap a value to grid
16
+ */
17
+ export declare function snapToGrid(value: number, gridSize: number): number;
18
+ /**
19
+ * Align point to grid and apply precision
20
+ */
21
+ export declare function align(point: Point, grid: Grid, precision: number): Point;
22
+ /**
23
+ * Round point coordinates
24
+ */
25
+ export declare function round(point: Point, precision: number): Point;
26
+ //# sourceMappingURL=grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../src/utils/grid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAEnC;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,KAAK,CAAA;IACb,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AA2BD;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAG,IAAI,CAMxE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElE;AAYD;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK,CAExE;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK,CAE5D"}
@@ -0,0 +1,70 @@
1
+ import { Point } from "../geometry";
2
+
3
+ /**
4
+ * Grid interface for dynamic grid system
5
+ */
6
+
7
+ /**
8
+ * Get grid dimension for a single axis
9
+ */
10
+ function getGridDimension(diff, step) {
11
+ // Return step if diff = 0
12
+ if (!diff) {
13
+ return step;
14
+ }
15
+ var abs = Math.abs(diff);
16
+ var count = Math.round(abs / step);
17
+
18
+ // Return abs if less than one step apart
19
+ if (!count) {
20
+ return abs;
21
+ }
22
+
23
+ // Otherwise, return corrected step
24
+ var roundedDiff = count * step;
25
+ var remainder = abs - roundedDiff;
26
+ var correction = remainder / count;
27
+ return step + correction;
28
+ }
29
+
30
+ /**
31
+ * Get grid size in x and y dimensions, adapted to source and target positions
32
+ */
33
+ export function getGrid(step, source, target) {
34
+ return {
35
+ source: source.clone(),
36
+ x: getGridDimension(target.x - source.x, step),
37
+ y: getGridDimension(target.y - source.y, step)
38
+ };
39
+ }
40
+
41
+ /**
42
+ * Snap a value to grid
43
+ */
44
+ export function snapToGrid(value, gridSize) {
45
+ return Math.round(value / gridSize) * gridSize;
46
+ }
47
+
48
+ /**
49
+ * Snap a point to grid
50
+ */
51
+ function snapPointToGrid(point, grid) {
52
+ var source = grid.source;
53
+ var x = snapToGrid(point.x - source.x, grid.x) + source.x;
54
+ var y = snapToGrid(point.y - source.y, grid.y) + source.y;
55
+ return new Point(x, y);
56
+ }
57
+
58
+ /**
59
+ * Align point to grid and apply precision
60
+ */
61
+ export function align(point, grid, precision) {
62
+ return snapPointToGrid(point.clone(), grid).round(precision);
63
+ }
64
+
65
+ /**
66
+ * Round point coordinates
67
+ */
68
+ export function round(point, precision) {
69
+ return point.round(precision);
70
+ }
@@ -0,0 +1,6 @@
1
+ export * from './grid';
2
+ export * from './direction';
3
+ export * from './rect';
4
+ export * from './route';
5
+ export * from './node';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA"}
@@ -0,0 +1,5 @@
1
+ export * from "./grid";
2
+ export * from "./direction";
3
+ export * from "./rect";
4
+ export * from "./route";
5
+ export * from "./node";
@@ -0,0 +1,27 @@
1
+ import type { InternalNode } from '../options';
2
+ /**
3
+ * Node dimensions interface
4
+ */
5
+ export interface NodeDimensions {
6
+ width: number;
7
+ height: number;
8
+ }
9
+ /**
10
+ * Get node dimensions following ReactFlow's internal logic
11
+ * Priority: measured > direct property > initialWidth/Height > 0
12
+ *
13
+ * @param node - ReactFlow internal node
14
+ * @returns Node dimensions with width and height
15
+ */
16
+ export declare function getNodeDimensions(node: InternalNode): NodeDimensions;
17
+ /**
18
+ * Get node absolute position from internals
19
+ *
20
+ * @param node - ReactFlow internal node
21
+ * @returns Absolute position { x, y }
22
+ */
23
+ export declare function getNodePosition(node: InternalNode): {
24
+ x: number;
25
+ y: number;
26
+ };
27
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/utils/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,cAAc,CAKpE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAE5E"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Node dimensions interface
3
+ */
4
+
5
+ /**
6
+ * Get node dimensions following ReactFlow's internal logic
7
+ * Priority: measured > direct property > initialWidth/Height > 0
8
+ *
9
+ * @param node - ReactFlow internal node
10
+ * @returns Node dimensions with width and height
11
+ */
12
+ export function getNodeDimensions(node) {
13
+ var _ref, _ref2, _node$measured$width, _node$measured, _ref3, _ref4, _node$measured$height, _node$measured2;
14
+ var width = (_ref = (_ref2 = (_node$measured$width = (_node$measured = node.measured) === null || _node$measured === void 0 ? void 0 : _node$measured.width) !== null && _node$measured$width !== void 0 ? _node$measured$width : node.width) !== null && _ref2 !== void 0 ? _ref2 : node.initialWidth) !== null && _ref !== void 0 ? _ref : 0;
15
+ var height = (_ref3 = (_ref4 = (_node$measured$height = (_node$measured2 = node.measured) === null || _node$measured2 === void 0 ? void 0 : _node$measured2.height) !== null && _node$measured$height !== void 0 ? _node$measured$height : node.height) !== null && _ref4 !== void 0 ? _ref4 : node.initialHeight) !== null && _ref3 !== void 0 ? _ref3 : 0;
16
+ return {
17
+ width: width,
18
+ height: height
19
+ };
20
+ }
21
+
22
+ /**
23
+ * Get node absolute position from internals
24
+ *
25
+ * @param node - ReactFlow internal node
26
+ * @returns Absolute position { x, y }
27
+ */
28
+ export function getNodePosition(node) {
29
+ return node.internals.positionAbsolute;
30
+ }
@@ -0,0 +1,9 @@
1
+ import { Point, Rectangle } from '../geometry';
2
+ import type { ResolvedOptions, Direction } from '../options';
3
+ import type { Grid } from './grid';
4
+ /**
5
+ * Get points around a rectangle taking given directions into account
6
+ * Lines are drawn from anchor in given directions, intersections recorded
7
+ */
8
+ export declare function getRectPoints(anchor: Point, bbox: Rectangle, directionList: Direction[], grid: Grid, options: ResolvedOptions): Point[];
9
+ //# sourceMappingURL=rect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rect.d.ts","sourceRoot":"","sources":["../../src/utils/rect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAQ,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AA6ClC;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,KAAK,EACb,IAAI,EAAE,SAAS,EACf,aAAa,EAAE,SAAS,EAAE,EAC1B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,eAAe,GACvB,KAAK,EAAE,CAsET"}