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

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/Rectangle.d.ts +1 -1
  2. package/cjs/geometry/Rectangle.js +2 -2
  3. package/cjs/getManHattanPath.d.ts.map +1 -1
  4. package/cjs/getManHattanPath.js +153 -20
  5. package/cjs/obstacle/ObstacleMap.d.ts +7 -1
  6. package/cjs/obstacle/ObstacleMap.d.ts.map +1 -1
  7. package/cjs/obstacle/ObstacleMap.js +53 -1
  8. package/cjs/options/defaults.d.ts +1 -1
  9. package/cjs/options/defaults.d.ts.map +1 -1
  10. package/cjs/options/defaults.js +1 -1
  11. package/cjs/options/resolver.d.ts.map +1 -1
  12. package/cjs/options/resolver.js +4 -2
  13. package/cjs/options/types.d.ts +19 -6
  14. package/cjs/options/types.d.ts.map +1 -1
  15. package/cjs/pathfinder/findRoute.d.ts.map +1 -1
  16. package/cjs/pathfinder/findRoute.js +184 -13
  17. package/cjs/svg/pathConverter.d.ts.map +1 -1
  18. package/cjs/svg/pathConverter.js +23 -12
  19. package/cjs/utils/getAnchorPoints.d.ts +15 -0
  20. package/cjs/utils/getAnchorPoints.d.ts.map +1 -0
  21. package/cjs/utils/getAnchorPoints.js +75 -0
  22. package/cjs/utils/index.d.ts +1 -0
  23. package/cjs/utils/index.d.ts.map +1 -1
  24. package/cjs/utils/index.js +11 -0
  25. package/esm/geometry/Rectangle.d.ts +1 -1
  26. package/esm/geometry/Rectangle.js +2 -2
  27. package/esm/getManHattanPath.d.ts.map +1 -1
  28. package/esm/getManHattanPath.js +162 -22
  29. package/esm/obstacle/ObstacleMap.d.ts +7 -1
  30. package/esm/obstacle/ObstacleMap.d.ts.map +1 -1
  31. package/esm/obstacle/ObstacleMap.js +78 -0
  32. package/esm/options/defaults.d.ts +1 -1
  33. package/esm/options/defaults.d.ts.map +1 -1
  34. package/esm/options/defaults.js +1 -1
  35. package/esm/options/resolver.d.ts.map +1 -1
  36. package/esm/options/resolver.js +5 -3
  37. package/esm/options/types.d.ts +19 -6
  38. package/esm/options/types.d.ts.map +1 -1
  39. package/esm/pathfinder/findRoute.d.ts.map +1 -1
  40. package/esm/pathfinder/findRoute.js +206 -21
  41. package/esm/svg/pathConverter.d.ts.map +1 -1
  42. package/esm/svg/pathConverter.js +23 -12
  43. package/esm/utils/getAnchorPoints.d.ts +15 -0
  44. package/esm/utils/getAnchorPoints.d.ts.map +1 -0
  45. package/esm/utils/getAnchorPoints.js +69 -0
  46. package/esm/utils/index.d.ts +1 -0
  47. package/esm/utils/index.d.ts.map +1 -1
  48. package/esm/utils/index.js +2 -1
  49. package/package.json +1 -1
@@ -4,8 +4,114 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.findRoute = findRoute;
7
+ var _geometry = require("../geometry");
7
8
  var _SortedSet = require("./SortedSet");
8
9
  var _utils = require("../utils");
