Built with blockbuilder.org
Eventually this is going to be a DLA demo.
forked from tonyhschu's block: Antibiotic Resistance Simulation
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
const WIDTH = 960;
const HEIGHT = 500;
const NWALKERS = 100;
const NEAR = 5;
const LIFETIME = 100;
const clampColor = function(input) {
return Math.round(Math.max(0, Math.min(255, input)))
}
const wrap = function(n) {
if (n < 0) { return false } // return n + WIDTH * HEIGHT }
if (n > WIDTH * HEIGHT) { return false } // return n - WIDTH * HEIGHT }
return n
}
const adjacencyTransform = [
function(n) { return wrap(n - WIDTH) },
function(n) { return (n % WIDTH !== 0) ? wrap(n - 1) : false },
function(n) { return ((n + 1) % WIDTH !== 0) ? wrap(n + 1) : false },
function(n) { return wrap(n + WIDTH) },
function(n) { return wrap(n - WIDTH) },
function(n) { return (n % WIDTH !== 0) ? wrap(n - 1) : false },
function(n) { return ((n + 1) % WIDTH !== 0) ? wrap(n + 1) : false },
function(n) { return wrap(n + WIDTH) },
function(n) { return wrap(n + WIDTH) }, // bias downwards
], NADJ = 9;
// Set up
var substrate, treeCells, nTreeCells, treeTop, treeLeft, treeRight,
walkers, walkerAge, pxToPaint;
var canvas = d3.select("body").append("canvas")
.attr("width", WIDTH)
.attr("height", HEIGHT);
var svg = d3.select("body").append("svg")
.attr("width", WIDTH)
.attr("height", HEIGHT)
.style("position", "absolute")
.style("top", 0)
.style("left", 0)
var ctx = canvas.node().getContext("2d");
var imgData = ctx.getImageData(0, 0, WIDTH, HEIGHT);
var data = imgData.data;
function randomWalker() {
var pos, x, y, i, xx, yy;
do {
xx = treeLeft + Math.floor(Math.random() * (treeRight - treeLeft));
yy = treeTop - NEAR;
i = yy * WIDTH + xx;
} while (xx >= WIDTH || yy >= HEIGHT || substrate[i] > 0);
return i;
}
function addTreeCell(pos, v) {
substrate[pos] = v;
treeCells[nTreeCells] = pos;
nTreeCells += 1;
var x = pos % WIDTH, y = Math.floor(pos / WIDTH);
if (y < treeTop) { treeTop = y; }
if (x < treeLeft) { treeLeft = x; }
if (x > treeRight) { treeRight = x; }
}
var resetSimulation = function() {
substrate = d3.range(WIDTH * HEIGHT).map(function() { return 0; });
treeCells = d3.range(WIDTH * HEIGHT).map(function() { return null; });
nTreeCells = 0;
// initialise the substrate with a line at the bottom,
// 1/4 -> 3/4 of the way across.
for (var i = WIDTH/4; i < 3*WIDTH/4; i++) {
var j = (HEIGHT-1)*WIDTH + i;
addTreeCell(j, 1);
}
treeTop = HEIGHT-1;
treeLeft = WIDTH/4;
treeRight = 3*WIDTH/4;
// initialise each walker to a random position (above the
// substrate)
walkers = d3.range(NWALKERS).map(function() {
return randomWalker();
});
walkerAge = d3.range(NWALKERS).map(function() { return 0; });
substrate.forEach(function(v, i) {
var b = i * 4, c = v ? 255 : 0;
data[b] = c;
data[b + 1] = c;
data[b + 2] = c;
data[b+3] = 255;
})
ctx.putImageData(imgData, 0, 0)
window.requestAnimationFrame(tick)
}
var tick = function() {
// Should Continue
pxToPaint = []
// Simulate
walkers = walkers.map(function(p, i) {
var newp = adjacencyTransform[Math.floor(Math.random()*NADJ)](p);
if (newp === false) {
// gone off the screen: re-init to random pos
walkerAge[i] = 0;
return randomWalker();
}
if (substrate[newp] > 0) {
// hit the existing tree: attach and re-init
addTreeCell(p, substrate[newp]+1);
pxToPaint.push(p);
walkerAge[i] = 0;
return randomWalker();
}
walkerAge[i] += 1;
if (walkerAge[i] > LIFETIME) {
walkerAge[i] = 0;
return randomWalker();
}
pxToPaint.push(p);
return newp;
});
// Paint
pxToPaint.forEach(function(coordinate) {
var r = coordinate * 4;
var g = r + 1;
var b = g + 1;
var a = b + 1;
var subs = substrate[coordinate];
// TODO get r,g,b from some other colour.
data[r] = subs ? 255 : 50;
data[g] = subs ? 255 : 50;
data[b] = subs ? 255 : 50;
data[a] = 255
})
ctx.putImageData(imgData, 0, 0)
// if (liveCells.length > 0) {
window.requestAnimationFrame(tick)
//} else {
// console.log('done')
// setTimeout(resetSimulation, 5000)
//}
}
resetSimulation()
</script>
</body>
https://d3js.org/d3.v4.min.js