Staross — 2007-09-29 15:55:58

Une fonction récursive très classique qui dessine de petits arbres.
En programmation, une fonction récursive est simplement une fonction  qui s'apelle elle-même :

mafonction()
{
  mafonction()
}

Cette fonction à un problème car elle va s'appeller elle-même à l'infini !
On doit toujours mettre ce qu'on appelle une condition d'arret, qui permet d'arreter la récursion au bout d'un moment, par exemple :

mafonction(int nb)
{
  if(nb > 0)
     mafonction(nb-1)
}

Le nombre nb va diminuer au cours des appelles et la fonction va arreter de s'appeller elle même quand nb = 0.

Enfin bref !

import processing.opengl.*;

void setup() 
{
  size(800, 600,OPENGL); 
  smooth();
  colorMode(RGB, 255, 255, 255, 100);
  rectMode(CENTER);
}

void draw() 
{   
  background(0); 
  drawline(300, 300, 30. + mouseY/100., mouseX/10, 8);
}

void drawline(
              int x, //coordonnées du départ de la branche
              int y,
              float angle, //angle de départ
              int len, //longeur de la branche
              int nb //nombre d'embranchements
              )
{
  if(nb > 0) //condition d'arret
  {
    float dev=0.25; //deviation angulaire à chaque branche
    
    int nx = int(x+cos(angle)*len); //un peu de trigo.
    int ny = int(y+sin(angle)*len);

    stroke(nb*10, nb*10, nb*10, 120); //les lignes deviennent plus foncé à chaque branche
    fill(30*(-nb+10), 30*(-nb+10), 30*(-nb+10)); //les surfaces deviennent plus clairs à chaque branche
    
    //dessine
    line(x,y,nx,ny); 
    ellipse(x,y,nb+4,nb+4);
    //appelle les branches suivantes
    drawline(nx,ny,angle-dev-len/100.,len-2,nb-1);
    drawline(nx,ny,angle+dev+len/100.,len-2,nb-1);
  }
}

http://codelab.fr/up/arbre1.gif

http://codelab.fr/up/arbre2.gif

tobald — 2007-09-30 00:23:47

http://www.dandelioncollective.org/Dandelionimages/dandelion-stock2.jpg

Staross — 2007-09-30 15:40:21

Le même genre mais avec des angles aléatoires mutliples de pi.

import processing.opengl.*;
int sizex = 1024;
int sizey = 768;
float pi = 3.14159265;
float phi = 1.61803399;

void setup() 
{
  size(sizex, sizey,OPENGL); 
  smooth();
  colorMode(RGB, 255, 255, 255, 100);
  noLoop();
  noStroke();
}

void draw() 
{
  background(255);

   form(sizex/2,sizey/2,int(random(5,12)),int(random(5,100)),0);
}

void form(int x, int y, int nb, int len, float angle)
{
  if(nb > 0 && len > 0)
  {
    angle = pi/2*int(random(-4,4)); 
    println(len);

    int nx =  int (x+ len*cos(angle) );
    int ny =  int (y+ len*sin(angle) );

    stroke(10+15*nb,8*nb,angle*10,len);
    line(x+random(-2,2),y+random(-2,2),nx+random(-2,2),ny+random(-2,2));
    stroke(10+15*nb,8*nb,angle*10,len+10);
    line(x+random(-2,2),y+random(-2,2),nx+random(-2,2),ny+random(-2,2));
    stroke(10+15*nb,8*nb,angle*10,len+50);
    line(x,y,nx,ny);

    form(nx,ny,nb-1,len-6,angle);
    form(nx,ny,nb-1,len-10,angle);
  }
  else
  {
    stroke(10+15*nb, 8*nb, angle*10, 20);
    ellipse(x,y,2,2);
  }

}

void mousePressed() 
{
  redraw();
}

http://codelab.fr/up/arbre04.jpg

http://codelab.fr/up/arbre03.jpg

http://codelab.fr/up/arbre02.jpg

http://codelab.fr/up/arbre00.jpg

dUX — 2007-10-01 01:04:13

Génial !
Va falloir que je me penche là dessus.

tobald — 2007-10-01 21:06:44

hello dux, ça faisait un petit moment ...

Esthétiquement parlant , le rendu me plait bien.
Par contre j'ai vraiment pas le courage de me plonger dans processing pour l'instant  :zsad:

http://codelab.fr/up/arbre1.gif

comment se fait il que la "chaine"  commence par un point créant 1 point et non 2 comme par la suite.

Staross — 2007-10-01 21:34:37

Bonne remarque, c'est parce que dans la fonction draw (qui est appellé par le programme automatiquement), j'appelle une seule fois ma fonction
drawline(x,y,...). Elle va dessiner le premier trait de x,y (l'origine) à nx,ny (le point suivant) (line(x,y,nx,ny);) et le cercle au point x,y (ellipse(x,y,nb+4,nb+4);).
Ensuite seulement j'appelle deux fois la fonction drawline() avec deux angles différents, et là ça se sépare en deux. Si on appellait trois fois drawline ça ferait trois branches sur chaque noeud.

En fait c'est un peu odiot de dessiner le cercle sur le noeud d'origine (x,y) parce que les dernières branches n'ont pas de feuilles !

osc — 2007-10-03 10:50:02

Les arbres récursifs sont assez courant, mais c'est tellement puissant.
ya Robert Penner et son Danseur Fractal -> http://www.robertpenner.com/index2.html
ou encore Jared Tarbell et son Tree Garden -> http://complexification.net/gallery/mac … reeGarden/
J'adore celui de Jared  :zjoy:

Là c'est du Flash mais ça revient au même.