10
+ /**
11
+ * Generate smart points based on position using extensionDistance and binary search
12
+ *
13
+ * Algorithm:
14
+ * 1. First try extensionDistance in the specified direction
15
+ * 2. If blocked, use binary search starting from step, halving until finding accessible point
16
+ * 3. For target points, approach from opposite direction
17
+ */
18
+ function generateSmartPoints(anchor, bbox, position, grid, map, options, isTarget = false) {
19
+ const directionMap = {
20
+ 'right': {
21
+ x: 1,
22
+ y: 0
23
+ },
24
+ 'left': {
25
+ x: -1,
26
+ y: 0
27
+ },
28
+ 'top': {
29
+ x: 0,
30
+ y: -1
31
+ },
32
+ 'bottom': {
33
+ x: 0,
34
+ y: 1
35
+ }
36
+ };
37
+ const direction = directionMap[position];
38
+ if (!direction) {
39
+ console.warn(`[generateSmartPoints] Unknown position: ${position}, falling back to anchor`);
40
+ return [anchor];
41
+ }
42
+
43
+ // Both source and target extend in the specified direction
44
+ // - Source: extends away from node in sourcePosition direction
45
+ // - Target: extends away from node in targetPosition direction (path approaches from this direction)
46
+ const actualDirection = direction;
47
+ const points = [];
48
+
49
+ // 1. First try extensionDistance
50
+ const extensionPoint = new _geometry.Point(anchor.x + actualDirection.x * options.extensionDistance, anchor.y + actualDirection.y * options.extensionDistance).round(options.precision);
51
+ console.log(`[generateSmartPoints] ${isTarget ? 'Target' : 'Source'} position=${position}, trying extension point: (${extensionPoint.x}, ${extensionPoint.y})`);
52
+ if (map.isAccessible(extensionPoint)) {
53
+ points.push(extensionPoint);
54
+ console.log(`[generateSmartPoints] Extension point is accessible`);
55
+ return points;
56
+ }
57
+ console.log(`[generateSmartPoints] Extension point blocked, using step-based search`);
58
+
59
+ // 2. Step-based search with binary refinement
60
+ // First, extend outward by step increments until we find an accessible point
61
+ let stepMultiplier = 1;
62
+ let maxSteps = 20; // Prevent infinite loop
63
+ let foundAccessibleDistance = -1;
64
+ console.log(`[generateSmartPoints] Starting outward search with step=${options.step}`);
65
+ while (stepMultiplier <= maxSteps) {
66
+ const distance = stepMultiplier * options.step;
67
+ const testPoint = new _geometry.Point(anchor.x + actualDirection.x * distance, anchor.y + actualDirection.y * distance).round(options.precision);
68
+ console.log(`[generateSmartPoints] Testing ${stepMultiplier}*step (distance=${distance}): (${testPoint.x}, ${testPoint.y})`);
69
+ if (map.isAccessible(testPoint)) {
70
+ foundAccessibleDistance = distance;
71
+ console.log(`[generateSmartPoints] Found accessible point at ${stepMultiplier}*step (distance=${distance})`);
72
+ break;
73
+ }
74
+ stepMultiplier++;
75
+ }
76
+
77
+ // 3. If we found an accessible point, refine by binary search within the last step interval
78
+ if (foundAccessibleDistance > 0) {
79
+ const outerDistance = foundAccessibleDistance;
80
+ const innerDistance = foundAccessibleDistance - options.step;
81
+ console.log(`[generateSmartPoints] Refining between ${innerDistance} and ${outerDistance}`);
82
+
83
+ // Binary search within the last step interval to find the closest accessible point
84
+ let left = innerDistance;
85
+ let right = outerDistance;
86
+ let bestDistance = outerDistance;
87
+
88
+ // Binary search with precision of 1px
89
+ while (right - left > 1) {
90
+ const mid = (left + right) / 2;
91
+ const testPoint = new _geometry.Point(anchor.x + actualDirection.x * mid, anchor.y + actualDirection.y * mid).round(options.precision);
92
+ console.log(`[generateSmartPoints] Binary search testing distance ${mid.toFixed(1)}: (${testPoint.x}, ${testPoint.y})`);
93
+ if (map.isAccessible(testPoint)) {
94
+ bestDistance = mid;
95
+ right = mid;
96
+ console.log(`[generateSmartPoints] Point accessible, searching closer (right=${right})`);
97
+ } else {
98
+ left = mid;
99
+ console.log(`[generateSmartPoints] Point blocked, searching further (left=${left})`);
100
+ }
101
+ }
102
+
103
+ // Use the best distance found
104
+ const finalPoint = new _geometry.Point(anchor.x + actualDirection.x * bestDistance, anchor.y + actualDirection.y * bestDistance).round(options.precision);
105
+ points.push(finalPoint);
106
+ console.log(`[generateSmartPoints] Final point at distance ${bestDistance}: (${finalPoint.x}, ${finalPoint.y})`);
107
+ } else {
108
+ // 4. If no accessible point found after maxSteps, use anchor as fallback
109
+ console.log(`[generateSmartPoints] No accessible point found after ${maxSteps} steps, using anchor: (${anchor.x}, ${anchor.y})`);
110
+ points.push(anchor);
111
+ }
112
+ return points;
113
+ }
114
+
9
115
  /**
10
116
  * Find route between two points using A* algorithm
11
117
  */
