ごった煮マシンというものを用いてBZ反応をシミュレーションします。ごった煮マシンとはBZ反応のような反応拡散系をセルオートマトンでシミュレーションするために作られたモデルです。
実際に動かしたものがこちらになります。
youtu.be
後半の部分がBZ反応にとても良く似ているかと思います。
ルールやパラメータは以下のpdfの一番下の方に書かれたものを参考にしました。
http://endeavor.eng.toyo.ac.jp/~yoshino/lecture/ex_com_simulation/2010week10.pdf
このpdfの説明を見ればどういうルールなのか理解できると思います。
少し仕様を変えていますがほとんどオリジナルと同じです。
コード
int len; int col, row; int[][] c; boolean pause = false; int n = 0; void setup() { size(600, 600); frameRate(10); len = 3; col = width/len; row = height/len; c = new int[col][row]; //最初の配置 for (int i = 0; i < col; i ++) { for (int j = 0; j < row; j ++) { c[i][j] = floor(random(0, 256)); } } } void draw() { background(255); //セルの描画 for (int i = 0; i < col; i ++) { for (int j = 0; j < row; j ++) { noStroke(); fill(c[i][j]); rect(i*len, j*len, len, len); } } //次のステップでの生命の配置を計算 if (pause == false) { //描画が動いているとき int[][] next = new int[col][row]; for (int i = 1; i < col+1; i ++) { for (int j = 1; j < row+1; j ++) { int a = 0; //隣接する感染したセル数 int b = 0; //隣接する病気のセル数 for (int k = 0; k <= 2; k ++) { for (int l = 0; l <= 2; l ++) { if (c[(i+k-1) % col][(j+l-1) % col] > 0 && c[(i+k-1) % col][(j+l-1) % col] <255 ) { a += 1; } if (c[(i+k-1) % col][(j+l-1) % col] == 255 ) { b += 1; } int s = c[(i-1) % col][(j-1) % col] + c[(i) % col][(j-1) % col] + c[(i+1) % col][(j-1) % col] + c[(i-1) % col][(j) % col] + c[(i) % col][(j) % col] + c[(i+1) % col][(j) % col] + c[(i-1) % col][(j+1) % col] + c[(i) % col][(j+1) % col] + c[(i+1) % col][(j+1) % col]; if (c[(i) % col][(j) % col] < 0) { c[(i) % col][(j) % col] = 0; } if (c[(i) % col][(j) % col] == 0) { float k_1 = 0.09; float k_2 = 0.01; next[(i) % col][(j) % col] = floor(a/k_1) + floor(b/k_2); } if (c[(i) % col][(j) % col] > 0 && c[(i) % col][(j) % col] < 255) { float g = -0.01; next[(i) % col][(j) % col] = floor(s/(a + b + 1) + g); } if (c[(i) % col][(j) % col] >= 255) { next[(i) % col][(j) % col] = 0; } } } } } c = next; //次のステップの配置を適用 } } void keyPressed() { //「s」キーでポーズする if (key == 's') pause = true; //「c」キーで画面の初期化 if (key == 'c') { for (int i = 0; i < col; i ++) { for (int j = 0; j < row; j ++) { c[i][j] = 0; } } } } void keyReleased() { //「s」キーが離されたらポーズを解除 if (key == 's') pause = false; }