We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hey there,
I'm trying to scale a turing pattern based on the Gray Scott Model but am struggling with it. Is there a way to scale the patterns? Because I want them in HiRes but along with the higher resolution the look changes a lot?
My guess: the solution lies within the Laplace Diffusor. (I developed a radial version of the Laplace Diffusor here based on a 3x3 grid.)
Here is the code... change the Resolution (N) from 500 to 5000 and see what I mean.
////////////////////////////////////////////////////////////////
// //
// Turing Pattern //
// //
////////////////////////////////////////////////////////////////
PGraphics hires;
String name;
float A, B, C, D;
int N = 500; // scale of pattern is nice
// int N = 5000; // scale of pattern is much to dense
int screenN = 500;
int counter; // counter
////3x3 Grid convolution // Laplace
float small = .546172610397832;
float big = .972265072024363;
//System parameters
float diffU = 0.2; //A
float diffV = 0.1; //B
float paramF;
float paramK;
float fade = (N/2) * .0000002;
boolean rndInitCondition;
float[][] U = new float[N][N];
float[][] V = new float[N][N];
float[][] dU = new float[N][N];
float[][] dV = new float[N][N];
int[][] offset = new int[N][4]; ///Scale
void generateInitialState() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
U[i][j] = 1.0; ///A white
V[i][j] = 0.0; ///B black
}
}
if (rndInitCondition) {
for (int i = N/3; i < 2*N/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 = N/3; i < 2*N/3; i++) {
for (int j = N/3; j < 2*N/3; j++) {
U[i][j] = 0.5;
V[i][j] = 0.25;
}
}
}
}
void setup() {
colorMode(HSB, 1.0);
hires = createGraphics(N, N, JAVA2D); // Create a new PGraphics object 5000x5000px
hires.beginDraw(); // Start drawing to the PGraphics object
size(screenN, screenN, P2D);
//hires.colorMode(HSB, 1.0);
hires.smooth();
rndInitCondition = true;
//Populate U and V with initial data
generateInitialState();
//Set up offsets
for (int i = 1; i < N-1; i++) {
offset[i][0] = i-1;
offset[i][1] = i+1;
}
offset[1][0] = N-1;
offset[1][1] = 1;
offset[N-1][0] = N-2;
offset[N-1][1] = 0;
}
void timestep(float F, float K, float diffU, float diffV) {
F = 0.027;
K = 0.057;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
float u = U[i][j]; //black
float v = V[i][j]; //white
int left = offset[i][0]; // = i-1
int right = offset[i][1]; // = i+1
int up = offset[j][0]; // = j-1
int down = offset[j][1]; // = j+1
float uvv = u*v*v; ///Reaction
// Diffusion (Laplace Operator)
// float lapU = (U[left][j] + U[right][j] + U[i][up] + U[i][down] - 4*u);
// float lapV = (V[left][j] + V[right][j] + V[i][up] + V[i][down] - 4*v);
/////////////////Radial Diffusion (Laplace Operator)
float lapU = (((U[left][j] + U[right][j] + U[i][up] + U[i][down]) * big) + ((U[left][up] + U[right][down] + U[right][up] + U[left][down]) * small) - ((3.889060288097452 + 2.184690441591328) * u));
float lapV = (((V[left][j] + V[right][j] + V[i][up] + V[i][down]) * big) + ((V[left][up] + V[right][down] + V[right][up] + V[left][down]) * small) - ((3.889060288097452 + 2.184690441591328) * v));
dU[i][j] = diffU*lapU - uvv + F*(1 - u);
dV[i][j] = diffV*lapV + uvv - (K+F)*v;
}
}
for (int i= 0; i < N; i++) {
for (int j = 0; j < N; j++) {
U[i][j] += dU[i][j];
V[i][j] += dV[i][j];
}
}
}
void draw() {
counter++;
for (int k = 0; k < 10; k++) {
timestep(paramF, paramK, diffU, diffV);
}
// Draw points
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
hires.set(i, j, color(0.0, 0.0, U[i][j]));
}
}
if(counter%3 == 0) { // every 10th frame we snap a preview and draws it
PImage img = hires.get(0, 0, hires.width, hires.height); //snap an image from the off-screen graphics
img.resize(width, height); // resize to fit the on-screen display
image(img,0,0); // display the resized image on screen
}
}
/////////////////////////////////////////////////////////////// Save Name
void keyPressed() {
switch (key) {
case 's':
hires.endDraw(); // finish drawing
name = getIncrementalFilename("Turing-####.tiff");
hires.save(name); //save to file - use .tif as format for high-res
println("saved"); // nice with some feedback
}
}
public String getIncrementalFilename(String what) {
String s="",prefix,suffix,padstr,numstr;
int index=0,first,last,count;
File f;
boolean ok;
first=what.indexOf('#');
last=what.lastIndexOf('#');
count=last-first+1;
if( (first!=-1)&& (last-first>0)) {
prefix=what.substring(0, first);
suffix=what.substring(last+1);
// Comment out if you want to use absolute paths
// or if you're not using this inside PApplet
if(sketchPath!=null) prefix=savePath(prefix);
index=0;
ok=false;
do {
padstr="";
numstr=""+index;
for(int i=0; i<count-numstr.length(); i++) padstr+="0";
s=prefix+padstr+numstr+suffix;
f=new File(s);
ok=!f.exists();
index++;
// Provide a panic button. If index > 10000 chances are it's an
// invalid filename.
if(index>10000) ok=true;
}
while(!ok);
// Panic button - comment out if you know what you're doing
if(index>10000) {
println("getIncrementalFilename thinks there is a problem - Is there "+
" more than 10000 files already in the sequence or is the filename invalid?");
return prefix+"ERR"+suffix;
}
}
return s;
}