Skip to content

Instantly share code, notes, and snippets.

@adrianseeley
Created March 12, 2014 21:10
Show Gist options
  • Save adrianseeley/9516421 to your computer and use it in GitHub Desktop.
Save adrianseeley/9516421 to your computer and use it in GitHub Desktop.
Genetic Color Sort
<div id="log"></div><br>
<canvas id="canvas" width="256", height="256"></canvas>
<script type="text/javascript">
//<canvas id="canvas" width="4096", height="4096"></canvas>
var log = document.getElementById("log");
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var imgdata = ctx.createImageData(canvas.width, canvas.height);
function set_pixel (x, y, r, g, b) {
var index = (x + y * imgdata.width) * 4;
imgdata.data[index + 0] = r;
imgdata.data[index + 1] = g;
imgdata.data[index + 2] = b;
imgdata.data[index + 3] = 255;
};
function swap_pixels (x1, y1, x2, y2) {
var p1 = get_pixel(x1, y1);
var p2 = get_pixel(x2, y2);
set_pixel(x1, y1, p2[0], p2[1], p2[2]);
set_pixel(x2, y2, p1[0], p1[1], p1[2]);
};
function get_pixel (x, y) {
var index = (x + y * imgdata.width) * 4;
return [imgdata.data[index + 0], imgdata.data[index + 1], imgdata.data[index + 2]];
};
function draw () {
ctx.putImageData(imgdata, 0, 0);
};
function prep () {
var r = 0;
var g = 0;
var b = 0;
var incr = 4096 / canvas.width;
for (var x = 0; x < canvas.width; x++) {
for (var y = 0; y < canvas.height; y++) {
set_pixel(x, y, r, g, b);
b += incr;
if (b > 255) {
b = 0;
g += incr;
if (g > 255) {
g = 0;
r += incr;
}
}
}
}
draw();
};
function preprandom () {
for (var x = 0; x < canvas.width; x++) {
for (var y = 0; y < canvas.height; y++) {
set_pixel(x, y, Math.floor(Math.random() * 255), Math.floor(Math.random() * 255), Math.floor(Math.random() * 255));
}
}
draw();
};
function fitness () {
var f = 0;
for (var x = 0; x < canvas.width; x++) {
for (var y = 0; y < canvas.height; y++) {
var p = get_pixel(x, y);
for (var x2 = Math.max(0, -range); x2 <= range && x + x2 < canvas.width; x2++) {
for (var y2 = Math.max(0, -range); y2 <= range && y + y2 < canvas.height; y2++) {
if (x2 == 0 & y2 == 0) continue;
var d = 0;
var p2 = get_pixel(x + x2, y + y2);
for (var c = 0; c < p.length; c++) {
d += Math.pow(p[c] - p2[c], 2);
}
f += Math.sqrt(d);
}
}
}
}
return f;
};
function pass () {
iter++;
var x_hosts = [];
var y_hosts = [];
var x_dests = [];
var y_dests = [];
for (var m = 0; m < mutas; m++) {
x_hosts.push(Math.floor(Math.random() * canvas.width));
y_hosts.push(Math.floor(Math.random() * canvas.height));
x_dests.push(Math.floor(Math.random() * canvas.width));
y_dests.push(Math.floor(Math.random() * canvas.height));
swap_pixels(x_hosts[m], y_hosts[m], x_dests[m], y_dests[m]);
}
var new_fitness = fitness();
if (new_fitness < queen_fitness) {
misses = 0;
queen_fitness = new_fitness;
draw();
} else {
misses++;
if (misses > misses_cap) {
mutas--;
misses = 0;
}
for (var m = 0; m < mutas; m++) {
swap_pixels(x_hosts[m], y_hosts[m], x_dests[m], y_dests[m]);
}
}
log.innerHTML = "iter: " + iter + " mutas: " + mutas + " misses: " + misses + " fit: " + queen_fitness;
if (mutas == 0) return alert("Done!");
setTimeout(pass, 0);
};
iter = 0;
misses = 0;
misses_cap = 100;
mutas = 5;
range = 1;
//prep();
preprandom();
queen_fitness = fitness();
setTimeout(pass, 1000);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment