UNPKG

@rxflow/manhattan

Version:

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

76 lines (69 loc) 1.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCost = getCost; exports.getKey = getKey; exports.normalizePoint = normalizePoint; exports.reconstructRoute = reconstructRoute; var _geometry = require("../geometry"); /** * Normalize a point to a unit direction vector */ function normalizePoint(point) { return new _geometry.Point(point.x === 0 ? 0 : Math.abs(point.x) / point.x, point.y === 0 ? 0 : Math.abs(point.y) / point.y); } /** * Get string key for a point */ function getKey(point) { return point.toString(); } /** * Calculate minimum Manhattan distance from a point to multiple anchors */ function getCost(from, anchors) { let min = Infinity; for (const anchor of anchors) { const dist = from.manhattanDistance(anchor); if (dist < min) { min = dist; } } return min; } /** * Reconstruct route by concatenating points with their parents * Removes redundant points in the same direction */ function reconstructRoute(parents, points, tailPoint, startPoint, endPoint) { const route = []; let prevDiff = normalizePoint(endPoint.diff(tailPoint)); // tailPoint is assumed to be aligned already let currentKey = getKey(tailPoint); let parent = parents.get(currentKey); let point; while (parent) { // point is assumed to be aligned already point = points.get(currentKey); if (point) { const diff = normalizePoint(point.diff(parent)); if (!diff.equals(prevDiff)) { route.unshift(point); prevDiff = diff; } } // parent is assumed to be aligned already currentKey = getKey(parent); parent = parents.get(currentKey); } // leadPoint is assumed to be aligned already const leadPoint = points.get(currentKey); if (leadPoint) { const fromDiff = normalizePoint(leadPoint.diff(startPoint)); if (!fromDiff.equals(prevDiff)) { route.unshift(leadPoint); } } return route; }