Skip to content

Instantly share code, notes, and snippets.

@xmichaelx
Last active November 21, 2015 21:08
Show Gist options
  • Save xmichaelx/36e686e935d7dd15220a to your computer and use it in GitHub Desktop.
Save xmichaelx/36e686e935d7dd15220a to your computer and use it in GitHub Desktop.
1D cellular automata
function shuffle(o){
for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
}
function cellular1d(width, height, density, rule) {
var blackPixelsCount = Math.floor(width*density), whitePixelsCount = width - blackPixelsCount;
var initial = [];
while(blackPixelsCount--) {
initial.push(1);
}
while(whitePixelsCount--) {
initial.push(0);
}
initial = shuffle(initial);
var matrix = new Uint8Array(width * height);
for (var i = 0 ; i < width;i++) {
matrix[i] = initial[i];
}
for (var i=1;i<height;i++) {
var prevOffset = (i-1) * width;
var currentOffset = i * width;
// left-most item
var str = "" + matrix[prevOffset + width - 1] + matrix[prevOffset] + matrix[prevOffset + 1];
matrix[currentOffset] = rule[str];
// right-most item
str = "" + matrix[prevOffset+width-2] + matrix[prevOffset+width-1] + matrix[prevOffset];
matrix[currentOffset + width-1] = rule[str];
for (var j = 1;j<width-1;j++) {
str = "" + matrix[prevOffset + j-1] + matrix[prevOffset + j] +matrix[prevOffset + j+1];
matrix[currentOffset + j] = rule[str]
}
}
return matrix;
}
function pad(num, size) {
var s = num+"";
while (s.length < size)
s = "0" + s;
return s;
}
function draw() {
var params = JSON.parse(document.getElementById("input_parameters").value);
var num = pad(params.rule.toString(2),8);
var rule = {
"111" : parseInt(num[0]), "110" : parseInt(num[1]), "101" : parseInt(num[2]),
"100" : parseInt(num[3]), "011" : parseInt(num[4]), "010" : parseInt(num[5]),
"001" : parseInt(num[6]), "000" : parseInt(num[7])
};
var matrix = cellular1d(params.width, params.height, params.density, rule);
var canvas = document.getElementById("canvas");
canvas.width = params.width;
canvas.height = params.height;
var ctx = canvas.getContext('2d');
var imageData = ctx.getImageData(0, 0, params.width, params.height);
var data = imageData.data;
var i = params.width;
while (i--) {
var j = params.height;
while (j--) {
var index = (j * params.width + i) * 4;
var point = (1 - matrix[j * params.width + i]);
data[index] = point*255; // red
data[++index] = point*255; // green
data[++index] = point*255; // blue
data[++index] = 255; // alpha
}
}
ctx.putImageData(imageData, 0, 0);
}
window.onload = function() {
var initialParams = {
width:1000,
height:800,
density:0.5,
rule:184
};
document.getElementById("input_parameters").value = JSON.stringify(initialParams);
document.getElementById('input_parameters').onkeypress = function(e){
if (!e) e = window.event;
var keyCode = e.keyCode || e.which;
if (keyCode == '13'){
draw();
}
};
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Cellular automata</title>
<meta name="description" content="Cellular automata">
<meta name="author" content="black_feathered">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-10">
<div class="input-group">
<span class="input-group-addon">Input parameters</span>
<input type="text" class="form-control" id="input_parameters">
</div>
</div>
<div class="col-xs-2">
<button type="button" class="btn btn-default" onclick="draw()">Draw</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<canvas class="img-thumbnail" id="canvas"></canvas>
</div>
</div>
</div>
</body>
<script src="cellular.js"></script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment