Skip to content

Commit eab0143

Browse files
committed
more collinear tests (#92)
1 parent b7df1f2 commit eab0143

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

src/delaunay.js

+19-7
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,29 @@ function pointY(p) {
1616
function area(hull, points) {
1717
let n = hull.length, x0, y0,
1818
x1 = points[2 * hull[n - 1]],
19-
y1 = points[2 * hull[n - 1] + 1],
20-
area = 0;
19+
y1 = points[2 * hull[n - 1] + 1];
2120

21+
const v = [];
2222
for (let i = 0; i < n; i ++) {
2323
x0 = x1, y0 = y1;
24-
x1 = points[2 * hull[i]];
25-
y1 = points[2 * hull[i] + 1];
26-
area += y0 * x1 - x0 * y1;
24+
x1 = points[2 * hull[i]] - points[2 * hull[0]];
25+
y1 = points[2 * hull[i] + 1] - points[2 * hull[0] + 1];
26+
v.push(y0 * x1, - x0 * y1);
2727
}
2828

29-
return area / 2;
29+
return kahansum(v) / 2;
30+
}
31+
32+
function kahansum(values) {
33+
let summ = 0,
34+
c = 0;
35+
for (const num of values) {
36+
let y = num - c,
37+
t = summ + y;
38+
c = t - summ - y;
39+
summ = t;
40+
}
41+
return summ;
3042
}
3143

3244
function jitter(x, y, r) {
@@ -50,7 +62,7 @@ export default class Delaunay {
5062
const d = this._delaunator, points = this.points;
5163

5264
// check for collinear
53-
if (d.hull && d.hull.length > 2 && area(d.hull, points) < 1e-10) {
65+
if (d.hull && d.hull.length > 2 && (d.triangles.length === 0 || area(d.hull, points) < 1e-10)) {
5466
this.collinear = Int32Array.from({length: points.length/2}, (_,i) => i)
5567
.sort((i, j) => points[2 * i] - points[2 * j] || points[2 * i + 1] - points[2 * j + 1]); // for exact neighbors
5668
const e = this.collinear[0], f = this.collinear[this.collinear.length - 1],

test/delaunay-test.js

+12
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,18 @@ tape("delaunay.find(x, y) works with collinear points", test => {
135135
test.equal(points[delaunay.find(10, 10, 0)][1], 4);
136136
});
137137

138+
tape("delaunay.find(x, y) works with collinear points 2", test => {
139+
const points = Array.from({ length: 120 }, (_, i) => [i * 4, i / 3 + 100]);
140+
const delaunay = Delaunay.from(points);
141+
test.deepEqual([...delaunay.neighbors(2)], [ 1, 3 ]);
142+
});
143+
144+
tape("delaunay.find(x, y) works with collinear points 3", test => {
145+
const points = Array.from({ length: 120 }, (_, i) => [i * 4, i / 3 + 100]);
146+
const delaunay = Delaunay.from(points);
147+
test.deepEqual([...delaunay.neighbors(2)], [ 1, 3 ]);
148+
});
149+
138150
tape("delaunay.find(x, y) works with collinear points (large)", test => {
139151
const points = Array.from({length: 2000}, (_,i) => [i**2,i**2]);
140152
const delaunay = Delaunay.from(points);

0 commit comments

Comments
 (0)