delaunay
Version:
Delaunay triangulation in arbitrary dimensions
155 lines (129 loc) • 3.89 kB
HTML
<html>
<head>
<title>2D Delaunay Triangulation Example</title>
<meta charset="utf-8"/>
</head>
<body>
<canvas id="canvas" width="256" height="256">
</canvas>
<script type="text/javascript" src="../lib/matrix.js">
</script>
<script type="text/javascript" src="../lib/barycentric.js">
</script>
<script type="text/javascript" src="../lib/delaunay.js">
</script>
<script type="text/javascript">
function lookup(mesh, vertices, vertex, key) {
var simplex = new Array(3),
i, coords;
vertex = Delaunay.resolve(vertex, key);
for(i = mesh.length; i; ) {
simplex[2] = Delaunay.resolve(vertices[mesh[--i]], key);
simplex[1] = Delaunay.resolve(vertices[mesh[--i]], key);
simplex[0] = Delaunay.resolve(vertices[mesh[--i]], key);
coords = Barycentric.contains(simplex, vertex);
if(coords) {
coords.unshift(
vertices[mesh[i + 0]],
vertices[mesh[i + 1]],
vertices[mesh[i + 2]]
);
return coords;
}
}
return null;
}
function lerp(a, b, c, x, y) {
a = a["color"];
b = b["color"];
c = c["color"];
return Math.round(a + x * (b - a) + y * (c - a));
}
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
id = ctx.getImageData(0, 0, canvas.width, canvas.height),
vertices = new Array(8),
vertex = {"location": new Array(2)},
mesh, i, x, y, coords;
/* Randomly distribute vertices around the canvas. */
for(i = vertices.length; i--; )
vertices[i] = {
"location": [
Math.random() * (canvas.width - 8) + 4,
Math.random() * (canvas.height - 8) + 4
],
"color": Math.floor(Math.random() * 256)
}
/* Delaunay triangulate the vertices. */
mesh = Delaunay.triangulate(vertices, "location");
/* Look up each pixel in the mesh. */
i = id.data.length;
for(y = id.height; y--; ) {
vertex["location"][1] = y + 0.5;
for(x = id.width; x--; ) {
vertex["location"][0] = x + 0.5;
id.data[--i] = 255;
if(coords = lookup(mesh, vertices, vertex, "location")) {
id.data[--i] =
id.data[--i] =
id.data[--i] = lerp.apply(null, coords);
}
else if((x + y) & 16) {
id.data[--i] = 255;
id.data[--i] = 63;
id.data[--i] = 63;
}
else {
id.data[--i] = 191;
id.data[--i] = 47;
id.data[--i] = 47;
}
}
}
ctx.putImageData(id, 0, 0);
ctx.strokeStyle = "yellow";
for(i = mesh.length; i; ) {
ctx.beginPath();
--i;
ctx.moveTo(
vertices[mesh[i]]["location"][0],
vertices[mesh[i]]["location"][1]
);
--i;
ctx.lineTo(
vertices[mesh[i]]["location"][0],
vertices[mesh[i]]["location"][1]
);
--i;
ctx.lineTo(
vertices[mesh[i]]["location"][0],
vertices[mesh[i]]["location"][1]
);
ctx.closePath();
ctx.stroke();
}
for(i = vertices.length; i--; ) {
ctx.fillStyle =
"rgb(" +
vertices[i]["color"] +
"," +
vertices[i]["color"] +
"," +
vertices[i]["color"] +
")";
ctx.beginPath();
ctx.arc(
vertices[i]["location"][0],
vertices[i]["location"][1],
4,
0,
2 * Math.PI,
false
);
ctx.fill();
ctx.stroke();
}
</script>
</body>
</html>