@rxflow/manhattan 0.0.1-alpha.0 → 0.0.1-alpha.10

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 (49) hide show
  1. package/cjs/geometry/collision.d.ts +15 -0
  2. package/cjs/geometry/collision.d.ts.map +1 -0
  3. package/cjs/geometry/collision.js +81 -0
  4. package/cjs/geometry/index.d.ts +1 -0
  5. package/cjs/geometry/index.d.ts.map +1 -1
  6. package/cjs/geometry/index.js +20 -1
  7. package/cjs/getManHattanPath.d.ts +7 -14
  8. package/cjs/getManHattanPath.d.ts.map +1 -1
  9. package/cjs/getManHattanPath.js +54 -54
  10. package/cjs/options/defaults.js +1 -1
  11. package/cjs/svg/index.d.ts +1 -0
  12. package/cjs/svg/index.d.ts.map +1 -1
  13. package/cjs/svg/index.js +14 -1
  14. package/cjs/svg/pathParser.d.ts +11 -0
  15. package/cjs/svg/pathParser.d.ts.map +1 -0
  16. package/cjs/svg/pathParser.js +76 -0
  17. package/cjs/utils/grid.d.ts.map +1 -1
  18. package/cjs/utils/grid.js +3 -17
  19. package/cjs/utils/index.d.ts +1 -0
  20. package/cjs/utils/index.d.ts.map +1 -1
  21. package/cjs/utils/index.js +11 -0
  22. package/cjs/utils/pathValidation.d.ts +11 -0
  23. package/cjs/utils/pathValidation.d.ts.map +1 -0
  24. package/cjs/utils/pathValidation.js +130 -0
  25. package/esm/geometry/collision.d.ts +15 -0
  26. package/esm/geometry/collision.d.ts.map +1 -0
  27. package/esm/geometry/collision.js +73 -0
  28. package/esm/geometry/index.d.ts +1 -0
  29. package/esm/geometry/index.d.ts.map +1 -1
  30. package/esm/geometry/index.js +2 -1
  31. package/esm/getManHattanPath.d.ts +7 -14
  32. package/esm/getManHattanPath.d.ts.map +1 -1
  33. package/esm/getManHattanPath.js +70 -64
  34. package/esm/options/defaults.js +1 -1
  35. package/esm/svg/index.d.ts +1 -0
  36. package/esm/svg/index.d.ts.map +1 -1
  37. package/esm/svg/index.js +2 -1
  38. package/esm/svg/pathParser.d.ts +11 -0
  39. package/esm/svg/pathParser.d.ts.map +1 -0
  40. package/esm/svg/pathParser.js +82 -0
  41. package/esm/utils/grid.d.ts.map +1 -1
  42. package/esm/utils/grid.js +3 -17
  43. package/esm/utils/index.d.ts +1 -0
  44. package/esm/utils/index.d.ts.map +1 -1
  45. package/esm/utils/index.js +2 -1
  46. package/esm/utils/pathValidation.d.ts +11 -0
  47. package/esm/utils/pathValidation.d.ts.map +1 -0
  48. package/esm/utils/pathValidation.js +162 -0
  49. package/package.json +1 -1
@@ -1 +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"}
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;AAWD;;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"}
package/esm/utils/grid.js CHANGED
@@ -8,23 +8,9 @@ import { Point } from "../geometry";
8
8
  * Get grid dimension for a single axis
9
9
  */
10
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;
11
+ // Always return fixed step size to maintain consistent padding
12
+ // This ensures paths stay at least 'padding' distance from obstacles
13
+ return step;
28
14
  }
29
15
 
