gpml2pvjson
Version:
convert GPML (XML) to pvjson (json)
162 lines • 12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateOrientation = exports.getOrientationOfHyperedgeEndPoint = exports.getOrientationOfHyperedgeStartPoint = void 0;
var fp_1 = require("lodash/fp");
var geom_utils_1 = require("../geom-utils");
var Angle_1 = require("../spinoffs/Angle");
var edge_1 = require("./edge");
/**
* getOrientationOfHyperedgeStartPoint
*
* Get orientation of the start point of an edge that is attached to another
* edge.
*
* @param referencedEdge {PvjsonEdge}
* @param startPoint {Point}
* @param otherPoint {Point}
* @return {Orientation}
*/
function getOrientationOfHyperedgeStartPoint(referencedEdge, startPoint, endPoint) {
if (!referencedEdge) {
throw new Error("Missing referencedEdge when calculating orientation of point attached to other edge.");
}
var currentPath = new geom_utils_1.SmartPath([startPoint, endPoint]);
var angleOfCurrentVectorSum = currentPath.sum.angle;
var referencedPath = new geom_utils_1.SmartPath(referencedEdge.points, referencedEdge);
// This is the angle of the line tangent to the referenced edge at
// startPoint.
var angleOfReferencedEdgeAtPointOnEdge = referencedPath.position(startPoint.attachmentDisplay.position[0]).angle;
var firstSegmentCalculations = geom_utils_1.START_SEGMENT_DETAILS_MAPS.map(function (startSegmentDetailsMap) {
/*
* referenced edge
* /
* /
* /.
* / angle (rad)
* / .
* /--------------
* / ^ | --------------
* / | | | |
* | ------------| |
* | | |
* firstSegment --------------
* (of current edge)
*
*/
var orientation = startSegmentDetailsMap.orientation;
var orientationX = orientation[0], orientationY = orientation[1];
var firstSegmentEndPoint = {
x: startPoint.x + edge_1.DEFAULT_STUB_LENGTH * orientationX,
y: startPoint.y + edge_1.DEFAULT_STUB_LENGTH * orientationY
};
return {
firstSegmentEndPoint: firstSegmentEndPoint,
endPoint: endPoint,
emanationAngle: startSegmentDetailsMap.angle,
orientation: orientation
};
})
.map(function (_a) {
var firstSegmentEndPoint = _a.firstSegmentEndPoint, endPoint = _a.endPoint, emanationAngle = _a.emanationAngle, orientation = _a.orientation;
var isSameSide = geom_utils_1.sameSide(referencedEdge.points[0], fp_1.last(referencedEdge.points), firstSegmentEndPoint, endPoint);
var angleBetweenOrientationVectorAndCurrentEdge = Angle_1.distance(emanationAngle, angleOfCurrentVectorSum);
var angleBetweenOrientationVectorAndReferencedEdge = Angle_1.distance(angleOfReferencedEdgeAtPointOnEdge, emanationAngle);
return {
isSameSide: isSameSide,
angleBetweenOrientationVectorAndCurrentEdge: angleBetweenOrientationVectorAndCurrentEdge,
angleBetweenOrientationVectorAndVectorPerpendicularToReferencedEdge: Math.abs(angleBetweenOrientationVectorAndReferencedEdge - Math.PI / 2),
orientation: orientation
};
})
// Sorting by three criteria, with the most important first:
// 1. The second point and the end point of the current edge are on the
// same of the referenced edge.
// 2. The emanation angle is as close as possible to being perpendicular to
// the referenced edge.
// 3. The angle of the first segment matches the angle of the current edge.
.sort(function (a, b) {
if (a.isSameSide && !b.isSameSide) {
return -1;
}
else if (!a.isSameSide && b.isSameSide) {
return 1;
}
else {
if (a.angleBetweenOrientationVectorAndVectorPerpendicularToReferencedEdge <
b.angleBetweenOrientationVectorAndVectorPerpendicularToReferencedEdge) {
return -1;
}
else if (a.angleBetweenOrientationVectorAndVectorPerpendicularToReferencedEdge >
b.angleBetweenOrientationVectorAndVectorPerpendicularToReferencedEdge) {
return 1;
}
else {
if (a.angleBetweenOrientationVectorAndCurrentEdge <
b.angleBetweenOrientationVectorAndCurrentEdge) {
return -1;
}
else if (a.angleBetweenOrientationVectorAndCurrentEdge >
b.angleBetweenOrientationVectorAndCurrentEdge) {
return 1;
}
else {
return 0;
}
}
}
});
var formatted = fp_1.map(function (firstSegmentCalculation) {
var angleBetweenOrientationVectorAndVectorPerpendicularToReferencedEdge = firstSegmentCalculation.angleBetweenOrientationVectorAndVectorPerpendicularToReferencedEdge, angleBetweenOrientationVectorAndCurrentEdge = firstSegmentCalculation.angleBetweenOrientationVectorAndCurrentEdge, isSameSide = firstSegmentCalculation.isSameSide;
return {
angleBetweenOrientationVectorAndVectorPerpendicularToReferencedEdge: String(angleBetweenOrientationVectorAndVectorPerpendicularToReferencedEdge /
Math.PI) + " * PI",
angleBetweenOrientationVectorAndCurrentEdge: String(angleBetweenOrientationVectorAndCurrentEdge / Math.PI) + " * PI",
isSameSide: isSameSide
};
}, firstSegmentCalculations);
return firstSegmentCalculations[0].orientation;
}
exports.getOrientationOfHyperedgeStartPoint = getOrientationOfHyperedgeStartPoint;
// Uses the same sorting criteria as getOrientationOfHyperedgeStartPoint,
// except with the obvious changes in direction to account for being the
// endPoint instead of the startPoint.
exports.getOrientationOfHyperedgeEndPoint = fp_1.flow(getOrientationOfHyperedgeStartPoint, geom_utils_1.flipOrientation);
// Validate orientation of attachment display.
//
// When attached to a normal Node, we can calculate the orientation immediately
// so this will return true right away.
// When attached to an Edge or Group, we need to do more processing,
// so this will at least initially return false.
// TODO: Not sure whether the orientation of a point attached to an Edge or a
// Group is ever set.
function validateOrientation(orientation) {
return !!orientation && fp_1.isFinite(orientation[0]) && fp_1.isFinite(orientation[1]);
}
exports.validateOrientation = validateOrientation;
/*
// NOTE: PathVisio-Java appears to try to avoid making an edge
// terminate into another edge at an approach angle of anything
// less than about 30 deg.
if (endPoint.hasOwnProperty("isAttachedTo")) {
const referencedEndPath = new SmartPath(endEntity.points, endEntity);
const angleOfReferencedEdgeAtPointOnEdge = referencedEndPath.position(
startPoint.attachmentDisplay.position[0]
).angle;
if (
Math.abs(
START_SIDE_TO_EMANATION_ANGLE_MAPPINGS[endSide] -
angleOfReferencedEdgeAtPointOnEdge
) <
30 * (Math.PI / 180)
) {
// edge1 is almost parallel with edge2, making it hard to read, so we need to recalculate.
endPoint.orientation = getOrientationOfHyperedgeEndPoint(
endEntity,
endPoint,
startPoint
);
return getAndCompareSides(startPoint, endPoint, endEntity);
}
}
//*/
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JpZW50YXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZWRnZS9vcmllbnRhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxnQ0FBc0Q7QUFDdEQsNENBTXVCO0FBQ3ZCLDJDQUE2QztBQVE3QywrQkFBNkM7QUFFN0M7Ozs7Ozs7Ozs7R0FVRztBQUNILFNBQWdCLG1DQUFtQyxDQUNqRCxjQUEwQixFQUMxQixVQUF3QyxFQUN4QyxRQUFzQztJQUV0QyxJQUFJLENBQUMsY0FBYyxFQUFFO1FBQ25CLE1BQU0sSUFBSSxLQUFLLENBQ2Isc0ZBQXNGLENBQ3ZGLENBQUM7S0FDSDtJQUVELElBQU0sV0FBVyxHQUFHLElBQUksc0JBQVMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQzFELElBQU0sdUJBQXVCLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUM7SUFDdEQsSUFBTSxjQUFjLEdBQUcsSUFBSSxzQkFBUyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFFNUUsa0VBQWtFO0lBQ2xFLGNBQWM7SUFDZCxJQUFNLGtDQUFrQyxHQUFHLGNBQWMsQ0FBQyxRQUFRLENBQ2hFLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQ3pDLENBQUMsS0FBSyxDQUFDO0lBRVIsSUFBTSx3QkFBd0IsR0FBRyx1Q0FBMEIsQ0FBQyxHQUFHLENBQUMsVUFDOUQsc0JBQXNCO1FBRXRCOzs7Ozs7Ozs7Ozs7Ozs7V0FlRztRQUVLLElBQUEsV0FBVyxHQUFLLHNCQUFzQixZQUEzQixDQUE0QjtRQUN4QyxJQUFBLFlBQVksR0FBa0IsV0FBVyxHQUE3QixFQUFFLFlBQVksR0FBSSxXQUFXLEdBQWYsQ0FBZ0I7UUFDakQsSUFBTSxvQkFBb0IsR0FBaUI7WUFDekMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDLEdBQUcsMEJBQW1C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