Skip to content
This repository was archived by the owner on May 11, 2021. It is now read-only.

Commit 2b438b2

Browse files
author
peter mattingly
committed
Changing kline.equal() to strict collinearity check.
1 parent 95f3553 commit 2b438b2

File tree

2 files changed

+42
-15
lines changed

2 files changed

+42
-15
lines changed

test/kline.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,10 @@
3939
start();
4040
});
4141

42+
asyncTest('Two line segments that do not inersect and are not collinear, not equal', 1, function() {
43+
var result = line.equal([[3, 4], [5, 11]], [[5, 6], [9, 5]]);
44+
strictEqual(result, false);
45+
start();
46+
});
47+
4248
})();

utils/kline.js

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,44 @@ var kline = KhanUtil.kline = {
2424
];
2525
},
2626

27+
/**
28+
* Tests if two lines are collinear.
29+
* https://en.wikipedia.org/wiki/Collinearity
30+
*/
2731
equal: function(line1, line2, tolerance) {
28-
// TODO (jack): A nicer implementation might just check collinearity of
29-
// vectors using underscore magick
30-
// Compare the directions of the lines
31-
var v1 = kvector.subtract(line1[1],line1[0]);
32-
var v2 = kvector.subtract(line2[1],line2[0]);
33-
if (!kvector.collinear(v1, v2, tolerance)) {
34-
return false;
35-
}
36-
// If the start point is the same for the two lines, then they are the same
37-
if (kpoint.equal(line1[0], line2[0])) {
38-
return true;
32+
var DEFAULT_TOLERANCE = 1e-9;
33+
34+
if (!tolerance) {
35+
tolerance = DEFAULT_TOLERANCE;
3936
}
40-
// Make sure that the direction to get from line1 to
41-
// line2 is the same as the direction of the lines
42-
var line1ToLine2Vector = kvector.subtract(line2[0], line1[0]);
43-
return kvector.collinear(v1, line1ToLine2Vector, tolerance);
37+
38+
/**
39+
* line1's points are trivially collinear.
40+
* So check against each point in line2.
41+
* Form a triangle of the points (line1 and a single point from line2)
42+
* iff the area of the triangle is zero, are the points collinear
43+
* http://mathworld.wolfram.com/Collinear.html
44+
*/
45+
var x1 = line1[0][0];
46+
var y1 = line1[0][1];
47+
var x2 = line1[1][0];
48+
var y2 = line1[1][1];
49+
return _.every(line2, function(dim) {
50+
var x3 = dim[0];
51+
var y3 = dim[1];
52+
53+
//calculating area of triangle formed by the three points
54+
//https://en.wikipedia.org/wiki/Shoelace_formula#Examples
55+
//A = 1/2|x1*y2 + x2*y3 + x3*y1 - x2*y1 - x3*y2 - x1*y3|
56+
var area = (1/2)*Math.abs(x1*y2 + x2*y3 + x3*y1 -
57+
x2*y1 - x3*y2 - x1*y3);
58+
59+
if (area === 0 || area < tolerance) {
60+
return true;
61+
} else {
62+
return false;
63+
}
64+
});
4465
},
4566

4667
intersect: function(px, py, rx, ry, qx, qy, sx, sy) {

0 commit comments

Comments
 (0)