Sierpinski triangle
by alancnet
HTML
<canvas width="400" height="400" id="canvas">
</canvas>
CSS
canvas {
border: solid 1px black;
}
JavaScript
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
Math.TAO = Math.PI * 2;
function segment(a, b, polarity) {
return {
a: a,
b: b,
polarity: polarity,
children: [],
vector: vector(b.x - a.x, b.y - a.y),
normal: vector(b.x - a.x, b.y - a.y).normalize(),
length: a.length(b)
}
}
function log(v, text) {
if (text) {
console.log(text + ": %o", v);
} else {
console.log(v);
}
return v;
}
function vector(x,y) {
return {
x: x,
y: y,
multiply: function(v2) {
if (isFinite(v2)) return vector(this.x * v2, this.y * v2);
else return vector(this.x * v2.x, this.y * v2.y);
},
add: function(v2) {
if (isFinite(v2)) return vector(this.x + v2, this.y + v2);
else return vector(this.x + v2.x, this.y + v2.y);
},
rotate: function(r) {
var length = this.length(vector(0,0));
var normal = this.normalize();
var radian = normal.radial();
r -= radian;
return vector(
Math.cos(r),
Math.sin(r)
).multiply(length);
},
length: function(v2) {
return Math.sqrt(Math.pow(v2.x - this.x, 2) + Math.pow(v2.y - this.y, 2));
},
normalize: function() {
var correction = 1 / this.length(vector(0,0));
return vector(this.x * correction, this.y * correction);
},
radial: function() {
return Math.atan2(this.x, this.y);
}
}
}
function rotation(f) {
return (Math.TAO / 4) + Math.TAO * f;
}
function fractal(s) {
// If this segment has been fractaled, fractal the children instead.
if (s.children.length) s.children.forEach(fractal);
else {
var seg1 = segment(
s.a,
s.a.add(s.vector.rotate(rotation(-.166666666666666...