Petit hommage à Benoit Mandelbrot

Publié le 11 Novembre 2010

Benoit Mandelbrot n'est plus, mais les fractales, elles, sont toujours là, et pour longtemps. Et depuis longtemps aussi d'ailleurs. En hommage à ce grand Môssieur de l'imagerie mathématique, voici une petite série de fractales obtenues avec Processing avec une des méthodes les plus simples qui soit (que J... avait déjà programmé il y a vingt ans sur un Amiga, soit dit en passant).

 

La méthode est simple, placez un point dans le plan et appliquez à ses coordonnées une transformation géométrique: une rotation, une translation ou une homothétie. Tracez le point à ses nouvelles coordonnées et recommencez: appliquez à nouveau une de ces transformations et retracez. Recommencez ainsi de suite des millions de fois en alternant ces différentes transformations et vous avez de bonnes chances d'obtenir une fractale, plus ou moins déformée, plus ou moins connexe ou poussière. Voici quelques exemples:

 

fractal1-184-1

fractal1-284-1

fractal1-355-1

fractal1-649-1

fractal1-694-1

fractal1-700-1

fractal1-811-1

fractal1-833-1

fractal1-872-1

fractal1-910-1

fractal1-911-1

fractal1-983-1

 

Et pour ceux que cela intéresse, voici le code.

 

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, xcentre, ycentre;
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);
 
  x=int(random(sx));
  y=int(random(sy));
 
  xcentre=3*sx/5;//+vx/2;
  ycentre=3*sy/5;//+vy/2;
 
  h=50;
  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.3) {
      xnew=sx/2+ratio*(x-sx/2); ynew=sy/2+(y-sy/2)*ratio;
      h=constrain(h+10,0,100);
    } else if (test>0.7) {
      xnew=xcentre+(x-xcentre)*ratio*cos(theta)-(y-ycentre)*ratio*sin(theta);
      ynew=ycentre+(y-ycentre)*ratio*cos(theta)+(x-xcentre)*ratio*sin(theta);
      h=constrain(h-7,0,100);
    } else {
      xnew=100+(x-100)*cos(theta)-(y-100)*sin(theta);
      ynew=100+(y+100)*cos(theta)+(x-100)*sin(theta);
      h=constrain(h-8,0,100);
    }
   
    if (x>0 && x<sx-1 && y>0 && y<sy-1){
      xint=int(x)+1;
      yint=int(y)+1;
      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
 
  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("fractal1-" + numsequence + "-" + numeroimage + ".jpg");
    println("PHOTO "+ numsequence + " - " +  + numeroimage );
    numeroimage=numeroimage+1;
}

Rédigé par J...

Publié dans #logiciels de création

Commenter cet article