sprotty
Version:
A next-gen framework for graphical views
126 lines • 6.35 kB
JavaScript
;
/********************************************************************************
* Copyright (c) 2021-2022 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IntersectionFinder = exports.BY_DESCENDING_X_THEN_DESCENDING_Y = exports.BY_X_THEN_DESCENDING_Y = exports.BY_DESCENDING_X_THEN_Y = exports.BY_X_THEN_Y = exports.isIntersectingRoutedPoint = void 0;
const inversify_1 = require("inversify");
const tinyqueue_1 = __importDefault(require("tinyqueue"));
const sweepline_1 = require("./sweepline");
function isIntersectingRoutedPoint(routedPoint) {
return routedPoint !== undefined && 'intersections' in routedPoint && 'kind' in routedPoint;
}
exports.isIntersectingRoutedPoint = isIntersectingRoutedPoint;
const BY_X_THEN_Y = (a, b) => {
if (a.intersectionPoint.x === b.intersectionPoint.x) {
return a.intersectionPoint.y - b.intersectionPoint.y;
}
return a.intersectionPoint.x - b.intersectionPoint.x;
};
exports.BY_X_THEN_Y = BY_X_THEN_Y;
const BY_DESCENDING_X_THEN_Y = (a, b) => {
if (a.intersectionPoint.x === b.intersectionPoint.x) {
return a.intersectionPoint.y - b.intersectionPoint.y;
}
return b.intersectionPoint.x - a.intersectionPoint.x;
};
exports.BY_DESCENDING_X_THEN_Y = BY_DESCENDING_X_THEN_Y;
const BY_X_THEN_DESCENDING_Y = (a, b) => {
if (a.intersectionPoint.x === b.intersectionPoint.x) {
return b.intersectionPoint.y - a.intersectionPoint.y;
}
return a.intersectionPoint.x - b.intersectionPoint.x;
};
exports.BY_X_THEN_DESCENDING_Y = BY_X_THEN_DESCENDING_Y;
const BY_DESCENDING_X_THEN_DESCENDING_Y = (a, b) => {
if (a.intersectionPoint.x === b.intersectionPoint.x) {
return b.intersectionPoint.y - a.intersectionPoint.y;
}
return b.intersectionPoint.x - a.intersectionPoint.x;
};
exports.BY_DESCENDING_X_THEN_DESCENDING_Y = BY_DESCENDING_X_THEN_DESCENDING_Y;
/**
* Finds intersections among edges and updates routed points to reflect those intersections.
*
* This only yields correct intersections among straight line segments and doesn't work with bezier curves.
*/
let IntersectionFinder = class IntersectionFinder {
/**
* Finds all intersections in the specified `routing` and replaces the `RoutedPoints` that are
* intersecting by adding intersection information to routing points (@see `IntersectingRoutedPoints`).
* @param routing the edge routing to find intersections for and update.
*/
apply(routing) {
const intersections = this.find(routing);
this.addToRouting(intersections, routing);
}
/**
* Finds the intersections in the specified `routing` and returns them.
* @param routing the edge routing to find intersections for and update.
* @returns the identified intersections.
*/
find(routing) {
const eventQueue = new tinyqueue_1.default(undefined, sweepline_1.checkWhichEventIsLeft);
routing.routes.forEach((route, routeId) => {
if (this.isSupportedRoute(route)) {
(0, sweepline_1.addRoute)(routeId, route, eventQueue);
}
});
return (0, sweepline_1.runSweep)(eventQueue);
}
/**
* Specifies whether or not a specific route should be included in this intersection search or not.
*
* As this intersection finder only supports linear line segments, this method only returns `true`
* for routes that only contain routed points, which are either 'source', 'target' or 'linear'.
*/
isSupportedRoute(route) {
return route.find(point => point.kind !== 'source' && point.kind !== 'target' && point.kind !== 'linear') === undefined;
}
addToRouting(intersections, routing) {
for (const intersection of intersections) {
const routable1 = routing.get(intersection.routable1);
const routable2 = routing.get(intersection.routable2);
this.addIntersectionToRoutedPoint(intersection, routable1, intersection.segmentIndex1);
this.addIntersectionToRoutedPoint(intersection, routable2, intersection.segmentIndex2);
}
}
addIntersectionToRoutedPoint(intersection, routedPoint, segmentIndex) {
if (routedPoint && routedPoint.length > segmentIndex) {
const segment = routedPoint[segmentIndex + 1];
if (isIntersectingRoutedPoint(segment)) {
segment.intersections.push(intersection);
}
else {
const intersectingRoutedPoint = Object.assign(Object.assign({}, segment), { intersections: [intersection] });
routedPoint[segmentIndex + 1] = intersectingRoutedPoint;
}
}
}
};
exports.IntersectionFinder = IntersectionFinder;
exports.IntersectionFinder = IntersectionFinder = __decorate([
(0, inversify_1.injectable)()
], IntersectionFinder);
//# sourceMappingURL=intersection-finder.js.map