反応拡散系

提供:kuhalaboWiki
(版間での差分)
移動: 案内, 検索
(Gray-Scott Reaction and Diffusion(反応拡散系)モデル)
(Gray-Scott Reaction and Diffusion(反応拡散系)モデル)
9行: 9行:
 
* 物質B:一定の割合で消滅する(Kill)
 
* 物質B:一定の割合で消滅する(Kill)
 
* 1つのAと2つのBとが反応するとAがBに変化する。
 
* 1つのAと2つのBとが反応するとAがBに変化する。
* 物質A,Bの濃淡を模様として描画する。物質Aの発生率と物質Bの消滅率を微妙に変化させるだけで、現れる模様は大きく変化する。
 
  
 
[[ファイル:Rd-reaction.png]]
 
[[ファイル:Rd-reaction.png]]
  
*2つの物質AとBが反応しながら、空間に拡散していく様子を反応拡散方程式で表する。
+
* 2つの物質AとBが反応しながら、空間に拡散していく様子を反応拡散方程式で表わす。
  
 
[[ファイル:Rd-equation.png]]
 
[[ファイル:Rd-equation.png]]
 +
 +
* 物質A,Bの濃淡を模様として描画する。物質Aの発生率と物質Bの消滅率を微妙に変化させるだけで、現れる模様は大きく変化する。
  
 
;参照資料
 
;参照資料

2020年11月1日 (日) 23:43時点における版

目次

Gray-Scott Reaction and Diffusion(反応拡散系)モデル

物質は空間内で濃度の濃いところから薄いところへ拡散し、最終的に均一になります。 2つの物質が反応しながら拡散するとき、物質の濃淡の波ができ、生物に見られる多種多様な模様が生成されます。 これはチューリングパターンとして知られていて、シマウマの縞模様やヒョウの斑模様などがよい例です。

反応と拡散のアルゴリズム
  • 物質A:一定の割合で発生する(Feed)
  • 物質B:一定の割合で消滅する(Kill)
  • 1つのAと2つのBとが反応するとAがBに変化する。

Rd-reaction.png

  • 2つの物質AとBが反応しながら、空間に拡散していく様子を反応拡散方程式で表わす。

Rd-equation.png

  • 物質A,Bの濃淡を模様として描画する。物質Aの発生率と物質Bの消滅率を微妙に変化させるだけで、現れる模様は大きく変化する。
参照資料
シミュレーション
ソース
芸術学部フェスタ2020

ソース例

int M = 640;
int N = 480;

//System parameters
double diffU;
double diffV;
double paramF;
double paramK;

boolean rndInitCondition;

double[][] U = new double[M][N];
double[][] V = new double[M][N];

double[][] dU = new double[M][N];
double[][] dV = new double[M][N];

void settings() {
  size(M,N);
}

void generateInitialState() {
    for (int i = 0; i < M; i++) {
      for (int j = 0; j < N; j++) { 
        U[i][j] = 1.0;
        V[i][j] = 0.0;
      }
    }
    
    if (rndInitCondition) {
        for (int i = M/3; i < 2*M/3; i++) {
            for (int j = N/3; j < 2*N/3; j++) {     
               U[i][j] = 0.5*(1 + random(-1, 1));
               V[i][j] = 0.25*( 1 + random(-1, 1));
          }
        }
    } else {
      for (int i = M/3; i < 2*M/3; i++) {
            for (int j = N/3; j < 2*N/3; j++) {     
               U[i][j] = 0.5;
               V[i][j] = 0.25;
          }
        }
    }
}

void setup() {
   frameRate(48);
   smooth();
   colorMode(HSB,1.0);
   
   //Set default parameters;
   diffU = 0.16;
   diffV = 0.08;
   paramF = 0.035;
   paramK = 0.06;
   
   rndInitCondition = true;
   
   //Populate U and V with initial data
   generateInitialState();
}

void timestep(double F, double K, double diffU, double diffV) {
      for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
          int p = i + j*N;
          
          double u = U[i][j];
          double v = V[i][j];
          double uvv = u*v*v;
          
          int left = (i-1+M) % M;
          int right = (i+1) % M;
          int up = (j-1+N) % N;
          int down = (j+1) % N;
       
          double lapU = (U[left][j] + U[right][j] + U[i][up] + U[i][down] - 4*u);
          double lapV = (V[left][j] + V[right][j] + V[i][up] + V[i][down] - 4*v);
          
          dU[i][j] = diffU*lapU  - uvv + F*(1 - u);
          dV[i][j] = diffV*lapV + uvv - (K+F)*v;
        }
      }
    for (int i= 0; i < M; i++) {
      for (int j = 0; j < N; j++){
          U[i][j] += dU[i][j];
          V[i][j] += dV[i][j];
      }
    }
}

void draw(){ 
    for (int k = 0; k < 10; k++) {
       timestep(paramF, paramK, diffU, diffV);
    }
   
    // Draw points
    for (int i = 0; i < M; i++) {
      for (int j = 0; j < N; j++) {
        set(i, j, color((float)(1-U[i][j]),0.9, 0.5 ));
      }
    }
}

キーボードでパラメータを変更

void keyPressed() {
  switch (key) {
    case '1':
          diffU = 0.16;
          diffV = 0.08;
          paramF = 0.035;
          paramK = 0.06;
          generateInitialState();
          break;
    case '2':
          diffU = 0.16;
          diffV = 0.08;
          paramF = 0.042;
          paramK = 0.065;
          generateInitialState();
          break;
    case '3':
          diffU = 0.18;
          diffV = 0.13;
          paramF = 0.025;
          paramK = 0.056;
          generateInitialState();
          break;
    case '4':
          diffU = 0.18;
          diffV = 0.09;
          paramF = 0.02;
          paramK = 0.056;
          generateInitialState();
          break;
    case '5':
          diffU = 0.14;
          diffV = 0.06;
          paramF = 0.035;
          paramK = 0.065;
          generateInitialState();
          break;
    case '6':
          diffU = 0.19;
          diffV = 0.09;
          paramF = 0.062;
          paramK = 0.062;
          generateInitialState();
          break;
     case '7':
          diffU = 0.16;
          diffV = 0.08;
          paramF = 0.05;
          paramK = 0.065;
          generateInitialState();
          break;
    case 'r':
          rndInitCondition = true;
          generateInitialState();
          break;
    case 'n':
          rndInitCondition = false;
          generateInitialState();
  }
}

参考

スケーラブルアート論

個人用ツール
名前空間

変種
操作
案内
ツールボックス