UNPKG

@rxflow/manhattan

Version:

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

116 lines (109 loc) 4.67 kB
import { Point } from "../geometry"; import { defaults, directionMap } from "./defaults"; /** * Normalize padding value to box format */ function normalizePadding(padding) { if (typeof padding === 'number') { return { top: padding, right: padding, bottom: padding, left: padding }; } return padding; } /** * Normalize angle to 0-360 range */ export function normalizeAngle(angle) { while (angle < 0) { angle += 360; } while (angle >= 360) { angle -= 360; } return angle; } /** * Resolve options by merging user options with defaults */ export function resolveOptions() { var _options$step, _options$maxLoopCount, _options$precision, _options$maxDirection, _options$startDirecti, _options$endDirection, _options$excludeNodes, _options$excludeShape, _options$excludeTermi, _options$borderRadius, _options$extensionDis, _options$penalties, _options$padding; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var step = (_options$step = options.step) !== null && _options$step !== void 0 ? _options$step : defaults.step; var maxLoopCount = (_options$maxLoopCount = options.maxLoopCount) !== null && _options$maxLoopCount !== void 0 ? _options$maxLoopCount : defaults.maxLoopCount; var precision = (_options$precision = options.precision) !== null && _options$precision !== void 0 ? _options$precision : defaults.precision; var maxDirectionChange = (_options$maxDirection = options.maxDirectionChange) !== null && _options$maxDirection !== void 0 ? _options$maxDirection : defaults.maxDirectionChange; var startDirections = (_options$startDirecti = options.startDirections) !== null && _options$startDirecti !== void 0 ? _options$startDirecti : defaults.startDirections; var endDirections = (_options$endDirection = options.endDirections) !== null && _options$endDirection !== void 0 ? _options$endDirection : defaults.endDirections; var excludeNodes = (_options$excludeNodes = options.excludeNodes) !== null && _options$excludeNodes !== void 0 ? _options$excludeNodes : defaults.excludeNodes; var excludeShapes = (_options$excludeShape = options.excludeShapes) !== null && _options$excludeShape !== void 0 ? _options$excludeShape : defaults.excludeShapes; var excludeTerminals = (_options$excludeTermi = options.excludeTerminals) !== null && _options$excludeTermi !== void 0 ? _options$excludeTermi : defaults.excludeTerminals; var borderRadius = (_options$borderRadius = options.borderRadius) !== null && _options$borderRadius !== void 0 ? _options$borderRadius : defaults.borderRadius; var extensionDistance = (_options$extensionDis = options.extensionDistance) !== null && _options$extensionDis !== void 0 ? _options$extensionDis : defaults.extensionDistance; var penalties = (_options$penalties = options.penalties) !== null && _options$penalties !== void 0 ? _options$penalties : defaults.penalties; var fallbackRoute = options.fallbackRoute; // Convert padding to paddingBox var padding = (_options$padding = options.padding) !== null && _options$padding !== void 0 ? _options$padding : defaults.padding; var sides = normalizePadding(padding); var paddingBox = { x: -sides.left, y: -sides.top, width: sides.left + sides.right, height: sides.top + sides.bottom }; // Calculate cost (same as step) var cost = step; // Calculate directions array with offsets and costs var directions = [{ cost: cost, offsetX: step, offsetY: 0, angle: 0 }, { cost: cost, offsetX: -step, offsetY: 0, angle: 0 }, { cost: cost, offsetX: 0, offsetY: step, angle: 0 }, { cost: cost, offsetX: 0, offsetY: -step, angle: 0 }]; // Calculate angle for each direction directions.forEach(function (direction) { var point1 = new Point(0, 0); var point2 = new Point(direction.offsetX, direction.offsetY); direction.angle = normalizeAngle(point1.theta(point2)); }); return { step: step, maxLoopCount: maxLoopCount, precision: precision, maxDirectionChange: maxDirectionChange, startDirections: startDirections, endDirections: endDirections, excludeNodes: excludeNodes, excludeShapes: excludeShapes, excludeTerminals: excludeTerminals, paddingBox: paddingBox, borderRadius: borderRadius, extensionDistance: extensionDistance, sourcePosition: options.sourcePosition, targetPosition: options.targetPosition, directionMap: directionMap, directions: directions, penalties: penalties, cost: cost, fallbackRoute: fallbackRoute, previousDirectionAngle: undefined }; }