@@ -24,24 +130,41 @@ function findRoute(sourceBBox, targetBBox, sourceAnchor, targetAnchor, map, opti
24
130
  const endPoint = targetEndpoint;
25
131
 
26
132
  // Get start and end points around rectangles
27
- let startPoints = (0, _utils.getRectPoints)(startPoint, sourceBBox, options.startDirections, grid, options);
28
- let endPoints = (0, _utils.getRectPoints)(targetEndpoint, targetBBox, options.endDirections, grid, options);
29
- console.log('[findRoute] Start points from getRectPoints:', startPoints.map(p => `(${p.x}, ${p.y})`));
30
- console.log('[findRoute] End points from getRectPoints:', endPoints.map(p => `(${p.x}, ${p.y})`));
31
-
32
- // Take into account only accessible rect points
33
- startPoints = startPoints.filter(p => map.isAccessible(p));
34
- endPoints = endPoints.filter(p => map.isAccessible(p));
133
+ // Use smart point generation based on position if available
134
+ let startPoints;
135
+ let endPoints;
136
+
137
+ // Generate smart start points based on sourcePosition
138
+ if (options.sourcePosition) {
139
+ startPoints = generateSmartPoints(startPoint, sourceBBox, options.sourcePosition, grid, map, options, false);
140
+ console.log('[findRoute] Start points from smart generation:', startPoints.map(p => `(${p.x}, ${p.y})`));
141
+ } else {
142
+ startPoints = (0, _utils.getRectPoints)(startPoint, sourceBBox, options.startDirections, grid, options);
143
+ console.log('[findRoute] Start points from getRectPoints:', startPoints.map(p => `(${p.x}, ${p.y})`));
144
+ // Take into account only accessible rect points
145
+ startPoints = startPoints.filter(p => map.isAccessible(p));
146
+ }
147
+
148
+ // Generate smart end points based on targetPosition
149
+ if (options.targetPosition) {
150
+ endPoints = generateSmartPoints(targetEndpoint, targetBBox, options.targetPosition, grid, map, options, true);
151
+ console.log('[findRoute] End points from smart generation:', endPoints.map(p => `(${p.x}, ${p.y})`));
152
+ } else {
153
+ endPoints = (0, _utils.getRectPoints)(targetEndpoint, targetBBox, options.endDirections, grid, options);
154
+ console.log('[findRoute] End points from getRectPoints:', endPoints.map(p => `(${p.x}, ${p.y})`));
155
+ // Take into account only accessible rect points
156
+ endPoints = endPoints.filter(p => map.isAccessible(p));
157
+ }
35
158
  console.log('[findRoute] Start points after filter:', startPoints.map(p => `(${p.x}, ${p.y})`));
36
159
  console.log('[findRoute] End points after filter:', endPoints.map(p => `(${p.x}, ${p.y})`));
37
160
 
38
161
  // Ensure we always have at least the anchor points
39
162
  // This handles edge cases where anchor is on the node boundary
40
163
  if (startPoints.length === 0) {
41
- startPoints = [(0, _utils.align)(startPoint, grid, precision)];
164
+ startPoints = [(0, _utils.round)(startPoint, precision)];
42
165
  }
43
166
  if (endPoints.length === 0) {
44
- endPoints = [(0, _utils.align)(endPoint, grid, precision)];
167
+ endPoints = [(0, _utils.round)(endPoint, precision)];
45
168
  }
46
169
 
47
170
  // Initialize A* data structures
@@ -111,8 +234,8 @@ function findRoute(sourceBBox, targetBBox, sourceAnchor, targetAnchor, map, opti
111
234
  continue;
112
235
  }
113
236
 
114
- // Calculate neighbor point
115
- const neighborPoint = (0, _utils.align)(currentPoint.clone().translate(direction.gridOffsetX || 0, direction.gridOffsetY || 0), grid, precision);
237
+ // Calculate neighbor point (no grid alignment)
238
+ const neighborPoint = (0, _utils.round)(currentPoint.clone().translate(direction.gridOffsetX || 0, direction.gridOffsetY || 0), precision);
116
239
  const neighborKey = (0, _utils.getKey)(neighborPoint);
117
240
 
118
241
  // Skip if closed or not accessible
@@ -120,7 +243,55 @@ function findRoute(sourceBBox, targetBBox, sourceAnchor, targetAnchor, map, opti
120
243
  continue;
121
244
  }
122
245
 
123
- // Check if neighbor is an end point
246
+ // Check if we can reach any end point directly from this neighbor
247
+ // This allows connecting to end points that are not on the grid
248
+ let canReachEndPoint = false;
249
+ let reachableEndPoint = null;
250
+ for (const endPt of endPoints) {
251
+ const distanceToEnd = neighborPoint.manhattanDistance(endPt);
252
+
253
+ // If close enough to end point (within step distance), try direct connection
254
+ if (distanceToEnd < options.step * 1.5) {
255
+ // Check if we can move directly to the end point
256
+ const dx = endPt.x - neighborPoint.x;
257
+ const dy = endPt.y - neighborPoint.y;
258
+
259
+ // Allow direct connection if it's orthogonal or close to orthogonal
260
+ const isOrthogonal = Math.abs(dx) < 0.1 || Math.abs(dy) < 0.1;
261
+ if (isOrthogonal && map.isAccessible(endPt)) {
262
+ canReachEndPoint = true;
263
+ reachableEndPoint = endPt;
264
+ break;
265
+ }
266
+ }
267
+ }
268
+
269
+ // If we can reach an end point directly, add it as the final step
270
+ if (canReachEndPoint && reachableEndPoint) {
271
+ const endKey = (0, _utils.getKey)(reachableEndPoint);
272
+ const endCost = neighborPoint.manhattanDistance(reachableEndPoint);
273
+ const totalCost = currentCost + direction.cost + endCost;
274
+ if (!openSet.isOpen(endKey) || totalCost < (costs.get(endKey) || Infinity)) {
275
+ points.set(endKey, reachableEndPoint);
276
+ parents.set(endKey, neighborPoint);
277
+ costs.set(endKey, totalCost);
278
+
279
+ // Also add the neighbor point if not already added
280
+ if (!points.has(neighborKey)) {
281
+ points.set(neighborKey, neighborPoint);
282
+ parents.set(neighborKey, currentPoint);
283
+ costs.set(neighborKey, currentCost + direction.cost);
284
+ }
285
+
286
+ // Check if this is our target end point
287
+ if (endPointsKeys.has(endKey)) {
288
+ options.previousDirectionAngle = directionAngle;
289
+ return (0, _utils.reconstructRoute)(parents, points, reachableEndPoint, startPoint, endPoint);
290
+ }
291
+ }
292
+ }
293
+
294
+ // Check if neighbor is an end point (exact match)
124
295
  if (endPointsKeys.has(neighborKey)) {
125
296
  const isEndPoint = neighborPoint.equals(endPoint);
126
297
  if (!isEndPoint) {
@@ -1 +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"}
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,CA2EjG;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,EAAE,CAgCzE"}
@@ -36,31 +36,42 @@ function pointsToPath(points, precision, borderRadius = 0) {
36
36
  const current = points[i];
37
37
  const next = points[i + 1];
38
38
 
39
- // Calculate the distance from prev to current and current to next
40
- const distToPrev = Math.sqrt(Math.pow(current.x - prev.x, 2) + Math.pow(current.y - prev.y, 2));
41
- const distToNext = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));
39
+ // Calculate direction vectors
40
+ const dx1 = current.x - prev.x;
41
+ const dy1 = current.y - prev.y;
42
+ const dx2 = next.x - current.x;
43
+ const dy2 = next.y - current.y;
44
+
45
+ // Calculate distances
46
+ const dist1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
47
+ const dist2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
42
48
 
43
49
  // Use the smaller of borderRadius or half the segment length
44
- const radius = Math.min(borderRadius, distToPrev / 2, distToNext / 2);
50
+ const radius = Math.min(borderRadius, dist1 / 2, dist2 / 2);
51
+
52
+ // Normalize direction vectors
53
+ const ndx1 = dx1 / dist1;
54
+ const ndy1 = dy1 / dist1;
55
+ const ndx2 = dx2 / dist2;
56
+ const ndy2 = dy2 / dist2;
45
57
 
46
- // Calculate the point before the corner (on the line from prev to current)
47
- const beforeCornerRatio = (distToPrev - radius) / distToPrev;
58
+ // Calculate the point before the corner
48
59
  const beforeCorner = {
49
- x: prev.x + (current.x - prev.x) * beforeCornerRatio,
50
- y: prev.y + (current.y - prev.y) * beforeCornerRatio
60
+ x: current.x - ndx1 * radius,
61
+ y: current.y - ndy1 * radius
51
62
  };
52
63
 
53
- // Calculate the point after the corner (on the line from current to next)
54
- const afterCornerRatio = radius / distToNext;
64
+ // Calculate the point after the corner
55
65
  const afterCorner = {
56
- x: current.x + (next.x - current.x) * afterCornerRatio,
57
- y: current.y + (next.y - current.y) * afterCornerRatio
66
+ x: current.x + ndx2 * radius,
67
+ y: current.y + ndy2 * radius
58
68
  };
59
69
 
60
70
  // Draw line to the point before corner
61
71
  path += ` L ${roundCoord(beforeCorner.x)} ${roundCoord(beforeCorner.y)}`;
62
72
 
63
73
  // Draw quadratic bezier curve for the rounded corner
74
+ // The control point is the actual corner point
64
75
  path += ` Q ${roundCoord(current.x)} ${roundCoord(current.y)} ${roundCoord(afterCorner.x)} ${roundCoord(afterCorner.y)}`;
65
76
  }
66
77
 
@@ -0,0 +1,15 @@
1
+ import { Point } from '../geometry';
2
+ import type { ObstacleMap } from '../obstacle';
3
+ import type { Direction } from '../options';
4
+ /**
5
+ * Get accessible anchor points using binary search optimization
6
+ *
7
+ * @param anchor - The anchor point (on node edge)
8
+ * @param position - The position/direction (right, left, top, bottom)
9
+ * @param extensionDistance - The preferred extension distance
10
+ * @param step - The step size for binary search
11
+ * @param obstacleMap - The obstacle map for accessibility checking
12
+ * @returns Array of accessible points, prioritized by distance
13
+ */
14
+ export declare function getAnchorPoints(anchor: Point, position: Direction, extensionDistance: number, step: number, obstacleMap: ObstacleMap): Point[];
15
+ //# sourceMappingURL=getAnchorPoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getAnchorPoints.d.ts","sourceRoot":"","sources":["../../src/utils/getAnchorPoints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,KAAK,EACb,QAAQ,EAAE,SAAS,EACnB,iBAAiB,EAAE,MAAM,EACzB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,WAAW,GACvB,KAAK,EAAE,CA0DT"}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getAnchorPoints = getAnchorPoints;
7
+ var _geometry = require("../geometry");
8
+ /**
9
+ * Get accessible anchor points using binary search optimization
10
+ *
11
+ * @param anchor - The anchor point (on node edge)
12
+ * @param position - The position/direction (right, left, top, bottom)
13
+ * @param extensionDistance - The preferred extension distance
14
+ * @param step - The step size for binary search
15
+ * @param obstacleMap - The obstacle map for accessibility checking
16
+ * @returns Array of accessible points, prioritized by distance
17
+ */
18
+ function getAnchorPoints(anchor, position, extensionDistance, step, obstacleMap) {
19
+ const points = [];
20
+
21
+ // Determine direction vector based on position
22
+ const directionMap = {
23
+ 'right': {
24
+ dx: 1,
25
+ dy: 0
26
+ },
27
+ 'left': {
28
+ dx: -1,
29
+ dy: 0
30
+ },
31
+ 'top': {
32
+ dx: 0,
33
+ dy: -1
34
+ },
35
+ 'bottom': {
36
+ dx: 0,
37
+ dy: 1
38
+ }
39
+ };
40
+ const dir = directionMap[position];
41
+ if (!dir) {
42
+ console.warn(`[getAnchorPoints] Invalid position: ${position}`);
43
+ return [anchor];
44
+ }
45
+ console.log(`[getAnchorPoints] Finding points for position '${position}' from (${anchor.x}, ${anchor.y})`);
46
+
47
+ // 1. First try extensionDistance
48
+ const extensionPoint = new _geometry.Point(anchor.x + dir.dx * extensionDistance, anchor.y + dir.dy * extensionDistance);
49
+ if (obstacleMap.isAccessible(extensionPoint)) {
50
+ console.log(`[getAnchorPoints] Extension point (${extensionPoint.x}, ${extensionPoint.y}) is accessible`);
51
+ points.push(extensionPoint);
52
+ return points;
53
+ }
54
+ console.log(`[getAnchorPoints] Extension point (${extensionPoint.x}, ${extensionPoint.y}) is blocked, trying binary search`);
55
+
56
+ // 2. If extensionDistance point is blocked, use binary search with step
57
+ // Try: step -> step/2 -> step/4 -> ... -> 1px
58
+ let distance = step;
59
+ while (distance >= 1) {
60
+ const testPoint = new _geometry.Point(anchor.x + dir.dx * distance, anchor.y + dir.dy * distance);
61
+ if (obstacleMap.isAccessible(testPoint)) {
62
+ console.log(`[getAnchorPoints] Found accessible point at distance ${distance}px: (${testPoint.x}, ${testPoint.y})`);
63
+ points.push(testPoint);
64
+ return points;
65
+ }
66
+
67
+ // Halve the distance for next iteration
68
+ distance = Math.floor(distance / 2);
69
+ }
70
+
71
+ // 3. If still no accessible point found, return the anchor itself
72
+ console.warn(`[getAnchorPoints] No accessible point found, using anchor itself: (${anchor.x}, ${anchor.y})`);
73
+ points.push(anchor);
74
+ return points;
75
+ }
@@ -4,4 +4,5 @@ export * from './rect';
4
4
  export * from './route';
5
5
  export * from './node';
6
6
  export * from './pathValidation';
7
+ export * from './getAnchorPoints';
7
8
  //# 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;AACtB,cAAc,kBAAkB,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;AAChC,cAAc,mBAAmB,CAAA"}
@@ -68,4 +68,15 @@ Object.keys(_pathValidation).forEach(function (key) {
68
68
  return _pathValidation[key];
69
69
  }
70
70
  });
