Skip to content

Commit

Permalink
Update lib/epsilon implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
egjiri committed Apr 2, 2017
1 parent 9e52b21 commit 77ef05b
Showing 1 changed file with 74 additions and 82 deletions.
156 changes: 74 additions & 82 deletions lib/epsilon.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,61 +17,63 @@ function Epsilon(eps){
eps = v;
return eps;
},
pointAboveOrOnLine: function(pt, left, right){
var Ax = left[0];
var Ay = left[1];
var Bx = right[0];
var By = right[1];
var Cx = pt[0];
var Cy = pt[1];
return (Bx - Ax) * (Cy - Ay) - (By - Ay) * (Cx - Ax) >= -eps;
round: function(v){
var factor = 1 / eps;
return Math.round(v * factor) / factor;
},
delta: function(v1, v2){
return my.round(v2 - v1);
},
equal: function(v1, v2){
return my.delta(v1, v2) === 0;
},
deltaX: function(p1, p2){
return my.delta(p1[0], p2[0]);
},
deltaY: function(p1, p2){
return my.delta(p1[1], p2[1]);
},
slope: function(p1, p2){
// return my.deltaY(p1, p2) / my.deltaX(p1, p2);
return my.round(my.deltaY(p1, p2) / my.deltaX(p1, p2));
},
slopesDelta: function(a0, a1, b0, b1){
return my.delta(my.slope(a0, a1), my.slope(b0, b1));
},
slopesEqual: function(a0, a1, b0, b1){
return my.slopesDelta(a0, a1, b0, b1) === 0;
},
pointAboveOrOnLine: function(p, left, right){
return my.slope(left, right) <= my.slope(left, p);
},
pointBetween: function(p, left, right){
// p must be collinear with left->right
// returns false if p == left, p == right, or left == right
var d_py_ly = p[1] - left[1];
var d_rx_lx = right[0] - left[0];
var d_px_lx = p[0] - left[0];
var d_ry_ly = right[1] - left[1];

var dot = d_px_lx * d_rx_lx + d_py_ly * d_ry_ly;
// if `dot` is 0, then `p` == `left` or `left` == `right` (reject)
// if `dot` is less than 0, then `p` is to the left of `left` (reject)
if (dot < eps)
return false;

var sqlen = d_rx_lx * d_rx_lx + d_ry_ly * d_ry_ly;
// if `dot` > `sqlen`, then `p` is to the right of `right` (reject)
// therefore, if `dot - sqlen` is greater than 0, then `p` is to the right of `right` (reject)
if (dot - sqlen > -eps)
return false;

return true;
return my.slopesEqual(left, right, left, p) &&
!(my.pointsSame(left, right)) &&
(my.deltaX(left, p) > 0 && my.deltaY(left, p) > 0) &&
(my.deltaX(right, p) < 0 && my.deltaY(right, p) < 0);
},
pointsSameX: function(p1, p2){
return Math.abs(p1[0] - p2[0]) < eps;
return my.deltaX(p1, p2) === 0;
},
pointsSameY: function(p1, p2){
return Math.abs(p1[1] - p2[1]) < eps;
return my.deltaY(p1, p2) === 0;
},
pointsSame: function(p1, p2){
return my.pointsSameX(p1, p2) && my.pointsSameY(p1, p2);
},
pointsCompare: function(p1, p2){
// returns -1 if p1 is smaller, 1 if p2 is smaller, 0 if equal
if (my.pointsSameX(p1, p2))
return my.pointsSameY(p1, p2) ? 0 : (p1[1] < p2[1] ? -1 : 1);
return p1[0] < p2[0] ? -1 : 1;
},
pointsCollinear: function(pt1, pt2, pt3){
// does pt1->pt2->pt3 make a straight line?
// essentially this is just checking to see if the slope(pt1->pt2) === slope(pt2->pt3)
// if slopes are equal, then they must be collinear, because they share pt2
var dx1 = pt1[0] - pt2[0];
var dy1 = pt1[1] - pt2[1];
var dx2 = pt2[0] - pt3[0];
var dy2 = pt2[1] - pt3[1];
return Math.abs(dx1 * dy2 - dx2 * dy1) < eps;
return my.pointsSameY(p1, p2) ? 0 : (my.deltaY(p1, p2) > 0 ? -1 : 1);
return my.deltaX(p1, p2) > 0 ? -1 : 1;
},
pointsCollinear: function(p1, p2, p3){
// does p1->p2->p3 make a straight line?
// essentially this is just checking to see if the slope(p1->p2) === slope(p2->p3)
// if slopes are equal, then they must be collinear, because they share p2
return my.pointsSame(p1, p2) || my.pointsSame(p2, p3) || my.pointsSame(p1, p3) || my.slopesEqual(p1, p2, p2, p3);
},
linesIntersect: function(a0, a1, b0, b1){
// returns false if the lines are coincident (e.g., parallel or on top of each other)
Expand All @@ -92,55 +94,45 @@ function Epsilon(eps){
// 0 intersection point is between segment's first and second points (exclusive)
// 1 intersection point is directly on segment's second point
// 2 intersection point is after segment's second point
var adx = a1[0] - a0[0];
var ady = a1[1] - a0[1];
var bdx = b1[0] - b0[0];
var bdy = b1[1] - b0[1];

var axb = adx * bdy - ady * bdx;
if (Math.abs(axb) < eps)
if (my.slopesEqual(a0, a1, b0, b1))
return false; // lines are coincident

var dx = a0[0] - b0[0];
var dy = a0[1] - b0[1];

var A = (bdx * dy - bdy * dx) / axb;
var B = (adx * dy - ady * dx) / axb;

var ret = {
alongA: 0,
alongB: 0,
pt: [
a0[0] + A * adx,
a0[1] + A * ady
]
var pt = my.intersectionPoint(a0, a1, b0, b1)
return {
alongA: my.intersectionAlong(pt[0], a0[0], a1[0]),
alongB: my.intersectionAlong(pt[0], b0[0], b1[0]),
pt: pt
};
},
intersectionPoint: function(a0, a1, b0, b1) {
var adx = my.deltaX(a0, a1);
var ady = my.deltaY(a0, a1);
var bdx = my.deltaX(b0, b1);
var bdy = my.deltaY(b0, b1);

// categorize where intersection point is along A and B
var axb = adx * bdy - ady * bdx;

if (A <= -eps)
ret.alongA = -2;
else if (A < eps)
ret.alongA = -1;
else if (A - 1 <= -eps)
ret.alongA = 0;
else if (A - 1 < eps)
ret.alongA = 1;
else
ret.alongA = 2;
var dx = my.deltaX(b0, a0);
var dy = my.deltaY(b0, a0);

if (B <= -eps)
ret.alongB = -2;
else if (B < eps)
ret.alongB = -1;
else if (B - 1 <= -eps)
ret.alongB = 0;
else if (B - 1 < eps)
ret.alongB = 1;
else
ret.alongB = 2;
var A = (bdx * dy - bdy * dx) / axb;

return ret;
return [
a0[0] + A * adx,
a0[1] + A * ady
];
},
intersectionAlong: function(pt, left, right) {
if (my.delta(pt, left) > 0)
return -2;
else if (my.equal(pt, left))
return -1;
else if (my.delta(pt, left) < 0 && my.delta(pt, right) > 0)
return 0;
else if (my.equal(pt, right))
return 1;
else
return 2;
}
};
return my;
Expand Down

0 comments on commit 77ef05b

Please sign in to comment.