@rxflow/manhattan
Version:
Manhattan routing algorithm for ReactFlow - generates orthogonal paths with obstacle avoidance
116 lines (109 loc) • 4.67 kB
JavaScript
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
};
}