Skip to content

Instantly share code, notes, and snippets.

@gchan
Last active December 30, 2015 20:48
Show Gist options
  • Save gchan/7882865 to your computer and use it in GitHub Desktop.
Save gchan/7882865 to your computer and use it in GitHub Desktop.
Sierpinski Triangle
<!DOCTYPE html>
<meta charset="utf-8">
<style>
polygon {
fill: orange;
}
body {
font: 12px sans-serif;
}
</style>
<body>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.3.11/d3.min.js"></script>
<div id='controls'>
<button id='subtract'>-</button>
<button id='add'>+</button>
Level <strong id='level'>5</strong>
</div>
<script>
var margin = { top: 20, right: 20, bottom: 20, left: 20 },
width = 480 - margin.left - margin.right,
height = 430 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var triangle_height = width / 2 * Math.tan(Math.PI * 1 / 3);
var root_triangle = {
top: { x: width / 2, y: 0 },
left: { x: 0, y: triangle_height },
right: { x: width, y: triangle_height }
};
var data_cache = {
0: [ root_triangle ]
};
var level = 5;
function clone_obj(obj) {
return JSON.parse(JSON.stringify(obj));
}
function compute_triangle_points(levels) {
var data;
if (data_cache[levels]) {
return data_cache[levels];
}
data = clone_obj(compute_triangle_points(levels - 1));
data.forEach(function(tri) {
var height_adj = (tri.left.y - tri.top.y) / 2;
var width_adj = (tri.top.x - tri.left.x) / 2;
var left_vertex = {
x: tri.left.x + width_adj,
y: tri.left.y - height_adj
};
var right_vertex = {
x: tri.right.x - width_adj,
y: tri.right.y - height_adj
};
var bottom_vertex = {
x: tri.top.x,
y: tri.right.y
};
var left_tri = clone_obj(tri);
var right_tri = clone_obj(tri);
tri.left = clone_obj(left_vertex);
tri.right = clone_obj(right_vertex);
left_tri.top = clone_obj(left_vertex);
left_tri.right = clone_obj(bottom_vertex);
right_tri.top = clone_obj(right_vertex);
right_tri.left = clone_obj(bottom_vertex);
data.push(left_tri);
data.push(right_tri);
});
data_cache[levels] = data;
return data;
}
function vertex_to_string(vertex) {
return vertex.x + ", " + vertex.y;
}
function triangle_points(tri) {
return vertex_to_string(tri.left) + " " + vertex_to_string(tri.right) + " " + vertex_to_string(tri.top);
}
function render_sierpinski_triangle(levels) {
d3.select('#level').text(level);
svg.selectAll("*").remove();
svg.selectAll("polygon")
.data(compute_triangle_points(levels))
.enter().append("polygon")
.attr('points', triangle_points);
}
function increase_level() {
level = Math.min(level + 1, 8);
render_sierpinski_triangle(level);
}
function decrease_level() {
level = Math.max(level - 1, 0);
render_sierpinski_triangle(level);
}
d3.select('#subtract').on('click', decrease_level);
d3.select('#add').on('click', increase_level);
render_sierpinski_triangle(level);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment