@rxflow/manhattan
Version:
Manhattan routing algorithm for ReactFlow - generates orthogonal paths with obstacle avoidance
75 lines (69 loc) • 2.56 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getAnchorPoints = getAnchorPoints;
var _geometry = require("../geometry");
/**
* Get accessible anchor points using binary search optimization
*
* @param anchor - The anchor point (on node edge)
* @param position - The position/direction (right, left, top, bottom)
* @param extensionDistance - The preferred extension distance
* @param step - The step size for binary search
* @param obstacleMap - The obstacle map for accessibility checking
* @returns Array of accessible points, prioritized by distance
*/
function getAnchorPoints(anchor, position, extensionDistance, step, obstacleMap) {
const points = [];
// Determine direction vector based on position
const directionMap = {
'right': {
dx: 1,
dy: 0
},
'left': {
dx: -1,
dy: 0
},
'top': {
dx: 0,
dy: -1
},
'bottom': {
dx: 0,
dy: 1
}
};
const dir = directionMap[position];
if (!dir) {
console.warn(`[getAnchorPoints] Invalid position: ${position}`);
return [anchor];
}
console.log(`[getAnchorPoints] Finding points for position '${position}' from (${anchor.x}, ${anchor.y})`);
// 1. First try extensionDistance
const extensionPoint = new _geometry.Point(anchor.x + dir.dx * extensionDistance, anchor.y + dir.dy * extensionDistance);
if (obstacleMap.isAccessible(extensionPoint)) {
console.log(`[getAnchorPoints] Extension point (${extensionPoint.x}, ${extensionPoint.y}) is accessible`);
points.push(extensionPoint);
return points;
}
console.log(`[getAnchorPoints] Extension point (${extensionPoint.x}, ${extensionPoint.y}) is blocked, trying binary search`);
// 2. If extensionDistance point is blocked, use binary search with step
// Try: step -> step/2 -> step/4 -> ... -> 1px
let distance = step;
while (distance >= 1) {
const testPoint = new _geometry.Point(anchor.x + dir.dx * distance, anchor.y + dir.dy * distance);
if (obstacleMap.isAccessible(testPoint)) {
console.log(`[getAnchorPoints] Found accessible point at distance ${distance}px: (${testPoint.x}, ${testPoint.y})`);
points.push(testPoint);
return points;
}
// Halve the distance for next iteration
distance = Math.floor(distance / 2);
}
// 3. If still no accessible point found, return the anchor itself
console.warn(`[getAnchorPoints] No accessible point found, using anchor itself: (${anchor.x}, ${anchor.y})`);
points.push(anchor);
return points;
}