Un albero che cresce

Disegnato dalla stessa funzione ricorsiva che genera un albero intero in una volta sola, con in più una variabile che dice fino a che punto è cresciuto. Ogni ramo si allunga a mano a mano che la crescita aumenta, e quando ha raggiunto la sua lunghezza ne spuntano altri due.

Tenere premuto il tasto del mouse sul canvas per far crescere l’albero.

    let crescita = 0.5;   // livelli cresciuti finora, da 0 a 7

function disegnaRamo( x, y, angolo, livello ) {
    let parte = constrain( crescita - livello, 0, 1 );   // da 0 a 1
    let lunghezza = pow( 0.6, livello ) * 130 * parte;
    let x2 = x + cos( angolo ) * lunghezza;
    let y2 = y + sin( angolo ) * lunghezza;
    line( x, y, x2, y2 );

    livello++;
    if (livello < 7 && livello < crescita) {
        disegnaRamo( x2, y2, angolo + 0.75, livello );
        disegnaRamo( x2, y2, angolo - 0.75, livello );
    }
}

function setup() {
    createCanvas( 670, 320 );
}

function draw() {
    background( 255 );
    if (mouseIsPressed) {
        crescita = min( crescita + 0.02, 7 );
    }
    disegnaRamo( width/2, height, PI*1.5, 0 );
}
  

Algoritmo

a ogni fotogramma:                                                draw()
    se il mouse è premuto, aumentare la crescita, fino a 7        min()
    disegnare il tronco                                           disegnaRamo()

per disegnare un ramo di un livello:                              disegnaRamo()
    calcolare quanto è cresciuto, da 0 a 1                        constrain()
    disegnarlo, lungo quanto è cresciuto                          line()
    se la crescita ha raggiunto il livello successivo:            if()
        disegnare i due rami del livello successivo

Istruzioni


  

Ogni livello cresce da 0 a 1 mentre la crescita passa dal suo numero al successivo: il livello 2, per esempio, fra 2 e 3. Con una crescita di 2.5 il tronco (livello 0) e i rami del livello 1 sono interi, perché la differenza supera 1, quelli del livello 2 sono a metà, quelli dei livelli successivi non ci sono ancora. constrain() tiene il valore fra 0 e 1.


  

I due rami del livello successivo si disegnano solo se la crescita lo ha raggiunto, cioè quando il ramo attuale è intero. Senza questa condizione la ricorsione disegnerebbe ogni volta tutti i rami, anche quelli ancora lunghi zero.

Variazioni

Con angolo + 0.75 + sin( frameCount * 0.02 ) * 0.05 al posto di angolo + 0.75 l’albero ondeggia come mosso dal vento, e ogni ramo trascina con sé quelli che porta.

Con strokeWeight( 7 - livello ) prima di line() lo spessore dei rami diminuisce a ogni livello, dal tronco alle punte.