Skip to content

Instantly share code, notes, and snippets.

@g-k
Forked from mbostock/.block
Last active December 17, 2015 18:09
Show Gist options
  • Save g-k/5651059 to your computer and use it in GitHub Desktop.
Save g-k/5651059 to your computer and use it in GitHub Desktop.
Trifoil Knot
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<style>
path {
fill: none;
stroke: #000;
stroke-width: 3px;
}
circle {
fill: steelblue;
stroke: #fff;
stroke-width: 3px;
}
</style>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>
<script>
var range = function (start, end, step) {
var result = [];
for (var i = start; i < end; i += step) {
result.push(i);
}
return result;
}
var options = {
size: 500, // canvas width and height
interpolation: "basis-closed",
samples: 8, // points along parameterized function
showSamples: false
};
var draw = function () {
var sin = Math.sin;
var cos = Math.cos;
var pi = Math.PI;
var size = options.size;
var samples = options.samples;
var phis = range(0, pi * 2, (pi * 2) / samples);
var points = phis.map(function (phi) {
return [sin(phi) + 2*sin(2*phi), cos(phi) - 2*cos(2*phi)];
});
points = points.map(function (point) {
return point
.map(function (coord) { return coord * (size / 8) }) // scale
.map(function (coord) { return coord + (size / 2) }); // center
});
var line = d3.svg.line()
.interpolate(options.interpolation);
// out with the old
d3.select("body svg").remove();
var svg = d3.select("body")
.append("svg")
.datum(points)
.attr("width", size)
.attr("height", size);
svg.append("path")
.style("stroke", "#ddd")
.attr("d", line);
svg.append("path")
.attr("d", line)
.call(transition);
if (options.showSamples) {
svg.selectAll('.point')
.data(points)
.enter()
.append("circle")
.attr("r", 4)
.attr("transform", function(d) { return "translate(" + d + ")"; });
}
function transition(path) {
path.transition()
.duration(7500)
.attrTween("stroke-dasharray", tweenDash)
.each("end", function() { d3.select(this).call(transition); });
}
function tweenDash() {
var l = this.getTotalLength(),
i = d3.interpolateString("0," + l, l + "," + l);
return function(t) { return i(t); };
}
}
var gui = new dat.GUI();
gui.add(options, 'size', 0, 2000)
.step(10)
.onChange(draw);
gui.add(options, 'samples', 0, 16)
.step(1)
.onChange(draw);
var interpolatorNames = [
"linear",
"step-before",
"step-after",
"basis",
"basis-open",
"basis-closed",
"cardinal",
"cardinal-open",
"cardinal-closed",
"monotone"
]
gui.add(options, 'interpolation')
.options(interpolatorNames)
.onChange(draw);
gui.add(options, 'showSamples')
.onChange(draw);
draw();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment