Adam Pearce

Zoomable Sierpinski Triangle

After finishing up the petition project, I wanted to use what I learned about d3.js to create something a little more fun. After a few hours1 of work, I had this:

//triangle centered at (cx, cy) with circumradius r
function addTriangle(cx, cy, r){
    .on(mobile ? "click" : "mouseover", function(d){
      addTriangle(  cx,             cy - r/2,       r/2);     
      addTriangle(  cx - r*sin30/2, cy + r*cos30/2, r/2);     
      addTriangle(  cx + r*sin30/2, cy + r*cos30/2, r/2);'mouseover', function(){});'click', function(){
        addTriangle(cx, cy, r);});
    .attr('fill', 'white')
    .attr('points', (cx)  +','+   (cy)  +' '+ 
                    (cx)  +','+   (cy)  +' '+
                    (cx)  +','+   (cy))
      .attr('fill', randomColor())
      .attr('points', (cx)  +','+   (cy-r)          +' '+ 
              (cx-r*sin30)  +','+   (cy + r*cos30)  +' '+
              (cx+r*sin30)  +','+   (cy + r*cos30))

which is currently live at the above link. There are a lot of things I'd like to add – proper mobile support, more fractal patterns, deeper zooming, and more interesting coloring – but I've just been clicking and scrolling around the triangles instead. It's incredible to me that such a small snipping of code could create something so visually engaging. Even though the internet already has dozens of Sierpinski Triangles, I haven't found any as interactive and eloquent as this one (which is because of d3.js, not anything I've done) so I feel ok posting it.

  1. The most frustrating part of making this: tricking myself into think that I had forgotten everything about geometry. From about 2 AM to 3.30 AM, I was trying to find the vertices of an equilateral triangle given the circumradius and center. This is pretty easy to do with trigonometry (see lines 21-23) , but I kept getting lopsided triangles no matter how I calculated the vertices. I even ended up pulling a geometry textbook off the shelf to check that I was doing the math correctly. Eventually (and I can't remember what lead me to this realization or why it didn't come earlier) it dawned on me that Math.sin(x) thought x was in radians and I was entering degrees.