xxxxxxxxxx
151
// Reaction-Diffusion
// The Coding Train / Daniel Shiffman
// https://thecodingtrain.com/challenges/13-reaction-diffusion
// https://youtu.be/BV9ny785UNc
// https://nebula.tv/videos/the-coding-train-coding-challenge-13-reaction-diffusion-algorithm-in-p5js
// Code from Challenge: https://editor.p5js.org/codingtrain/sketches/govdEW5aE
// Written entirely based on
// http://www.karlsims.com/rd.html
// Also, for reference
// http://hg.postspectacular.com/toxiclibs/src/44d9932dbc9f9c69a170643e2d459f449562b750/src.sim/toxi/sim/grayscott/GrayScott.java?at=default
var grid;
var next;
var dA = 1;
var dB = 1.4;
var feed = 0.055;
var k = 0.075;
var t = 1;
function setup() {
createCanvas(400, 400);
pixelDensity(1);
cols = ["#03045e","#023e8a","#0077b6","#0096c7","#00b4d8","#48cae4","#90e0ef","#ade8f4","#caf0f8"];
grid = [];
next = [];
var a = color(0);
var b = color(0);
var c = color(0);
for (var x = 0; x < width; x++) {
grid[x] = [];
next[x] = [];
for (var y = 0; y < height; y++) {
grid[x][y] = {
a: 1,
// b: 0
b: noise(x / 100, y / 100)
};
next[x][y] = {
a: 1,
b: noise(x / 10, y / 10)
};
}
}
// for (var i = 100; i < 110; i++) {
// for (var j = 100; j < 110; j++) {
// grid[i][j].b = 1;
// }
// }
// next = grid;
}
function draw() {
background(51);
loadPixels();
for (var x = 1; x < width - 1; x++) {
for (var y = 1; y < height - 1; y++) {
var a = grid[x][y].a;
var b = grid[x][y].b;
next[x][y].a = a +
(dA * laplaceA(x, y)) -
(a * b * b) +
(feed * (1 - a)) * t;
next[x][y].b = b +
(dB * laplaceB(x, y)) +
(a * b * b) -
((k + feed) * b) * t;
next[x][y].a = constrain(next[x][y].a, 0, 1);
next[x][y].b = constrain(next[x][y].b, 0, 1);
var col = color(cols[floor(map(next[x][y].b, 0, 1, 0, cols.length - 1))]);
var pix = (x + y * width) * 4;
a = red(col);
b = green(col);
c = blue(col);
c = constrain(c, 0, 255);
pixels[pix + 0] = a;
pixels[pix + 1] = b;
pixels[pix + 2] = c;
pixels[pix + 3] = 255;
}
}
updatePixels();
// loadPixels();
// for (var x = 0; x < width; x++) {
// for (var y = 0; y < height; y++) {
// var pix = (x + y * width) * 4;
// var a = next[x][y].a;
// var b = next[x][y].b;
// var c = floor((a - b) * 255);
// c = constrain(c, 0, 255);
// pixels[pix + 0] = a * 255;
// pixels[pix + 1] = c;
// pixels[pix + 2] = b * 255;
// pixels[pix + 3] = 255;
// }
// }
// updatePixels();
swap();
}
function laplaceA(x, y) {
var sumA = 0;
sumA += grid[x][y].a * -1;
sumA += grid[x - 1][y].a * 0.2;
sumA += grid[x + 1][y].a * 0.2;
sumA += grid[x][y + 1].a * 0.2;
sumA += grid[x][y - 1].a * 0.2;
sumA += grid[x - 1][y - 1].a * 0.05;
sumA += grid[x + 1][y - 1].a * 0.05;
sumA += grid[x + 1][y + 1].a * 0.05;
sumA += grid[x - 1][y + 1].a * 0.05;
// sumA = sumA * sumA;
return sumA;
}
function laplaceB(x, y) {
var sumB = 0;
sumB += grid[x][y].b * -1;
sumB += grid[x - 1][y].b * 0.2;
sumB += grid[x + 1][y].b * 0.2;
sumB += grid[x][y + 1].b * 0.2;
sumB += grid[x][y - 1].b * 0.2;
sumB += grid[x - 1][y - 1].b * 0.05;
sumB += grid[x + 1][y - 1].b * 0.05;
sumB += grid[x + 1][y + 1].b * 0.05;
sumB += grid[x - 1][y + 1].b * 0.05;
// sumB = sumB * sumB;
return sumB;
}
function swap() {
var temp = grid;
grid = next;
next = temp;
}