Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active Feb 8, 2016
Embed
What would you like to do?
Cellular automata
license: gpl-3.0
redirect: https://beta.observablehq.com/@mbostock/1d-cellular-automaton

From MathWorld: “A cellular automaton is a collection of ‘colored’ cells on a grid of specified shape that evolves through a number of discrete time steps according to a set of rules based on the states of neighboring cells.”

This example explores binary, nearest-neighbor, one-dimensional automata, of which there are 256 (28) possible rules. All 256 rules are arranged in a grid, by column and then by row. The top-left corner is rule 0; the bottom-right corner is rule 255. Zoom in to see more of any particular rule.

onmessage = function(e) {
var z0 = Math.max(0, 4 - e.data.zoom),
z1 = Math.max(0, e.data.zoom - 4),
w = e.data.size.x >> z0,
h = e.data.size.y >> z0,
n = 1 << z0,
col = e.data.column >> z1 << z0,
row = e.data.row >> z1 << z0,
data = e.data.data = [],
state = [];
for (var j = 0, y = 0; j < n; j++, y += h) {
for (var i = 0, x = 0; i < n; i++, x += w) {
draw((j | row) | ((i | col) << 4), x, y);
}
}
function draw(r, x, y) {
for (var i = 0; i < w; i++) {
state[i] = ~~(Math.random() * 2);
}
for (var j = 0; j < h; j++) {
var p = state.slice(),
k = 4 * (e.data.size.x * (j + y) + x);
for (var i = 0; i < w; i++) {
data[k++] = data[k++] = data[k++] = 255 * state[i];
data[k++] = 255;
state[i] = (r >> (p[i - 1] << 2 | p[i] << 1 | p[i + 1])) & 1;
}
}
}
postMessage(e.data);
};
<html>
<head>
<script type="text/javascript" src="https://cdn.rawgit.com/simplegeo/polymaps/v2.2.0/polymaps.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/simplegeo/polymaps/v2.2.0/examples/canvas/procedural.js"></script>
<style type="text/css">
@import url("https://cdn.rawgit.com/simplegeo/polymaps/v2.2.0/examples/example.css");
#map {
background: #ddd;
}
</style>
</head>
<body id="map">
<script type="text/javascript">
var po = org.polymaps;
var map = po.map()
.container(document.getElementById("map").appendChild(po.svg("svg")))
.zoomRange([0, 5])
.zoom(1)
.tileSize({x: 512, y: 512})
.center({lat: 0, lon: 0})
.add(po.interact())
.add(po.hash());
map.add(po.procedural()
.zoom(function(z) { return Math.min(4, z); })
.worker("cell-worker.js"));
map.add(po.compass()
.pan("none"));
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment