Skip to content

Instantly share code, notes, and snippets.

@robinhouston
Last active October 27, 2019 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save robinhouston/9611db02e197e3bc98e3 to your computer and use it in GitHub Desktop.
Save robinhouston/9611db02e197e3bc98e3 to your computer and use it in GitHub Desktop.
A worm on a Hilbert curve
width: 512
height: 512
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Hilbert curve</title>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<style>
svg path { fill: none; }
#bg { stroke: #ccc; }
#worm { stroke: red; stroke-width: 2; }
</style>
</head>
<body>
<div></div>
<script>
var ITERATIONS = 7,
N = Math.pow(2, ITERATIONS + 2);
var INITIAL_WORM_LENGTH = 100,
FINAL_WORM_LENGTH = 1021;
var svg = d3.select("div").append("svg")
.attr("width", N).attr("height", N);
var bg = svg.append("path").attr("id", "bg");
var worm = svg.append("path").attr("id", "worm");
var s = "L", i = 0, n = 1;
function next() {
s = s.replace(/([LR])/g, function(x) {
return ({L: "+RF-LFL-FR+", R: "-LF+RFR+FL-"})[x];
}).replace(/-\+|\+-|\+\+\+\+|----/g, "");
i++;
n *= 2;
}
function curve() {
var scale = N / n;
var r = "M" + (scale/2) + "," + (scale/2);
var b = [scale, 0];
for (var j=0; j<s.length; j++) {
switch(s.charAt(j)) {
case '+': b = [ -b[1], b[0] ]; break;
case '-': b = [ b[1], -b[0] ]; break;
case 'F':
r += "l" + b[0] + "," + b[1];
break;
}
}
return r;
}
for (var j = 0; i < ITERATIONS; j++) next();
var c = curve();
bg.attr("d", c);
worm.attr("d", c);
var length = worm.node().getTotalLength();
worm.attr("stroke-dasharray", "0 0 " + INITIAL_WORM_LENGTH + " " + (length - INITIAL_WORM_LENGTH));
worm.transition()
.duration(90 * 1000)
.ease("poly-in-out", 2)
.attr("stroke-dasharray", "0 " + (length - FINAL_WORM_LENGTH) + " " + FINAL_WORM_LENGTH + " 0");
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment