How to get turing patterns with a direction?

edited January 2014 in How To...

Hey there,

lately I was doodling around with the "Multiscale Turing Patterns" Code of Frederik van Houtte (w:blut). From a designers point of view I was curious what potential it has and what new opportunities it offers.

So, first of all I reduced the Levels to only one, to get the basics behind the concept. I received the typical, basic pattern, very similar to the pattern found on a mackerels skin.

Then I tried to shape it a bit and bring it into a ring form. Doing this, I found out, that the pattern tends to follow horizontal and vertical lines. In the first render steps it still looks pretty random but it becomes more obvious after a while

See here:

Early render step:
MCB_00018

Later render step:
MCB_00229

So here's my question:

Is there a way to let the pattern follow lines parallel to the circle? For now I didn't changed the "TuringPattern class" just the "void draw" part. This is the code (incl. the credits):

/*
// This is a fast and basic implementation of Jonathan McCabe's multi-scale Turing pattern.
 // Check out his paper: http://www.jonathanmccabe.com/Cyclic_Symmetric_Multi-Scale_Turing_Patterns.pdf
 // Jason Rampe's blog provides implementation details:
 // http://softologyblog.wordpress.com/2011/07/05/multi-scale-turing-patterns/
 // Special thanks to Jason for pestering Jonathan about the details ;)
 //
 // Feel free to use, distribute, change, any_verb this code but please attribute Jonathan for his
 // remarkeable algorithm and the beautiful McCabeisms it generates.
 //
 // Cheers,
 // Frederik
 //
 */


float[][] grid;
float[][] tmp;
int num;
int levels;
TuringPattern[] patterns;
int counter;
int size = 400;
float noiseScale = 0.05;
float n;
float iR =50;
float oR = 190;
int centerX, centerY;
float dist;

void setup() {
  size(size, size); 
  num=size;
  levels=1;
  tmp=new float[num][num];
  patterns=new TuringPattern[levels];
  patterns[0]=new  TuringPattern(num, 4, 8, 4, 8, 1, 0.05);
  /*   patterns[1]=new  TuringPattern(num, 100, 200, 100, 200, 1, 0.05);
   patterns[2]=new  TuringPattern(num, 10, 20, 10, 20, 1, 0.03);
   patterns[3]=new  TuringPattern(num, 5, 10, 5, 10, 1, 0.02);
   patterns[4]=new  TuringPattern(num, 2, 4, 2, 4, 1, 0.01);
   */
  initGrid();
  noStroke();
}

void draw() {
  for (int i=0;i<5;i++) step();
  translate((counter%2)*size, ((counter/2)%2)*size);
  render();
}

void keyPressed() {
  saveFrame("MCB_#####.png");
}

void mouseReleased() {   
  initGrid();
}

void render() {
  for (int i=0;i<num;i++) {
    for (int j=0;j<num;j++) {      

      fill((grid[i][j]+1)/2*255);
      rect(i, j, 1, 1);
    }
  }
  counter++;
}

void initGrid() {

  counter=0;

  grid=new float[num][num];
  centerX = width/2;
  centerY = height/2;

  for (int i=0;i<num;i++) {
    for (int j=0;j<num;j++) {


      grid[i][j]=random(-1, 1);
    }
  }
}


void step() {
  for (int i=0;i<levels;i++) {
    patterns[i].step(grid, tmp);
  }
  updateGrid();
}


//checkout the references in the intro, they're a lot better
//than any comments I can come up with
void updateGrid() {

  float smallest=10;
  float largest=-10;
  for (int i=0;i<num;i++) {
    for (int j=0;j<num;j++) {

      float bestvariation=patterns[0].variations[i][j];
      int bestlevel=0;
      for (int k=1;k<levels;k++) {
        if ((patterns[k].variations[i][j]<bestvariation)) {
          bestlevel=k; 
          bestvariation=patterns[k].variations[i][j];
        }
      }

      ///////////////////////////  this is a part I changed    
      dist = dist(centerX, centerY, i, j);
      if (dist < oR && dist > iR) {  

        if (patterns[bestlevel].activator[i][j]>patterns[bestlevel].inhibitor[i][j]) {
          grid[i][j]+=patterns[bestlevel].stepsize;
        }
      }
      else {
        grid[i][j]+=(patterns[bestlevel].stepsize);
      }
      largest=max(largest, grid[i][j]);
      smallest=min(smallest, grid[i][j]);
    }
  }

  float range=0.5*(largest-smallest);
  for (int i=0;i<num;i++) {
    for (int j=0;j<num;j++) {
      grid[i][j]=(grid[i][j]-smallest)/range-1;  
    }
  }
}

I guess I need to look into the TuringPattern class to change the behavior of the pattern, right?

Every hint is highly appreciated.

Tagged:

Answers

  • Answer ✓

    My hint would be to comment out the activator blur in the TuringPattern class' diffuse() method. Then you will notice that the horizontal/vertical pattern is mainly caused by the inhibitor blur. Then notice that the blur() method relies on a hor & vrt lineblur methods. Try to understand one of these. Then you might look into a radial blur algorithm and see what happens when you use that instead of the horizontal and vertical blur. Please -for future generations- post the final code here, once you made it.

  • Hey amnon, thank you very much for this very useful hints.

    I most definitely going to post the code... if I succeed.

  • hi @jamone were you able to implement the horizontal version ? I am trying to do the same thing but I couldn't yet.

Sign In or Register to comment.