Skip to content

Commit

Permalink
#7 bug fix in "doIntersect", (use geeksforgeeks code)
Browse files Browse the repository at this point in the history
  • Loading branch information
canbax committed Aug 28, 2021
1 parent a5c9164 commit 49ae6a7
Show file tree
Hide file tree
Showing 3 changed files with 1,011 additions and 166 deletions.
139 changes: 59 additions & 80 deletions cytoscape-layvo.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ return /******/ (function(modules) { // webpackBootstrap

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

module.exports = function () {
var cy = this;
return {
Expand Down Expand Up @@ -115,93 +117,70 @@ var _generalProperties = function _generalProperties(cy) {
};
};

/** e1 and e2 are array of objects
* @param { {srcEndpoint: {x: number, y:number}, tgtEndpoint: {x: number, y:number} }[] } e1
* @param { {srcEndpoint: {x: number, y:number}, tgtEndpoint: {x: number, y:number} }[] } e2
*/
var doIntersect = function doIntersect(e1, e2) {
var l1 = findLineEquationFrom2Points(e1.srcEndpoint, e1.tgtEndpoint);
var l2 = findLineEquationFrom2Points(e2.srcEndpoint, e2.tgtEndpoint);
var intersectionPoint = findIntersectionPointsOf2Lines(l1, l2);
if (!intersectionPoint) {
return false;
}
if (intersectionPoint.isParallel) {
if (!intersectionPoint.canOverlap) {
return false;
} else {
return areLineSegmentsIntersect(e1, e2);
}
}
var xRange1 = [Math.min(e1.srcEndpoint.x, e1.tgtEndpoint.x), Math.max(e1.srcEndpoint.x, e1.tgtEndpoint.x)];
var xRange2 = [Math.min(e2.srcEndpoint.x, e2.tgtEndpoint.x), Math.max(e2.srcEndpoint.x, e2.tgtEndpoint.x)];
var yRange1 = [Math.min(e1.srcEndpoint.y, e1.tgtEndpoint.y), Math.max(e1.srcEndpoint.y, e1.tgtEndpoint.y)];
var yRange2 = [Math.min(e2.srcEndpoint.y, e2.tgtEndpoint.y), Math.max(e2.srcEndpoint.y, e2.tgtEndpoint.y)];
var x = intersectionPoint.x,
y = intersectionPoint.y;

var Point = function Point(p) {
_classCallCheck(this, Point);

return x >= xRange1[0] && x >= xRange2[0] && x <= xRange1[1] && x <= xRange2[1] && y >= yRange1[0] && y >= yRange2[0] && y <= yRange1[1] && y <= yRange2[1];
this.x = p.x;
this.y = p.y;
};

// to check if to line segments that are from THE SAME equation (y = mx + n) intersects
var areLineSegmentsIntersect = function areLineSegmentsIntersect(e1, e2) {
var x1min = Math.min(e1.srcEndpoint.x, e1.tgtEndpoint.x);
var x1max = Math.max(e1.srcEndpoint.x, e1.tgtEndpoint.x);
var x2min = Math.min(e2.srcEndpoint.x, e2.tgtEndpoint.x);
var x2max = Math.max(e2.srcEndpoint.x, e2.tgtEndpoint.x);
// Given three colinear points p, q, r, the function checks if
// point q lies on line segment 'pr'

return x1max >= x2min && x2max >= x1min;

var onSegment = function onSegment(p, q, r) {
if (q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y)) return true;
return false;
};

/** If line equation is like "y = mx + n", returns an object with type {m: number, n: number}
* on the other hand line equation can be like x=3. In those cases returns an object like {x: number}
* @param {} p1 {x: number, y: number}
* @param {} p2 {x: number, y: number}
*/
var findLineEquationFrom2Points = function findLineEquationFrom2Points(p1, p2) {
var deltaX = p2.x - p1.x;
var deltaY = p2.y - p1.y;
if (deltaY == 0 && deltaX == 0) {
return null;
}
if (deltaX == 0) {
return { x: p1.x };
}
if (deltaY == 0) {
return { m: 0, n: p1.y };
}
var m = deltaY / deltaX;
var n = (p1.y * p2.x - p1.x * p2.y) / deltaX;
return { m: m, n: n };
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are colinear
// 1 --> Clockwise
// 2 --> Counterclockwise
var orientation = function orientation(p, q, r) {
// See https://www.geeksforgeeks.org/orientation-3-ordered-points/
// for details of below formula.
var val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);

if (val == 0) return 0; // colinear

return val > 0 ? 1 : 2; // clock or counterclock wise
};

/** "y = mx + n" or "x=3" are a line equaltions. Returns xy coordinates of point type {x: number, y: number}
* @param {} l1 {m: number, n: number}
* @param {} l2 {m: number, n: number}
/** e1 and e2 are array of objects
* @param { {srcEndpoint: {x: number, y:number}, tgtEndpoint: {x: number, y:number} }[] } e1
* @param { {srcEndpoint: {x: number, y:number}, tgtEndpoint: {x: number, y:number} }[] } e2
*/
var findIntersectionPointsOf2Lines = function findIntersectionPointsOf2Lines(l1, l2) {
// if both a like lines like x=3
if (l1.x && l2.x) {
if (l1.x == l2.x) {
return { x: l1.x, y: 0 };
}
return null;
}
if (l1.x) {
return { x: l1.x, y: l2.m * l1.x + l2.n };
}
if (l2.x) {
return { x: l2.x, y: l1.m * l2.x + l1.n };
}
var deltaM = l2.m - l1.m;
// there is no intersection between 2 lines, they are parallel
if (deltaM == 0) {
return { isParallel: true, canOverlap: l2.n == l1.n };
}
var x = (l1.n - l2.n) / deltaM;
var y = (l1.n * l2.m - l1.m * l2.n) / deltaM;
return { x: x, y: y };
var doIntersect = function doIntersect(e1, e2) {
var p1 = new Point(e1.srcEndpoint);
var q1 = new Point(e1.tgtEndpoint);
var p2 = new Point(e2.srcEndpoint);
var q2 = new Point(e2.tgtEndpoint);
// Find the four orientations needed for general and
// special cases
var o1 = orientation(p1, q1, p2);
var o2 = orientation(p1, q1, q2);
var o3 = orientation(p2, q2, p1);
var o4 = orientation(p2, q2, q1);

// General case
if (o1 != o2 && o3 != o4) return true;

// Special Cases
// p1, q1 and p2 are colinear and p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1)) return true;

// p1, q1 and q2 are colinear and q2 lies on segment p1q1
if (o2 == 0 && onSegment(p1, q2, q1)) return true;

// p2, q2 and p1 are colinear and p1 lies on segment p2q2
if (o3 == 0 && onSegment(p2, p1, q2)) return true;

// p2, q2 and q1 are colinear and q1 lies on segment p2q2
if (o4 == 0 && onSegment(p2, q1, q2)) return true;

return false; // Doesn't fall in any of the above cases
};

var findNumberOfCrosses = function findNumberOfCrosses(cy) {
Expand Down Expand Up @@ -230,12 +209,12 @@ var getEdgesWithBendpoints = function getEdgesWithBendpoints(cy) {
var x = edges[i];
var sp = x.segmentPoints();
if (!sp) {
r.push({ srcEndpoint: x.sourceEndpoint(), tgtEndpoint: x.targetEndpoint() });
r.push({ srcEndpoint: x.sourceEndpoint(), tgtEndpoint: x.targetEndpoint(), id: x.id() });
} else {
sp.unshift(x.sourceEndpoint());
sp.push(x.targetEndpoint());
for (var _i = 0; _i < sp.length - 1; _i++) {
r.push({ srcEndpoint: sp[_i], tgtEndpoint: sp[_i + 1] });
r.push({ srcEndpoint: sp[_i], tgtEndpoint: sp[_i + 1], id: x.id() });
if (_i != sp.length - 2) {
var currIdx = r.length - 1;
var nextIdx = r.length;
Expand Down
Loading

0 comments on commit 49ae6a7

Please sign in to comment.