Created
July 28, 2013 13:02
-
-
Save robinhouston/6098502 to your computer and use it in GitHub Desktop.
Spiral triangles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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