We are about to switch to a new forum software. Until then we have removed the registration on this forum.
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:
Later render step:
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.
Answers
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.