/* * reaction-diffusion simulation implementing the Gray-Scott model * main references: * (1) Computational Studies Of Pattern Formation In Turing Systems, Teemu Leppänen, Helsinki University of Technology * http://lib.tkk.fi/Diss/2004/isbn9512273969/ * (2) Fronts And Patterns In Reaction-Diffusion Equations, Aric Arild Hagberg, University Of Arizona * http://cnls.lanl.gov/~aric/Simulations/Simulations.html * * Frederik Vanhoutte, W:Blut 2009 */ //connectivity information, stores neighboring cells per index int[][] connectivity; //current, previous and next concentration values of substance U float[] Uc; float[] Up; float[] Un; //current, previous and next concentration values of substance V float[] Vc; float[] Vp; float[] Vn; //current and previous reaction-diffusion changes of substance U float[] Fc; float[] Fp; //current and previous reaction-diffusion changes of substance V float[] Gc; float[] Gp; // placeholder for array swapping float[] tmp; //concentration limits for rendering float Umin, Umax; float Vmin, Vmax; //reaction-diffusion parameters float F,K; // reaction parameters float DU,DV; // diffusion coefficients float dt; // time step //substrate int w; // size PImage substrate; // lo-res image int steps; boolean drawing; int mx,my; void setup(){ size(500,500); background(0); //simulation parameters w=120; //diffusion coefficients that work well for substrate size and time step DU=.082f; DV=.041f; //reaction parameters that give interesting result //found by empirically plotting interesting vs. non-interesting cases in a K vs F phase diagram F=random(0.015f,0.06f); K=0.05083f+0.26566f*F+random(-0.003f,0.003f); tmp = new float[w*w]; Uc = new float[w*w]; Up = new float[w*w]; Un = new float[w*w]; Fc = new float[w*w]; Fp = new float[w*w]; Vc = new float[w*w]; Vp = new float[w*w]; Vn = new float[w*w]; Gc = new float[w*w]; Gp = new float[w*w]; connectivity=new int[w*w][]; substrate=createImage(w,w,ARGB); // initial concentrations at trivial steady-state (all V, no U) for(int id=0;idw-1)ip-=w; if(ipp>w-1)ipp-=w; if(im<0)im+=w; if(imm<0)imm+=w; for(int j=0;jw-1)jp-=w; if(jpp>w-1)jpp-=w; if(jm<0)jm+=w; if(jmm<0)jmm+=w; connectivity[id][1]=toIndex(imm,j); connectivity[id][2]=toIndex(im,j); connectivity[id][3]=toIndex(ip,j); connectivity[id][4]=toIndex(ipp,j); connectivity[id][5]=toIndex(i,jmm); connectivity[id][6]=toIndex(i,jm); connectivity[id][7]=toIndex(i,jp); connectivity[id][8]=toIndex(i,jpp); } } // take first step using only current state (Euler) Euler(1f); steps=10; drawing=false; colorMode(HSB,1.0f); } void draw(){ if(drawing){ // add some V at mouse position mx=(int)(mouseX*w/(float)width); my=(int)(mouseY*w/(float)height); if((mx>=0)&&(mx=0)&&(my