71
+ });
72
+ var _getAnchorPoints = require("./getAnchorPoints");
73
+ Object.keys(_getAnchorPoints).forEach(function (key) {
74
+ if (key === "default" || key === "__esModule") return;
75
+ if (key in exports && exports[key] === _getAnchorPoints[key]) return;
76
+ Object.defineProperty(exports, key, {
77
+ enumerable: true,
78
+ get: function () {
79
+ return _getAnchorPoints[key];
80
+ }
81
+ });
71
82
  });
@@ -25,7 +25,7 @@ export declare class Rectangle {
25
25
  */
26
26
  getCorner(): Point;
27
27
  /**
28
- * Check if a point is contained within this rectangle
28
+ * Check if a point is contained within this rectangle (interior only, excluding edges)
29
29
  */
30
30
  containsPoint(point: Point): boolean;
31
31
  /**
@@ -60,12 +60,12 @@ export var Rectangle = /*#__PURE__*/function () {
60
60
  }
61
61
 
62
62
  /**
63
- * Check if a point is contained within this rectangle
63
+ * Check if a point is contained within this rectangle (interior only, excluding edges)
64
64
  */
65
65
  }, {
66
66
  key: "containsPoint",
67
67
  value: function containsPoint(point) {
68
- return point.x >= this.x && point.x <= this.x + this.width && point.y >= this.y && point.y <= this.y + this.height;
68
+ return point.x > this.x && point.x < this.x + this.width && point.y > this.y && point.y < this.y + this.height;
69
69
  }
70
70
 
71
71
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"getManHattanPath.d.ts","sourceRoot":"","sources":["../src/getManHattanPath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,QAAQ,EAAE,MAAM,eAAe,CAAA;AAG3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAMnE;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,YAAY,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAEhB,cAAc,EAAE,QAAQ,CAAC;IACzB,cAAc,EAAE,QAAQ,CAAC;IACzB;;OAEG;IACH,UAAU,EAAE,UAAU,CAAA;IAEtB;;OAEG;IACH,OAAO,CAAC,EAAE,sBAAsB,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAwRvE"}
1
+ {"version":3,"file":"getManHattanPath.d.ts","sourceRoot":"","sources":["../src/getManHattanPath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,QAAQ,EAAE,MAAM,eAAe,CAAA;AAG3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,UAAU,EAAa,MAAM,WAAW,CAAA;AAM9E;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,YAAY,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAEhB,cAAc,EAAE,QAAQ,CAAC;IACzB,cAAc,EAAE,QAAQ,CAAC;IACzB;;OAEG;IACH,UAAU,EAAE,UAAU,CAAA;IAEtB;;OAEG;IACH,OAAO,CAAC,EAAE,sBAAsB,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAgbvE"}