xxxxxxxxxx
156
// 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;
var t = 1.1;
function setup() {
createCanvas(400, 400);
// noprotect
pixelDensity(1);
cols = ["#001219","#005f73","#0a9396","#94d2bd","#e9d8a6","#ee9b00","#ca6702","#bb3e03","#ae2012","#9b2226"];
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: 1
// b: noise(x / 100, y / 100)
};
next[x][y] = {
a: 1,
b: 0
};
}
}
// for (var i = width / 2 - 10; i < width / 2 + 10; i++) {
// for (var j = height / 2 - 10; j < height / 2 + 10; j++) {
// grid[floor(random(width))][floor(random(height))].b = 1;
// }
// }
// next = grid;
}
function draw() {
background(51);
if(frameCount < 20){
grid[floor(random(width))][floor(random(height))].b = 1;
}
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;
dB = noise(x / 100, y / 100, frameCount / 100) * 2.5 + 0.5;
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 c = map(next[x][y].b, 0, 1, 0, cols.length - 1) - floor(map(next[x][y].b, 0, 1, 0, cols.length - 1))
var col = lerpColor(color(cols[floor(map(next[x][y].b, 0, 1, 0, cols.length - 2))]), color(cols[floor(map(next[x][y].b, 0, 1, 0, cols.length - 2)) + 1]), c);
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.1;
sumB += grid[x + 1][y].b * 0.1;
sumB += grid[x][y + 1].b * 0.5;
sumB += grid[x][y - 1].b * 0.1;
sumB += grid[x - 1][y - 1].b * 0.03;
sumB += grid[x + 1][y - 1].b * 0.03;
sumB += grid[x + 1][y + 1].b * 0.07;
sumB += grid[x - 1][y + 1].b * 0.07;
// sumB = sumB * sumB;
return sumB;
}
function swap() {
var temp = grid;
grid = next;
next = temp;
}