Skip to content

Instantly share code, notes, and snippets.

@robinhouston
Created July 28, 2013 13:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save robinhouston/6098502 to your computer and use it in GitHub Desktop.
Save robinhouston/6098502 to your computer and use it in GitHub Desktop.
Spiral triangles
<!DOCTYPE html>
<title>Triangular spiral</title>
<script src="http://bl.ocks.org/robinhouston/raw/6096562/rAF.js" charset="utf-8"></script>
<script src="http://bl.ocks.org/robinhouston/raw/6096562/doyle.js" charset="utf-8"></script>
<canvas width=960 height=500></canvas>
<script>
// Initialisation
var canvas = document.getElementsByTagName("canvas")[0],
context = canvas.getContext("2d");
// Complex arithmetic
function cmul(w, z) {
return [
w[0]*z[0] - w[1]*z[1],
w[0]*z[1] + w[1]*z[0]
];
}
function modulus(p) {
return Math.sqrt(p[0]*p[0] + p[1]*p[1]);
}
function crecip(z) {
var d = z[0]*z[0] + z[1]*z[1];
return [z[0]/d, -z[1]/d];
}
// Doyle spiral drawing
function spiral(r, start_point, delta, gamma, options) {
var recip_delta = crecip(delta),
mod_delta = modulus(delta),
mod_recip_delta = 1/mod_delta,
color_index = options.i,
colors = options.fill,
min_d = options.min_d,
max_d = options.max_d;
// Spiral inwards
for (var q = start_point, mod_q = modulus(q);
mod_q > min_d;
q = cmul(q, recip_delta), mod_q *= mod_recip_delta
) {
color_index = (color_index + colors.length - 1) % colors.length;
}
// Spiral outwards
for (;mod_q < max_d; q = cmul(q, delta), mod_q *= mod_delta) {
context.fillStyle = colors[color_index];
context.beginPath();
//context.arc(q[0], q[1], mod_q*r, 0, 7, false);
context.moveTo.apply(context, q);
context.lineTo.apply(context, cmul(q, delta));
context.lineTo.apply(context, cmul(q, gamma));
context.closePath();
context.fill();
color_index = (color_index + 1) % colors.length;
}
}
// Animation
var p = 9, q = 24;
var root = doyle(p, q);
var ms_per_repeat = 300;
function frame(t) {
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
context.translate(Math.round(canvas.width/2), cy = Math.round(canvas.height/2));
var scale = Math.pow(root.mod_a, t);
context.scale(scale, scale);
context.rotate(root.arg_a * t);
var min_d = 1/scale, max_d = canvas.width * 2;
var start = root.a;
for (var i=0; i<q; i++) {
spiral(root.r, start, root.a, root.b, {
fill: ["#483352"], i: 0, //, "#483352", "#486078"], i: (2*i)%3,
min_d: min_d, max_d: max_d
});
start = cmul(start, root.b);
}
}
var first_timestamp;
function loop(timestamp) {
if (!first_timestamp) first_timestamp = timestamp;
frame(((timestamp - first_timestamp) % (ms_per_repeat*3)) / ms_per_repeat);
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment