gramoloss
Version:
Graph theory package for edition and computation
140 lines (139 loc) • 5.54 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Link = exports.ORIENTATION = void 0;
const utils_1 = require("./utils");
var ORIENTATION;
(function (ORIENTATION) {
ORIENTATION["UNDIRECTED"] = "UNDIRECTED";
ORIENTATION["DIRECTED"] = "DIRECTED";
})(ORIENTATION || (exports.ORIENTATION = ORIENTATION = {}));
class Link {
constructor(index, graph, startVertex, endVertex, orientation) {
this.index = index;
this.graph = graph;
this.startVertex = startVertex;
this.endVertex = endVertex;
this.orientation = orientation;
this.color = "Neutral";
this.weight = "";
}
delete() {
// TODO : pour les aretes multiples il faut enlever neighbor que s'il n'y a plus d'aretes
// TODO : attention aux loops
if (this.orientation == ORIENTATION.UNDIRECTED) {
this.graph.matrix[this.startVertex.stackedIndex][this.endVertex.stackedIndex] -= 1;
this.graph.matrix[this.endVertex.stackedIndex][this.startVertex.stackedIndex] -= 1;
this.startVertex.neighbors.delete(this.endVertex.index);
this.endVertex.neighbors.delete(this.startVertex.index);
}
else {
this.graph.matrix[this.startVertex.stackedIndex][this.endVertex.stackedIndex] -= 1;
this.startVertex.outNeighbors.delete(this.endVertex.index);
this.endVertex.inNeighbors.delete(this.startVertex.index);
}
this.startVertex.incidentLinks.delete(this.index);
this.endVertex.incidentLinks.delete(this.index);
this.graph.links.delete(this.index);
}
/**
* Create k-1 vertices
* Create k links with the same color
* Delete this link
* @param k
*/
subdivide(k) {
let previousVertex = this.startVertex;
for (let i = 0; i < k; i++) {
const bezierPoints = typeof this.cp == "undefined" ?
[this.startVertex.getPos(), this.endVertex.getPos()] :
[this.startVertex.getPos(), this.cp, this.endVertex.getPos()];
const vertexPos = (0, utils_1.bezierCurvePoint)(i / k, bezierPoints);
const v = this.graph.addVertex(this.graph.getAvailableVertexIndex(), vertexPos.x, vertexPos.y);
if (this.orientation == ORIENTATION.UNDIRECTED) {
this.graph.addEdge(previousVertex, v);
}
else {
this.graph.addArc(previousVertex, v);
}
previousVertex = v;
}
if (this.orientation == ORIENTATION.UNDIRECTED) {
this.graph.addEdge(previousVertex, this.endVertex);
}
else {
this.graph.addArc(previousVertex, this.endVertex);
}
this.delete();
}
/**
* Return true iff at least one extremity of the link is in the set `s`.
* @return `s.has(startIndex) || s.has(endIndex)`
*/
hasAnExtrimityIn(s) {
return s.has(this.startVertex.index) || s.has(this.endVertex.index);
}
signatureEquals(startIndex, endIndex, orientation) {
if (this.orientation == orientation) {
switch (this.orientation) {
case ORIENTATION.UNDIRECTED: {
if ((0, utils_1.eqSet)(new Set([this.startVertex.index, this.endVertex.index]), new Set([startIndex, endIndex]))) {
return true;
}
break;
}
case ORIENTATION.DIRECTED: {
if (this.startVertex.index == startIndex && this.endVertex.index == endIndex) {
return true;
}
break;
}
}
}
return false;
}
/**
* Test if this link intersect another link
// TODO: faster algorithm for intersection between segment and bezier
* TODO use in the planar test of a graph
*/
intersectsLink(link) {
const v1 = this.startVertex.getPos();
const w1 = this.endVertex.getPos();
const v2 = link.startVertex.getPos();
const w2 = link.endVertex.getPos();
if (typeof this.cp == "undefined" && typeof link.cp == "undefined") {
return typeof (0, utils_1.segmentsInteriorIntersection)(v1, w1, v2, w2) == "undefined";
// return is_segments_intersection(v1, w1, v2, w2);
}
let cp1 = v1.middle(w1);
let cp2 = v2.middle(w2);
if (typeof this.cp != "undefined") {
cp1 = this.cp;
}
if (typeof link.cp != "undefined") {
cp2 = link.cp;
}
return (0, utils_1.isQuadraticBezierCurvesIntersection)(v1, cp1, w1, v2, cp2, w2);
}
getWeight() {
return this.weight;
}
/**
* @param fixedEnd is the coord of the extremity which has not moved
* @param newPos and @param previousPos are the positions of the extremity which has moved
*/
transformCP(newPos, previousPos, fixedEnd) {
if (typeof this.cp == "undefined") {
return;
}
const w = fixedEnd;
const u = previousPos.sub(w);
const nv = newPos.sub(w);
const theta = nv.getTheta(u);
const rho = u.getRho(nv);
const cp = this.cp.copy();
this.cp.x = w.x + rho * (Math.cos(theta) * (cp.x - w.x) - Math.sin(theta) * (cp.y - w.y));
this.cp.y = w.y + rho * (Math.sin(theta) * (cp.x - w.x) + Math.cos(theta) * (cp.y - w.y));
}
}
exports.Link = Link;