UNPKG

@rxflow/manhattan

Version:

Manhattan routing algorithm for ReactFlow - generates orthogonal paths with obstacle avoidance

75 lines (69 loc) 2.56 kB
"use strict"; 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; }