Published
Edited
Aug 26, 2018
2 forks
Importers
17 stars
Insert cell
Insert cell
Insert cell
Insert cell
// list the triangles that belong to the alpha shape
alphashape = {
const filter = alphashapefilter(delaunay, alpha);
return new Uint8Array(delaunay.triangles.length / 3).map((_, i) => filter(i));
}
Insert cell
// compute the boundary of that list
alphahull = boundary(delaunay, alphashape)
Insert cell
// based on https://bl.ocks.org/jasondavies/1554783
function boundary(delaunay, members) {
const counts = {},
edges = {},
result = [];
let r;

// Traverse the edges of all member triangles and discard any edges that appear twice.
members.forEach((member, d) => {
if (!member) return;
for (let i = 0; i < 3; i++) {
var e = [
delaunay.triangles[3 * d + i],
delaunay.triangles[3 * d + ((i + 1) % 3)]
].sort();
(edges[e[0]] = edges[e[0]] || []).push(e[1]);
(edges[e[1]] = edges[e[1]] || []).push(e[0]);
const k = e.join(":");
if (counts[k]) delete counts[k];
else counts[k] = 1;
}
});

while (1) {
let k = null;
// Pick an arbitrary starting point on a boundary.
for (k in counts) break;
if (k == null) break;
result.push((r = k.split(":").map(Number)));
delete counts[k];
let q = r[1];
while (q != r[0]) {
let p = q,
qs = edges[p],
n = qs.length;
for (let i = 0; i < n; i++) {
q = qs[i];
let edge = [p, q].sort().join(":");
if (counts[edge]) {
delete counts[edge];
r.push(q);
break;
}
}
}
}
return result;
}
Insert cell
// based on https://bl.ocks.org/gka/1552725
function alphashapefilter(delaunay, alpha) {
const asq = alpha ** 2;
function dist2(p, q) {
return (
(delaunay.points[2 * p] - delaunay.points[2 * q]) ** 2 +
(delaunay.points[2 * p + 1] - delaunay.points[2 * q + 1]) ** 2
);
}
return function(i) {
let t0 = delaunay.triangles[i * 3 + 0],
t1 = delaunay.triangles[i * 3 + 1],
t2 = delaunay.triangles[i * 3 + 2];
return dist2(t0, t1) < asq && dist2(t1, t2) < asq && dist2(t2, t0) < asq;
};
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more