Nell’ultimo post abbiamo analizzato la differenza tra la funzione random()noise(). La prima, vi ricordo, restituisce dei valori assolutamente casuali che dipendono dai parametri che passiamo alla funzione; la seconda, invece, ci permette di avere una sorta di casualità controllata.

I valori che vengono restituiti dalla funzione noise() hanno due caratteristiche fondamentali: sono correlati tra loro e hanno sempre un valore compreso tra 0 e 1.

Maggiore sarà la vicinanza tra i parametri che passiamo alla funzione, maggiore sarà, ovviamente, la correlazione tra i valori restituiti in output. È possibile verificare quanto ho appena detto utilizzando un paio di righe di codice:

println(noise(100));
println(noise(100.01));

Questo il risultato visualizzato in console:

0.3187103
0.318551

I risultati sono davvero molto vicini tra loro. Proviamo ad aumentare la distanza tra i due valori:

println(noise(100));
println(noise(101));

Ora la correlazione tra i due output è meno evidente:

0.56860673
0.48344862

Aumentando ulterioremente la distanza tra i parametri di input, avremo risultati in output sempre più simili a quelli ottenuti dalla funzione random():

println("Noise:");
println(noise(100));
println(noise(500));
println("Random:");
println(random(1));
println(random(1));

Può generare risultati simili a questo:

Noise:
0.16914257
0.68422705
Random:
0.48342746
0.89731866

Creare un grafico di valori restituiti da noise()

Il primo esempio che voglio realizzare oggi è un grafico che mi rappresenti, per valori di x crescenti, un valore y restituito da noise().

Ecco il codice:

/*
 * Noise examples 1
 * by Federico Pepe
*/

float xoff = 0;
float increment = 0.02;

void setup() {
  size(500, 500);
  background(255);
  noFill();
  noLoop();
}

void draw() {
  beginShape();
  for(int x = 0; x <= width; x++) {
    stroke(0);
    vertex(x, noise(xoff)*height);
    xoff += increment;
  }
  endShape();
}

Analizziamo velocemente il codice riportato qui sopra: per prima cosa creo le variabile di tipo float xoff e increment, dopodiché all'interno di setup() imposto la grandezza della finestra, il colore di sfondo, imposto che non ci sia nessun colore di riempimento, con noFill(), e che il programma non vada in loo  una volta avviato, con noLoop().

In draw() utilizzo una funzione che non abbiamo ancora visto: beginShape(). Questa funzione dice a Processing che vogliamo disegnare una forma complessa che avrà un'insieme di vertici – aggiunti con la funzione vertex() – che dovranno essere uniti in ordine gli uni agli altri finché non chiuderemo la forma con endShape().

Perché ho deciso di usare questa funzione? Perché così, estraendo per valori di x crescenti dei valori y generati dalla funzione noise(), tutti i punti saranno già collegati tra loro e genereranno un grafico come quello rappresentato qui sotto:

Grafico della funzione noise

Animiamo il grafico

/*
 * Noise example 2
 * by Federico Pepe
*/

float xoff;
float increment = 0.015;
float startPoint;

void setup() {
  size(500, 500);
  background(255);
  noFill();
}

void draw() {
  background(255);
  xoff = startPoint;
  beginShape();
  for(int x = 0; x <= width; x++) {
    stroke(0);
    vertex(x, noise(xoff)*height);
    xoff += increment;
  }
  endShape();
  startPoint += increment;
}

Con una veloce modifica al codice è possibile animare il grafico: per prima cosa eliminiamo il noLoop() e aggiungiamo una variabile per stabilire di volta in volta quale sarà il nostro punto di inizio: startPoint. Ovviamente, al termine del loop, dobbiamo incrementare quest'ultima variabile in modo da avere lo scorrimento orizzontale.

Ecco il risultato (in formato gif):

Grafico noise animato

Unisciti alla discussione

4 commenti

  1. scusa non ho capito come si ottiene il movimento orizzontale, se x a ogni ciclo for si azzera perché non si ricomincia dal margine a sinistra?

    1. Ciao Daniele! Con la tua domanda mi sono reso conto che, forse, non ho spiegato in modo esaustivo l’esempio che ho riportato nel post. In quello sketch non è la variabile x che dà il senso del movimento: a ogni ciclo for viene disegnata l’intera linea sullo schermo (come nell’esempio non animato più sopra).

      Quando il valore di x è uguale alla larghezza della finestra – quindi al termine del ciclo for – , si riparte dall’inizio del ciclo di draw e la linea viene ridisegnata ma, a questo punto, viene incrementata la variabile startPoint (startPoint += increment;) e viene tutto spostato leggermente verso sinistra perché, all’inizio del draw, alla variabile xoff viene riassegnato il valore di startPoint ( xoff = startPoint;).

      In poche parole, il senso dell’animazione è dato da una specie di illusione ottica (dovuta all’elevato numero di frame) perché la linea viene costantemente ridisegnata a schermo leggermente spostata rispetto a prima.

      Spero di essere stato chiaro ma se ti rimangono ancora dei dubbi, scrivimi pure!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.