Skip to content

Instantly share code, notes, and snippets.

@saifuddin778
Last active April 17, 2016 08:01
Show Gist options
  • Save saifuddin778/12bb5eb5f68e54b01a3cdd5841f71d44 to your computer and use it in GitHub Desktop.
Save saifuddin778/12bb5eb5f68e54b01a3cdd5841f71d44 to your computer and use it in GitHub Desktop.
Sierpiński Gasket

The famous Sierpiński Gasket!

Idea (in simplest words) is to create equilateral triangles within a parent equilateral triangle, in such a manner that after each iteration, three more small triangles are made that perfectly fit in the parent triangle.

In this implementation, the max number of triangles you see is: 9840. This number is generalized based on the formula [(3^n)/2] - 1, which at each n, corresponds to a round of iterations which fill the entire parent triangle with equally sized child triangles (n is kept to 9 in this example).

<!DOCTYPE html>
<meta charset="utf-8">
<style>
div {
font-family: monospace;
font-size: 12px;
text-align: center;
}
p {
display: inline;
}
#triangle_big {
fill: none;
stroke: none;
}
.children {
fill: none;
}
</style>
<body>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<div>
<p>Pick n for <i>[(3^n)/2] - 1: </i></p>
<select id='n_'>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
<option value='5'>5</option>
<option value='6'>6</option>
<option value='7'>7</option>
<option value='8'>8</option>
<option value='9'>9</option>
</select>
</div>
<script>
function middle_point(p1, p2) {
return [(p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2];
}
function get_reverse_triangle(ps) {
var rps = [
middle_point(ps[0], ps[1]),
middle_point(ps[0], ps[2]),
middle_point(ps[2], ps[1])
];
return rps;
}
function process_(new_point, tpoints, i, j) {
if (j == 0) {
//inserting at 0th index, as j == 0
//and taking out the last element
new_point.unshift(tpoints[i][j]);
new_point.pop();
} else if (j == 1) {
//appending at the end
//and taking out the first element
new_point.push(tpoints[i][j + 1]);
new_point.shift();
} else if (j == 2) {
//adding to j-1 th index
new_point[j - 1] = tpoints[i][j - 1];
}
return new_point;
}
function sierpinski(n_){
var margin = {
top: 30,
right: 60,
bottom: 60,
left: 30
};
var width = 1024 - margin.left - margin.right;
var height = (550 - 10) - margin.top - margin.bottom;
var svg = d3.select("body")
.append("svg")
.attr("id", "gasket_svg")
.attr("width", width).attr("height", height);
var tpoints = [
[
[(width * 0.2), (height * 0.9)],
[(width * 0.5), (height * 0.1)],
[(width * 0.8), (height * 0.9)]
]
];
var triangle = svg
.append("polygon")
.attr("id", "triangle_big")
.attr("points", tpoints[0][0][0] + "," + tpoints[0][0][1] + ", " + tpoints[0][1][0] + "," + tpoints[0][1][1] + ", " + tpoints[0][2][0] + "," + tpoints[0][2][1]);
var max_limit = parseInt(Math.pow(3, n_) / 2) - 1;
//some fancy stuff
if (n_ > 5){
var colors_ = d3.scale.linear().interpolate(d3.interpolateHcl).domain([0, max_limit]).range(['cornflowerblue', 'crimson']);
var stroke_width = 0.3;
}
else{
var colors_ = d3.scale.linear().interpolate(d3.interpolateHsl).domain([0, max_limit]).range(['cornflowerblue', 'crimson']);
var stroke_width = 0.7;
}
for (var i = 0; i < tpoints.length; i++) {
var rtrng = get_reverse_triangle(tpoints[i]);
for (var j = 0; j < rtrng.length; j++) {
var new_point = rtrng.map(function(u) {
return u;
});
new_point = process_(new_point, tpoints, i, j);
tpoints.push(new_point);
}
if (i == max_limit) {
for (var p = 0; p < tpoints.length; p++) {
append_(tpoints[p], p);
}
break;
}
}
console.log(stroke_width);
function append_(rtrng, i_) {
var pts = rtrng[0][0] + "," + rtrng[0][1] + ", " + rtrng[1][0] + "," + rtrng[1][1] + ", " + rtrng[2][0] + "," + rtrng[2][1];
svg.append("polygon")
.attr("class", "children")
.attr("stroke", colors_(i_))
.attr("stroke-width", stroke_width)
.attr("points", pts);
return;
}
}
sierpinski(1);
//trigger the selection
$('#n_').change(function(){
var n_ = +this.value;
$('#gasket_svg').remove();
sierpinski(n_);
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment