From 83d07fa5475c5c7ea5c7cbbd58ad73f479bdc996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Thu, 2 Mar 2023 14:57:06 +0100 Subject: [PATCH 1/2] fix precision error on voronoi.neighbors closes #137 --- src/voronoi.js | 9 +++++---- test/voronoi-test.js | 13 +++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/voronoi.js b/src/voronoi.js index 97d388b..2adbb63 100644 --- a/src/voronoi.js +++ b/src/voronoi.js @@ -152,16 +152,17 @@ export default class Voronoi { return this.delaunay._step(i, x, y) === i; } *neighbors(i) { + const epsilon = 1e-12; const ci = this._clip(i); if (ci) for (const j of this.delaunay.neighbors(i)) { const cj = this._clip(j); // find the common edge if (cj) loop: for (let ai = 0, li = ci.length; ai < li; ai += 2) { for (let aj = 0, lj = cj.length; aj < lj; aj += 2) { - if (ci[ai] == cj[aj] - && ci[ai + 1] == cj[aj + 1] - && ci[(ai + 2) % li] == cj[(aj + lj - 2) % lj] - && ci[(ai + 3) % li] == cj[(aj + lj - 1) % lj] + if (Math.abs(ci[ai] - cj[aj]) < epsilon + && Math.abs(ci[ai + 1] - cj[aj + 1]) < epsilon + && Math.abs(ci[(ai + 2) % li] - cj[(aj + lj - 2) % lj]) < epsilon + && Math.abs(ci[(ai + 3) % li] - cj[(aj + lj - 1) % lj]) < epsilon ) { yield j; break loop; diff --git a/test/voronoi-test.js b/test/voronoi-test.js index c8eb4a8..9cc1cb1 100644 --- a/test/voronoi-test.js +++ b/test/voronoi-test.js @@ -53,12 +53,7 @@ it("zero-length edges are removed", () => { it("voronoi neighbors are clipped", () => { const voronoi = Delaunay.from([[300, 10], [200, 100], [300, 100], [10, 10], [350, 200], [350, 400]]).voronoi([0, 0, 500, 150]); - assert.deepStrictEqual([...voronoi.neighbors(0)].sort(), [1, 2]); - assert.deepStrictEqual([...voronoi.neighbors(1)].sort(), [0, 2]); - assert.deepStrictEqual([...voronoi.neighbors(2)].sort(), [0, 1, 4]); - assert.deepStrictEqual([...voronoi.neighbors(3)].sort(), []); - assert.deepStrictEqual([...voronoi.neighbors(4)].sort(), [2]); - assert.deepStrictEqual([...voronoi.neighbors(5)].sort(), []); + assert.deepStrictEqual([0, 1, 2, 3, 4, 5].map(i => [...voronoi.neighbors(i)].sort()), [ [1, 2], [0, 2, 3], [0, 1, 4], [1], [2], []]); }); it("unnecessary points on the corners are avoided (#88)", () => { @@ -87,3 +82,9 @@ it("cellPolygons filter out empty cells and have the cell index as a property", Object.assign([[0, 1], [1, 0], [2, 0], [2, 2], [0, 2], [0, 1]], { index: 2 }) ]); }); + +it("voronoi.neighbors returns the correct neighbors", () => { + const points = [[10, 10], [36, 27], [90, 19], [50, 75]]; + const voronoi = Delaunay.from(points).voronoi([0, 0, 100, 90]); + assert.deepStrictEqual([0, 1, 2, 3].map(i => [...voronoi.neighbors(i)].sort()), [[1], [0, 2, 3], [1, 3], [1, 2]]); +}); From bdb7bed4cd22bf43f147d27e93f0db5543a3c98a Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sat, 4 Mar 2023 11:12:34 -0500 Subject: [PATCH 2/2] prettier --- src/voronoi.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/voronoi.js b/src/voronoi.js index 2adbb63..5764eae 100644 --- a/src/voronoi.js +++ b/src/voronoi.js @@ -160,10 +160,9 @@ export default class Voronoi { if (cj) loop: for (let ai = 0, li = ci.length; ai < li; ai += 2) { for (let aj = 0, lj = cj.length; aj < lj; aj += 2) { if (Math.abs(ci[ai] - cj[aj]) < epsilon - && Math.abs(ci[ai + 1] - cj[aj + 1]) < epsilon - && Math.abs(ci[(ai + 2) % li] - cj[(aj + lj - 2) % lj]) < epsilon - && Math.abs(ci[(ai + 3) % li] - cj[(aj + lj - 1) % lj]) < epsilon - ) { + && Math.abs(ci[ai + 1] - cj[aj + 1]) < epsilon + && Math.abs(ci[(ai + 2) % li] - cj[(aj + lj - 2) % lj]) < epsilon + && Math.abs(ci[(ai + 3) % li] - cj[(aj + lj - 1) % lj]) < epsilon) { yield j; break loop; }