xxxxxxxxxx
//チューリングパターンを使ったアート(差分方程式による反応拡散方程式のシミュレーション)
int m=3; //セルの大きさ
int n1=360/m, n2=360/m; //セルの数
float u[][] = new float[n1+2][n2+2]; //活性因子
float v[][] = new float[n1+2][n2+2]; //抑制因子
float u1[][] = new float[n1+2][n2+2]; //次の時刻の活性因子
float v1[][] = new float[n1+2][n2+2]; //次の時刻の抑制因子
float Cu[][] = new float[n1+2][n2+2]; //活性因子の拡散係数
float Cv[][] = new float[n1+2][n2+2]; //抑制因子の拡散係数
float dt=1.2, h=0.25; //時間間隔dt、格子間隔h
float a=0.024, b=0.078; //反応項a,b
//float Cu=0.002, Cv=0.001; //拡散係数Cu,Cv
PImage img;
color c[][] = new color[n1+2][n2+2];
void setup() {
size(360, 360);
//背景を描画
background(255);
noStroke();
fill(0);
textSize(width*0.7);
textAlign(CENTER,CENTER);
text("P5", width/2, height/2);
loadPixels(); //背景の色情報を保存
//初期状態
for (int i=1; i<=n1; i++) {
for (int j=1; j<=n2; j++) {
//活性因子は1、抑制因子は0。この時、f=g=0
u[i][j]=1.0; v[i][j]=0.0;
c[i][j] = pixels[(i-1)*m +(j-1)*m*width]; //画像の色
float d = map(brightness(c[i][j]), 0,255, -1.0,1.0); //輝度を変換
//拡散係数Cu,Cvに画像の輝度を反映させる
Cu[i][j] = 0.004 +d/1500;
Cv[i][j] = 0.001 +d/1500;
}
}
//全体的に乱雑さを与える
for (int i=1; i<=n1; i++) {
for (int j=1; j<=n2; j++) {
u[i][j] = 0.93 + random(-0.1, 0.1);
v[i][j] = 0.08 + random(-0.05, 0.05);
}
}
}
void draw() {
//各マスを描画
for (int i=1; i<=n1; i++) {
for (int j=1; j<=n2; j++) {
fill(constrain(255 -v[i][j]*300, 0,255)); //モノクロ色を設定
rect((i-1)*m, (j-1)*m, m, m);
}
}
update();
boundary();
}
//u[],v[]からu1[],v1[]への変化を計算
void update() {
for (int i=1; i<=n1; i++) {
for (int j=1; j<=n2; j++) {
//Du,Dvはそれぞれ(∇^2)u,(∇^2)vの近似式。
float Du = (u[i+1][j] +u[i][j+1] +u[i-1][j] +u[i][j-1] -4*u[i][j]) / (h*h);
float Dv = (v[i+1][j] +v[i][j+1] +v[i-1][j] +v[i][j-1] -4*v[i][j]) / (h*h);
//fやgは反応を司る式。右辺の反応項は任意に変更可能
float f = -u[i][j]*v[i][j]*v[i][j] +a*(1 -u[i][j]);
float g = u[i][j]*v[i][j]*v[i][j] -b*v[i][j];
//次の時刻の因子に時間変化量を加える
u1[i][j] = u[i][j] +(Cu[i][j]*Du +f)*dt;
v1[i][j] = v[i][j] +(Cv[i][j]*Dv +g)*dt;
}
}
//置換
for (int i=1; i<=n1; i++) {
for (int j=1; j<=n2; j++) {
u[i][j] = u1[i][j];
v[i][j] = v1[i][j];
}
}
}
//境界処理
void boundary() {
for (int j=1; j<=n2; j++) { //上下をつなげる
u[0][j] = u[n1][j];
u[n1+1][j] = u[1][j];
v[0][j] = v[n1][j];
v[n1+1][j] = v[1][j];
}
for (int i=1; i<=n1; i++) { //左右をつなげる
u[i][0] = u[i][n2];
u[i][n2+1] = u[i][1];
v[i][0] = v[i][n2];
v[i][n2+1] = v[i][1];
}
}