Skip to content

Instantly share code, notes, and snippets.

@ttran17
Last active January 14, 2020 18:52
Show Gist options
  • Save ttran17/e42968619f79c1b8d1a81ba2feacdc76 to your computer and use it in GitHub Desktop.
Save ttran17/e42968619f79c1b8d1a81ba2feacdc76 to your computer and use it in GitHub Desktop.
Generator for Voronoi cell neighbors for d3-delaunay
// Modification of delaunay.neighbors to find Voronoi cell neighbors
// This generator should be attached to delaunay.voronoi
*neighbors(i) {
const {delaunay: {inedges, hull, _hullIndex, halfedges, triangles, collinear = undefined}} = this;
// degenerate case with several collinear points
if (collinear) {
const l = collinear.indexOf(i);
if (l > 0) yield collinear[l - 1];
if (l < collinear.length - 1) yield collinear[l + 1];
return;
}
const potentialNeighbors = [];
const e0 = inedges[i];
if (e0 === -1) return; // coincident point
let e = e0, p0 = -1;
let internal = hull[_hullIndex[i]] === -1;
do {
p0 = triangles[e]; // yield p0 = triangles[e];
potentialNeighbors.push(p0);
internal = internal && hull[_hullIndex[p0]] === -1;
e = e % 3 === 2 ? e - 2 : e + 1;
if (triangles[e] !== i) break; // bad triangulation
e = halfedges[e];
if (e === -1) {
internal = false;
const p = hull[(_hullIndex[i] + 1) % hull.length];
if (p !== p0) potentialNeighbors.push(p); // yield p;
break;
}
} while (e !== e0);
// if all points were internal (not on the convex hull) then
// no further processing is necessary
if (internal) {
for (let p of potentialNeighbors) yield p;
return;
}
// a point is a neighbor if its cell polygon has at least two points
// in common with the selected cell polygon
const home = this.cellPolygon(i);
const K = home.length - 1;
for (let p of potentialNeighbors) {
const neighbor = this.cellPolygon(p);
const L = neighbor.length - 1;
let common = 0;
for (let k = 0; k < K; k++) {
const a = home[k];
for (let l = 0; l < L; l++) {
const b = neighbor[l];
if (a[0] === b[0] && a[1] === b[1]) { // Not sure why I previously also checked a[1] === b[0] etc.
common++;
break;
}
}
if (common > 1) break;
}
if (common > 1) yield p;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment