@rxflow/manhattan
Version:
Manhattan routing algorithm for ReactFlow - generates orthogonal paths with obstacle avoidance
120 lines (113 loc) • 3.23 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.normalizeAngle = normalizeAngle;
exports.resolveOptions = resolveOptions;
var _geometry = require("../geometry");
var _defaults = require("./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
*/
function normalizeAngle(angle) {
while (angle < 0) {
angle += 360;
}
while (angle >= 360) {
angle -= 360;
}
return angle;
}
/**
* Resolve options by merging user options with defaults
*/
function resolveOptions(options = {}) {
const step = options.step ?? _defaults.defaults.step;
const maxLoopCount = options.maxLoopCount ?? _defaults.defaults.maxLoopCount;
const precision = options.precision ?? _defaults.defaults.precision;
const maxDirectionChange = options.maxDirectionChange ?? _defaults.defaults.maxDirectionChange;
const startDirections = options.startDirections ?? _defaults.defaults.startDirections;
const endDirections = options.endDirections ?? _defaults.defaults.endDirections;
const excludeNodes = options.excludeNodes ?? _defaults.defaults.excludeNodes;
const excludeShapes = options.excludeShapes ?? _defaults.defaults.excludeShapes;
const excludeTerminals = options.excludeTerminals ?? _defaults.defaults.excludeTerminals;
const borderRadius = options.borderRadius ?? _defaults.defaults.borderRadius;
const extensionDistance = options.extensionDistance ?? _defaults.defaults.extensionDistance;
const penalties = options.penalties ?? _defaults.defaults.penalties;
const fallbackRoute = options.fallbackRoute;
// Convert padding to paddingBox
const padding = options.padding ?? _defaults.defaults.padding;
const sides = normalizePadding(padding);
const paddingBox = {
x: -sides.left,
y: -sides.top,
width: sides.left + sides.right,
height: sides.top + sides.bottom
};
// Calculate cost (same as step)
const cost = step;
// Calculate directions array with offsets and costs
const directions = [{
cost,
offsetX: step,
offsetY: 0,
angle: 0
}, {
cost,
offsetX: -step,
offsetY: 0,
angle: 0
}, {
cost,
offsetX: 0,
offsetY: step,
angle: 0
}, {
cost,
offsetX: 0,
offsetY: -step,
angle: 0
}];
// Calculate angle for each direction
directions.forEach(direction => {
const point1 = new _geometry.Point(0, 0);
const point2 = new _geometry.Point(direction.offsetX, direction.offsetY);
direction.angle = normalizeAngle(point1.theta(point2));
});
return {
step,
maxLoopCount,
precision,
maxDirectionChange,
startDirections,
endDirections,
excludeNodes,
excludeShapes,
excludeTerminals,
paddingBox,
borderRadius,
extensionDistance,
sourcePosition: options.sourcePosition,
targetPosition: options.targetPosition,
directionMap: _defaults.directionMap,
directions,
penalties,
cost,
fallbackRoute,
previousDirectionAngle: undefined
};
}