30
16
  /**
@@ -3,4 +3,5 @@ export * from './direction';
3
3
  export * from './rect';
4
4
  export * from './route';
5
5
  export * from './node';
6
+ export * from './pathValidation';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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"}
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;AACtB,cAAc,kBAAkB,CAAA"}
@@ -2,4 +2,5 @@ export * from "./grid";
2
2
  export * from "./direction";
3
3
  export * from "./rect";
4
4
  export * from "./route";
5
- export * from "./node";
5
+ export * from "./node";
6
+ export * from "./pathValidation";
@@ -0,0 +1,11 @@
1
+ import { Point } from '../geometry';
2
+ import type { NodeLookup } from '../options';
3
+ /**
4
+ * Check if a path intersects with any obstacles (nodes)
5
+ * A path is considered to intersect if it has >= 2 unique intersection points with a node
6
+ *
7
+ * Note: pathPoints should be pre-processed by parseSVGPath which samples bezier curves
8
+ * into line segments, so this function works correctly with curved paths
9
+ */
10
+ export declare function pathIntersectsObstacles(pathPoints: Point[], nodeLookup: NodeLookup): boolean;
11
+ //# sourceMappingURL=pathValidation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathValidation.d.ts","sourceRoot":"","sources":["../../src/utils/pathValidation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAa,MAAM,aAAa,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAyF5C;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAoC5F"}
@@ -0,0 +1,162 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
4
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
5
+ 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; } } }; }
6
+ 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); }
7
+ 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; }
8
+ import { Point, Rectangle } from "../geometry";
9
+ import { getNodeDimensions, getNodePosition } from "./node";
10
+
11
+ /**
12
+ * Get node bounding box
13
+ */
14
+ function getNodeBBox(nodeId, nodeLookup) {
15
+ var node = nodeLookup.get(nodeId);
16
+ if (!node) return null;
17
+ var dimensions = getNodeDimensions(node);
18
+ var position = getNodePosition(node);
19
+ return new Rectangle(position.x, position.y, dimensions.width, dimensions.height);
20
+ }
21
+
22
+ /**
23
+ * Find unique intersection points between a line segment and a rectangle
24
+ * Returns array of intersection points (deduplicated)
25
+ */
26
+ function findSegmentRectIntersections(p1, p2, rect) {
27
+ var intersections = [];
28
+ var tolerance = 0.01;
29
+
30
+ // Define rectangle edges
31
+ var edges = [{
32
+ start: new Point(rect.x, rect.y),
33
+ end: new Point(rect.x + rect.width, rect.y)
34
+ },
35
+ // Top
36
+ {
37
+ start: new Point(rect.x + rect.width, rect.y),
38
+ end: new Point(rect.x + rect.width, rect.y + rect.height)
39
+ },
40
+ // Right
41
+ {
42
+ start: new Point(rect.x + rect.width, rect.y + rect.height),
43
+ end: new Point(rect.x, rect.y + rect.height)
44
+ },
45
+ // Bottom
46
+ {
47
+ start: new Point(rect.x, rect.y + rect.height),
48
+ end: new Point(rect.x, rect.y)
49
+ } // Left
50
+ ];
51
+
52
+ // Find intersection point with each edge
53
+ var _loop = function _loop() {
54
+ var edge = _edges[_i];
55
+ var intersection = getLineSegmentIntersection(p1, p2, edge.start, edge.end);
56
+ if (intersection) {
57
+ // Check if this point is already in the list (avoid duplicates at corners)
58
+ var isDuplicate = intersections.some(function (existing) {
59
+ return Math.abs(existing.x - intersection.x) < tolerance && Math.abs(existing.y - intersection.y) < tolerance;
60
+ });
61
+ if (!isDuplicate) {
62
+ intersections.push(intersection);
63
+ }
64
+ }
65
+ };
66
+ for (var _i = 0, _edges = edges; _i < _edges.length; _i++) {
67
+ _loop();
68
+ }
69
+ return intersections;
70
+ }
71
+
72
+ /**
73
+ * Get intersection point between two line segments (if exists)
74
+ */
75
+ function getLineSegmentIntersection(p1, p2, p3, p4) {
76
+ var d1 = direction(p3, p4, p1);
77
+ var d2 = direction(p3, p4, p2);
78
+ var d3 = direction(p1, p2, p3);
79
+ var d4 = direction(p1, p2, p4);
80
+ if ((d1 > 0 && d2 < 0 || d1 < 0 && d2 > 0) && (d3 > 0 && d4 < 0 || d3 < 0 && d4 > 0)) {
81
+ // Lines intersect, calculate intersection point
82
+ var t = ((p3.x - p1.x) * (p3.y - p4.y) - (p3.y - p1.y) * (p3.x - p4.x)) / ((p1.x - p2.x) * (p3.y - p4.y) - (p1.y - p2.y) * (p3.x - p4.x));
83
+ return new Point(p1.x + t * (p2.x - p1.x), p1.y + t * (p2.y - p1.y));
84
+ }
85
+
86
+ // Check collinear cases
87
+ if (d1 === 0 && onSegment(p3, p1, p4)) return p1.clone();
88
+ if (d2 === 0 && onSegment(p3, p2, p4)) return p2.clone();
89
+ if (d3 === 0 && onSegment(p1, p3, p2)) return p3.clone();
90
+ if (d4 === 0 && onSegment(p1, p4, p2)) return p4.clone();
91
+ return null;
92
+ }
93
+ function direction(p1, p2, p3) {
94
+ return (p3.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (p3.y - p1.y);
95
+ }
96
+ function onSegment(p1, p2, p3) {
97
+ return p2.x >= Math.min(p1.x, p3.x) && p2.x <= Math.max(p1.x, p3.x) && p2.y >= Math.min(p1.y, p3.y) && p2.y <= Math.max(p1.y, p3.y);
98
+ }
99
+
100
+ /**
101
+ * Check if a path intersects with any obstacles (nodes)
102
+ * A path is considered to intersect if it has >= 2 unique intersection points with a node
103
+ *
104
+ * Note: pathPoints should be pre-processed by parseSVGPath which samples bezier curves
105
+ * into line segments, so this function works correctly with curved paths
106
+ */
107
+ export function pathIntersectsObstacles(pathPoints, nodeLookup) {
108
+ var tolerance = 0.01;
109
+
110
+ // Iterate through all nodes (including source and target)
111
+ var _iterator = _createForOfIteratorHelper(nodeLookup),
112
+ _step;
113
+ try {
114
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
115
+ var _step$value = _slicedToArray(_step.value, 1),
116
+ nodeId = _step$value[0];
117
+ var nodeBBox = getNodeBBox(nodeId, nodeLookup);
118
+ if (!nodeBBox) continue;
119
+ var allIntersections = [];
120
+
121
+ // Collect all unique intersection points for this node
122
+ for (var i = 0; i < pathPoints.length - 1; i++) {
123
+ var p1 = pathPoints[i];
124
+ var p2 = pathPoints[i + 1];
125
+ var segmentIntersections = findSegmentRectIntersections(p1, p2, nodeBBox);
126
+
127
+ // Add to global list, avoiding duplicates
128
+ var _iterator2 = _createForOfIteratorHelper(segmentIntersections),
129
+ _step2;
130
+ try {
131
+ var _loop2 = function _loop2() {
132
+ var intersection = _step2.value;
133
+ var isDuplicate = allIntersections.some(function (existing) {
134
+ return Math.abs(existing.x - intersection.x) < tolerance && Math.abs(existing.y - intersection.y) < tolerance;
135
+ });
136
+ if (!isDuplicate) {
137
+ allIntersections.push(intersection);
138
+ }
139
+ };
140
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
141
+ _loop2();
142
+ }
143
+ } catch (err) {
144
+ _iterator2.e(err);
145
+ } finally {
146
+ _iterator2.f();
147
+ }
148
+ }
149
+
150
+ // If path has 2 or more unique intersections with this node, it crosses through it
151
+ if (allIntersections.length >= 2) {
152
+ console.log("[pathIntersectsObstacles] Path crosses node ".concat(nodeId, " with ").concat(allIntersections.length, " intersections"));
153
+ return true;
154
+ }
155
+ }
156
+ } catch (err) {
157
+ _iterator.e(err);
158
+ } finally {
159
+ _iterator.f();
160
+ }
161
+ return false;
162
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rxflow/manhattan",
3
- "version": "0.0.1-alpha.0",
3
+ "version": "0.0.1-alpha.10",
4
4
  "description": "Manhattan routing algorithm for ReactFlow - generates orthogonal paths with obstacle avoidance",
5
5
  "keywords": [
6
6
  "reactflow",