Skip to content

Instantly share code, notes, and snippets.

@robinhouston
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robinhouston/29256371a9106f9eee61 to your computer and use it in GitHub Desktop.
Save robinhouston/29256371a9106f9eee61 to your computer and use it in GitHub Desktop.
Ammonis worms up close and personal
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ammonis worms, up close and personal</title>
<style>
body { margin: auto; width: 960px; height: 500px; overflow: hidden; }
</style>
</head>
<body>
<script>
var W = 120, H = 64, N = W*H, M = 8; // Tile dimensions
var doc = document.documentElement,
canvas = document.createElement("canvas"),
cx = canvas.getContext("2d"),
tile = document.createElement("canvas"),
tcx = tile.getContext("2d");
function init() {
tile.width = W;
tile.height = H;
canvas.width = W * M;
canvas.height = H * M;
document.body.appendChild(canvas);
initReactionDiffusion();
startReactionDiffusion();
}
function drawTiles() {
renderTile();
cx.drawImage(tile, 0, 0, W*M, H*M);
}
var α, β, af, α1, β1, α2, β2, α3, β3, α4, β4, α_temp, β_temp;
function initReactionDiffusion() {
α = []; β = [];
for (var i=0; i<N; i++) {
α[i] = Math.random() * 100 - 50;
β[i] = Math.random() * 100 - 50;
}
α1 = []; α2 = []; α3 = []; α4 = [];
β1 = []; β2 = []; β3 = []; β4 = [];
α_temp = []; β_temp = [];
}
function frame() {
rk4(f, 0.2);
drawTiles();
af = requestAnimationFrame(frame);
}
function startReactionDiffusion() {
af = requestAnimationFrame(frame);
}
function renderTile() {
var imd = tcx.createImageData(W, H),
d = imd.data;
for (var i=0; i<N; i++) {
var v = ((abClampMax - α[i]) / (abClampMax - abClampMin) * 255)|0;
d[4*i + 0] = v;
d[4*i + 1] = v;
d[4*i + 2] = v;
d[4*i + 3] = 0xFF;
}
tcx.putImageData(imd, 0, 0);
}
var clampMin = -10,
clampMax = 10,
D_a = 0.001,
D_b = 0.004,
abClampMin = -50,
abClampMax = 50;
function f(α_in, β_in, c, δα, δβ, δα_out, δβ_out) {
var α, β;
if (c == 0) {
α = α_in;
β = β_in;
} else {
α = α_temp;
β = β_temp;
for (var i=0; i<N; i++) {
α[i] = α_in[i] + c*δα[i];
β[i] = β_in[i] + c*δβ[i];
}
}
for (var y=0; y<H; y++) {
for (var x=0; x<W; x++) {
var i = W*y + x,
px = (x+W-1)%W, sx = (x+1)%W,
py = (y+H-1)%H, sy = (y+1)%H;
var laplacian_a = α[W*py+x] + α[W*y+sx] + α[W*sy+x] + α[W*y+px] - 4*α[i],
laplacian_b = β[W*py+x] + β[W*y+sx] + β[W*sy+x] + β[W*y+px] - 4*β[i];
δα_out[i] = (laplacian_a % 1.0) + Math.max(clampMin, Math.min(clampMax,
(D_a * (α[i]*α[i] - β[i]*β[i])) + laplacian_b));
δβ_out[i] = (laplacian_a % 1.0) + Math.max(clampMin, Math.min(clampMax,
(D_b * (2*α[i]*β[i])) - laplacian_a));
}
}
}
function rk4(f, h) {
f(α, β, 0, null, null, α1, β1);
f(α, β, h/2, α1, β1, α2, β2);
f(α, β, h/2, α2, β2, α3, β3);
f(α, β, h, α3, β3, α4, β4);
for (var i=0; i<N; i++) {
α[i] = Math.max(abClampMin, Math.min(abClampMax, α[i] + (h/6) * (α1[i] + 2*α2[i] + 2*α3[i] + α4[i]) ));
β[i] = Math.max(abClampMin, Math.min(abClampMax, β[i] + (h/6) * (β1[i] + 2*β2[i] + 2*β3[i] + β4[i]) ));
}
}
init();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment