Fractales générées par double rotation homothétique

Publié le 11 Novembre 2010

Le petit hommage à Benoit Mandelbrot risque en fait de durer un peu plus longtemps que prévu. Puisqu'avec Processing, une idée en amène facilement une autre, voici la question à laquelle on tente de répondre ici: à quoi ressemblent les attracteurs étranges d'une transformation consistant à appliquer la même rotation homothétique alternativement centrée sur deux points distincts ?

 

Gniaa ! Kek ça veut dire ?

 

Soient deux points A et B du plan. Définissons une rotation homothétique d'angle theta et de rapport alpha (alpha<1). Prenons un point quelconque du plan, traçons le. Calculons l'image de ce point par la rotation homothétique centrée sur A, traçons le nouveau point. Faisons pareil en centrant la rotation sur B, et traçons le nouveau point. Recommençons sur A, puis sur B, et ainsi de suite, des millions de fois. Traçons chacun des points et regardons le résultat: Ho mon dieu ! Des fractales... Comme c'est bizarre !

 

fractale par double rotation-17 1

fractale par double rotation-207 1

fractale par double rotation-216 1

fractale par double rotation-437 1

fractale par double rotation-462 1

fractale par double rotation-538 1

fractale par double rotation-659 1

fractale par double rotation-729 1

fractale par double rotation-914 1

fractale par double rotation-921 1

fractale par double rotation-958 1

fractale par double rotation-992 1

 

Et pour ceux qui voudraient jouer avec, voici le code Processing pour s'amuser:

 

int sx, sy, ii, npts, xint, yint, nmax, nmoy, numsequence, numeroimage;
float h, s, b, test;
float ratio, theta, x, y, vx,vy, xnew, ynew, xcentre1, ycentre1, xcentre2, ycentre2;
float rmin, rmax, tmin, tmax, vxmin, vxmax, vymin, vymax;
float[][][] nhsv;

void setup(){
  sx=600;
  sy=400;
  size(sx,sy);  
  nhsv = new float[sx][sy][4];
 
  npts=1000000;
 
  colorMode(HSB,100);
 
  rmin=0.01;
  rmax=0.99;
  tmin=2*PI/360*0;
  tmax=2*PI/360*360;
  vxmin=-1*sx/2;
  vxmax=1*sx/2;
  vymin=-1*sy/2;
  vymax=1*sy/2;
 
  ratio=random(rmin,rmax);
  theta=random(tmin,tmax);
 
  vx=random(vxmin,vxmax);
  vy=random(vymin,vymax);
 
  xcentre1=0.35*sx;
  ycentre1=0.5*sy;
  xcentre2=0.65*sx;
  ycentre2=0.5*sy;
 
  println("vx " + vx + "------- vy " + vy);
 
  x=xcentre1;
  x=xcentre2;
 
  h=10;
  s=70;
  b=100;
 
  stroke(h, s, b,10);
   
  background(0,0,0);
  numeroimage=1;
  numsequence=int(random(1,1000));
}

void draw(){
 
  for (int ii = 0; ii < npts; ii=ii+1) {
    test=random(1);
   
    if (test<0.5) {
      xnew=xcentre1+(x-xcentre1)*ratio*cos(theta)-(y-ycentre1)*ratio*sin(theta);
      ynew=ycentre1+(y-ycentre1)*ratio*cos(theta)+(x-xcentre1)*ratio*sin(theta);
      h=constrain(h-18-random(4),0,100);
    } else {
      xnew=xcentre2+(x-xcentre2)*ratio*cos(theta)-(y-ycentre2)*ratio*sin(theta);
      ynew=ycentre2+(y-ycentre2)*ratio*cos(theta)+(x-xcentre2)*ratio*sin(theta);
      h=constrain(h+18+random(4),0,100);
    }
   
    if (x>0 && x<sx-1 && y>0 && y<sy-1){
      xint=int(x); yint=int(y);
      nhsv[xint][yint][1]=(nhsv[xint][yint][0]*nhsv[xint][yint][1]+h)/(nhsv[xint][yint][0]+1); // on recalcule la composante h moyenne
      nhsv[xint][yint][0]=nhsv[xint][yint][0]+1; //on compte ce point supoplémentaire à cette position.
    }
   
    x=xnew;
    y=ynew;
  } // fin du for
 
  // on retrace l'image à partir de la matrice nhsv
 
  for (int i = 1; i < sx-2; i=i+1) {
    for (int j = 1; j < sy-2; j=j+1) { 
      nhsv[i][j][1] = (20*nhsv[i][j][1] + nhsv[i+1][j][1] + nhsv[i-1][j][1] + nhsv[i][j-1][1] + nhsv[i][j+1][1] )/24; 
    }
  }
 
  nmax=0; // d'abord on balaie tout pour trouver le mex d'intensité
  for (int i = 0; i < sx-1; i=i+1) {
    for (int j = 0; j < sy-1; j=j+1) { 
      if (nhsv[i][j][0] > nmax) { nmax=int(nhsv[i][j][0]); }
    }
  }
 
  // en fonction du max, on met la valeur v à 0 ou 100 proportionnellement
  for (int i = 0; i < sx-1; i=i+1) {
    for (int j = 0; j < sy-1; j=j+1) { 
      nhsv[i][j][3] = constrain(10*(12+log(nhsv[i][j][0]/nmax)),0,100);
      stroke(nhsv[i][j][1], s, nhsv[i][j][3]);
      point(i,j);
    }
  }
} // fin du draw

void mousePressed() {
  saveFrame("fractale_par_double_rotation-" + numsequence + "_" + numeroimage + ".jpg");
    println("PHOTO "+ numsequence + " - " +  + numeroimage );
    numeroimage=numeroimage+1;
}

Rédigé par J...

Publié dans #logiciels de création

Commenter cet article