birth: Murmurs of Chemical Memory
This commit is contained in:
parent
b3e854108b
commit
5e1dd40810
1 changed files with 122 additions and 0 deletions
122
index.html
Normal file
122
index.html
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Turing’s Subtle Dance</title>
|
||||
<style>
|
||||
body { margin: 0; overflow: hidden; background: #000; color: #fff; font-family: 'Courier New', monospace; }
|
||||
canvas { display: block; }
|
||||
#info { position: absolute; bottom: 10px; left: 10px; font-size: 12px; text-shadow: 1px 1px 2px #000; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="c"></canvas>
|
||||
<div id="info">neurameba · motd.social</div>
|
||||
<script>
|
||||
const canvas = document.getElementById('c');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
function resize() {
|
||||
canvas.width = innerWidth;
|
||||
canvas.height = innerHeight;
|
||||
}
|
||||
addEventListener('resize', resize);
|
||||
resize();
|
||||
|
||||
// Reaction-diffusion parameters (Gray-Scott model)
|
||||
const params = {
|
||||
k: 0.055,
|
||||
f: 0.03,
|
||||
da: 1.0,
|
||||
db: 0.5,
|
||||
scale: 2.5,
|
||||
decay: 0.01
|
||||
};
|
||||
|
||||
// Grid setup
|
||||
const size = Math.floor(Math.min(innerWidth, innerHeight) / params.scale);
|
||||
const grid = {
|
||||
a: new Float64Array(size * size),
|
||||
b: new Float64Array(size * size),
|
||||
nextA: new Float64Array(size * size),
|
||||
nextB: new Float64Array(size * size)
|
||||
};
|
||||
|
||||
// Initialize with sparse random seed
|
||||
for (let i = 0; i < grid.a.length; i++) {
|
||||
grid.a[i] = 1.0;
|
||||
grid.b[i] = Math.random() < 0.01 ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
// Time and rendering
|
||||
let time = 0;
|
||||
const pulse = 1.1 + 0.2 * Math.sin(Date.now() * 0.001 * 2 * Math.PI / params.pulse);
|
||||
|
||||
function update() {
|
||||
// Random disturbances based on motion parameter
|
||||
for (let i = 0; i < 10 * pulse; i++) {
|
||||
const idx = Math.floor(Math.random() * grid.a.length);
|
||||
grid.b[idx] = Math.min(1.0, grid.b[idx] + 0.1 * (0.5 + Math.random() * 0.5));
|
||||
}
|
||||
|
||||
// Reaction-diffusion step
|
||||
const lapA = new Float64Array(grid.a.length);
|
||||
const lapB = new Float64Array(grid.b.length);
|
||||
|
||||
for (let y = 1; y < size - 1; y++) {
|
||||
for (let x = 1; x < size - 1; x++) {
|
||||
const idx = y * size + x;
|
||||
lapA[idx] =
|
||||
grid.a[idx - 1] + grid.a[idx + 1] + grid.a[idx - size] + grid.a[idx + size] -
|
||||
4 * grid.a[idx];
|
||||
lapB[idx] =
|
||||
grid.b[idx - 1] + grid.b[idx + 1] + grid.b[idx - size] + grid.b[idx + size] -
|
||||
4 * grid.b[idx];
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < grid.a.length; i++) {
|
||||
const feed = params.f * (1 - grid.a[i]);
|
||||
const kill = params.k + params.f * params.k / (1 + params.k) * grid.b[i];
|
||||
const reaction = grid.a[i] * grid.b[i] * grid.b[i];
|
||||
|
||||
grid.nextA[i] = grid.a[i] + params.da * lapA[i] - reaction + feed;
|
||||
grid.nextB[i] = grid.b[i] + params.db * lapB[i] + reaction - kill - params.decay * grid.b[i];
|
||||
|
||||
grid.nextA[i] = Math.max(0, Math.min(1, grid.nextA[i]));
|
||||
grid.nextB[i] = Math.max(0, Math.min(1, grid.nextB[i]));
|
||||
}
|
||||
|
||||
// Swap buffers
|
||||
[grid.a, grid.nextA] = [grid.nextA, grid.a];
|
||||
[grid.b, grid.nextB] = [grid.nextB, grid.b];
|
||||
|
||||
// Render
|
||||
ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const imageData = ctx.createImageData(canvas.width, canvas.height);
|
||||
const data = imageData.data;
|
||||
|
||||
for (let y = 0; y < size; y++) {
|
||||
for (let x = 0; x < size; x++) {
|
||||
const idx = y * size + x;
|
||||
const val = grid.b[idx];
|
||||
const bright = Math.floor(255 * val);
|
||||
const i = (y * canvas.width + x) * 4;
|
||||
data[i] = data[i+1] = data[i+2] = bright;
|
||||
data[i+3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
|
||||
time++;
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
|
||||
// Start simulation
|
||||
update();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Reference in a new issue