L'affascinante mondo dei frattali
 

Quanto è lunga la costa della Sardegna?  La domanda può sembrare banale ma la risposta, se non avete mai sentito parlare dei frattali, vi sorprenderà: la sua lunghezza è infinita!  Come si può arrivare a giustificare una simile affermazione?  Beh, diciamo subito che si tratta solo di una estrapolazione matematica, tuttavia il risultato lascia senza parole.  Proverò a spiegarlo gradualmente iniziando con un esempio.
 

Un fiocco di neve frattale
 

La figura a lato mostra come generare il cosiddetto fiocco di neve di von Koch: si prende un segmento (fig. 1a), lo si taglia in 3 parti e si sostituisce quella centrale con due segmentini uguali a quello eliminato (fig. 1b); ora si ripete l'operazione con ciascuno dei quattro segmenti così ottenuti (fig. 1c) e si continua a ripeterla per un numero infinito di volte.  La curva che si ottiene dopo un numero infinito di iterazioni è una curva frattale e come tutte le curve frattali è dotata di affascinanti proprietà matematiche, facili da intuire ma, spesso, difficili da dimostrare.

Se il nome "fiocco di neve" vi sembra poco appropriato per la curva di fig. 1, forse cambierete idea osservando ciò che si ottiene applicando il procedimento appena descritto ai lati di un triangolo.

Curva a fiocco di neve 
Fig. 1 - Curva a fiocco di neve
 
Fiocco di neve di von Koch
Fig. 2 - Fiocco di neve di von Koch

 
Frattale, cioè frammentato e irregolare

Dare una definizione soddisfacente di questi stranissimi enti matematici non è affatto facile: non ci è riuscito nemmeno il loro scopritore!  In prima approssimazione possiamo affermare che una curva si dice frattale se ha la proprietà dell'autosimilitudine: ingrandendo un qualsiasi tratto di curva si visualizza un insieme di particolari altrettanto ricco e complesso del precedente; questo procedimento di "zoom" può proseguire all'infinito.  Da ciò derivano due curiose caratteristiche delle curve frattali:

Quest'ultimo fatto lo possiamo facilmente verificare per il fiocco di neve appena visto.  Ad ogni iterazione la lunghezza della curva cresce di un fattore 4/3: se il segmento di partenza ha lunghezza pari a 1, il secondo misura 4/3, il terzo 16/9, il quarto 64/27 e così via.  Questa successione è chiaramente divergente, cioè tende ad assumere un valore infinito.  Ma non è tutto: ogni pezzo del fiocco di neve, anche piccolissimo, gode della proprietà dell'autosimilitudine cioè contiene in sé un'infinita ricchezza di particolari, di minuscoli fiocchi di neve, e quindi anch'esso è di lunghezza infinita.
 

Circondati dai frattali!

Torniamo ora alla nostra domanda iniziale: quanto è lunga la costa della Sardegna?  Ebbene, la risposta dipende dalla scala alla quale viene fatta la misurazione: una valutazione sommaria fornisce un risultato relativamente basso che però cresce a dismisura se si inizia a prendere in considerazione ogni più piccolo promontorio, ogni anfratto, ogni scoglio, ogni granello di sabbia.  Insomma un tratto di costa può essere visto come un tratto di curva frattale.
In realtà i frattali sono in grado di rappresentare egregiamente una gran varietà di oggetti e fenomeni della Natura: non solo un tratto di costa ma anche i rami o le radici di un albero, una nuvola, le ramificazioni di un fulmine e la dentellatura di una foglia ne sono alcuni esempi.

Un rametto di felce frattale Un rametto di felce frattale in 3D
Figg. 3 e 4 - Rametti di felce frattale

 
L'insieme di Mandelbrot

L'insieme di Mandelbrot (d'ora in poi indicato con M) è un luogo geometrico del piano complesso; più precisamente è l'insieme dei punti di tale piano che soddisfano la legge di Mandelbrot:

Un punto c del piano complesso appartiene all'insieme se la successione definita ricorsivamente dalla formula
z(n+1) = z(n)*z(n) + c
con z(0) = 0
non diverge.
Cosa ha di speciale questo insieme?  E' presto detto: la sua frontiera (cioè il suo perimetro) è una curva frattale, uno dei frattali più complessi che si conoscano.

L'insieme di Mandelbrot (vista complessiva) L'insieme di Mandelbrot (dettaglio) L'insieme di Mandelbrot (dettaglio piccolissimo)
Fig. 5 - L'insieme di Mandelbrot Figg. 6 e 7 - Dettagli dell'insieme di Mandelbrot

La figura 5 mostra M nella sua interezza: i punti dell'insieme sono quelli di colore nero all'interno della grossa cardioide mentre gli altri colori sono usati per indicare le diverse velocità con cui la successione diverge, come spiegato più avanti.  Grazie alla proprietà dell'autosimilitudine, la frontiera di M si presta ad una interminabile e sorprendente esplorazione (figg. 6 e 7).  Nel caso del fiocco di neve, zoomando su un piccolo tratto di curva si visualizza una nuova curva uguale a quella di partenza; con M, invece, le cose sono un po' diverse: la proprietà dell'autosimilitudine vale in senso lato, infatti la frontiera di M è disseminata di un'infinità di minuscole cardioidi somiglianti ma non uguali a quella di partenza e le immagini che si possono ottenere sono infinitamente varie.  La principale differenza tra la grossa cardioide di fig. 5 e quelle minuscole che la circondano sta nei sottili filamenti che uniscono queste ultime al corpo principale dell'insieme.  I filamenti, simili a fulmini (fig. 7), sono interamente costituiti da punti appartenenti ad M ed infatti è possibile dimostrare che M è un insieme connesso.
 

Un insieme di Mandelbrot fatto in casa

Prima di spingerci oltre nell'esplorazione di M, cerchiamo di capire meglio come si ottengono questi disegni.  Vi sembrerà strano, ma è possibile generarli con un programma di poche righe!
Iniziamo ricordando qualche formula matematica (chiedo venia):

Associamo ad ogni pixel un punto del piano complesso e determiniamo se esso appartiene all'insieme: in caso affermativo lo coloriamo in bianco, altrimenti in nero.  Abbiamo così ottenuto una rappresentazione in 2 colori dell'insieme.  Per rendere la cosa più gradevole dal punto di vista estetico, e per meglio comprendere il comportamento dei vari punti del piano rispetto alla legge di Mandelbrot, conviene usare più colori.  Si può allora decidere di indicare con colori diversi la velocità con cui la successione diverge: ad esempio, si colorano in blu i punti in cui la successione diverge alla prima iterazione, in verde quelli in cui diverge alla seconda, ecc.  Ma come si fa a stabilire se la successione diverge o no?  Guardiamo più attentamente la legge di Mandelbrot:

  z(n+1) = z(n)*z(n) + c  

In essa compare il quadrato di z.  Ebbene, secondo una proprietà dei numeri complessi, se un numero z ha modulo >=2, il suo quadrato avrà modulo ancora maggiore e quindi la successione sarà divergente.  Se invece la successione, dopo un certo numero massimo di iterazioni, non accenna a divergere, si dà per scontato che non divergerà mai, e si accetta il punto che la origina come membro dell'insieme.  La cosa non è corretta dal punto di vista teorico, ma, se il numero di iterazioni è abbastanza alto, la probabilità di commettere errori di attribuzione è ragionevolmente limitata.
Per quanto detto finora, l'algoritmo opera nel seguente modo: viene calcolato ripetutamente il valore di z mediante la formula sopra indicata, e, ogni volta, il modulo di z viene confrontato col valore 2.  Il procedimento si arresta quando la successione mostra di essere divergente (mod(z)>=2) oppure quando si giunge al numero massimo di iterazioni.  Infine viene attribuito il colore opportuno al pixel corrispondente al punto c considerato e si passa al punto, e al pixel, successivi.
Quanto appena detto è alla base delle poche righe di codice in linguaggio C, Pascal e QBasic che ho approntato.
Per velocizzare l'elaborazione ho adottato due semplici ma importanti accorgimenti.  Il primo è nella condizione di uscita del ciclo WHILE che applica iterativamente la legge di Mandelbrot: il numero complesso in esame (e cioè il modulo del valore corrente di z, pari a sqrt(a*a+b*b)) viene confrontato senza la radice con il valore 4 (anziché 2), risparmiando alla macchina l'inutile e dispendiosa operazione di radice.  Il secondo accorgimento si basa sulla constatazione che, per colorare un pixel appartenente all'insieme, è necessario un numero di calcoli molto maggiore che per gli altri pixel in quanto il ciclo WHILE viene eseguito MAXCONT volte (dove MAXCONT è il numero massimo di iterazioni prefissato).  Ho pensato, quindi, di individuare (per via empirica) un rettangolo di piano complesso tutto appartenente all'insieme: in questo modo è possibile evitare l'esecuzione del ciclo per tutti i pixel di questo rettangolo, che verranno immediatamente attribuiti all'insieme senza ulteriori calcoli.  L'istruzione IF..THEN posta subito prima del WHILE si occupa proprio di questo.
Per velocizzare ulteriormente il programma si potrebbe sfruttare la simmetria dell'insieme rispetto all'asse delle ascisse, ma ho preferito non seguire questa strada per non appesantire eccessivamente il listato.  In alternativa si potrebbe ridurre ulteriormente il valore della costante MAXCONT, ma questo andrebbe a scapito della precisione del disegno (il valore attuale è già molto basso).
Per "zoomare" su un particolare della figura basta modificare le costanti INFX, SUPX, INFY, SUPY e rilanciare il programma; queste costanti, infatti, definiscono il rettangolo di piano che deve essere visualizzato sullo schermo (sono le coordinate del primo e del quarto vertice).  Se i valori attribuiti a tali costanti sono tali che INFX>SUPX si ottiene un'immagine ribaltata attorno all'asse delle ordinate.  La capacità di ingrandimento del programma è limitata unicamente dalla precisione del tipo di dato in virgola mobile utilizzato.
 

Fractint

I programmini che ho realizzato sono soltanto degli esempi: per le vostre esplorazioni vi raccomando l'ottimo programma freeware Fractint che può essere certamente considerato il programma DEFINITIVO sui frattali.  I suoi maggiori pregi sono:

Tutte le immagini presenti in questa pagina sono state create con Fractint.  I file GIF creati da Fractint hanno una importante caratteristica: oltre alla bitmap contengono al loro interno alcune informazioni che Fractint stesso è in grado di riutilizzare; queste informazioni sono etichettate come Application Data Block nel pieno rispetto dello standard GIF89a, uno standard estremamente versatile.  I programmi diversi da Fractint (compreso il vostro browser) ignorano i data block di altre applicazioni e visualizzano l'immagine senza problemi.  Provate a caricare una di queste immagini in Fractint e noterete che il programma si riporta automaticamente nello stato in cui si trovava quando l'immagine è stata creata: tutti i parametri che controllano l'aspetto dell'immagine vengono reimpostati e quindi è possibile riprendere l'esplorazione dal punto esatto in cui era stata interrotta.
Le GIF di questa pagina si trovano ora nella cache del browser.  Se non volete perdere tempo a cercarle, potete facilmente salvarle in una directory a piacere: cliccate su ciascuna di esse col tasto destro del mouse e scegliete l'opzione Salva con nome o Save as.
Qui di seguito vi propongo qualche altro esempio di ciò che si nasconde lungo la frontiera di M.
 
Particolare dell'insieme di Mandelbrot Particolare dell'insieme di Mandelbrot
Figg. 8 e 9 - Particolari dell'insieme di Mandelbrot

Volete sapere quali sono le coordinate della porzione di piano visualizzata in fig. 8?  Basta caricare l'immagine in Fractint (tasto R) e premere Tab.  Volete vedere in quale punto di M si trovano queste coordinate?  Basta zoomare all'indietro (tasti Page Up e Ctrl-Enter) fino a visualizzare l'intera cardioide: il punto che apparirà al centro dello schermo sarà quello che sono andato ad esplorare.  Volete aumentare la risoluzione per vedere meglio l'immagine?  Basta premere il tasto Del e scegliere uno dei tanti modi video supportati: l'immagine verrà ricalcolata al volo (non si tratta di un semplice ingrandimento della bitmap).  Le immagini di questa pagina sono state create in modalità preview così da poterne regolare la risoluzione a piacere; il preview può essere disattivato dal menu Preview Options (tasto V).

Quando si esplora un particolare di M in profondità è importante regolare opportunamente il valore del numero massimo di iterazioni (quello che nei programmini dimostrativi era chiamato MAXCONT).  Le figure seguenti mostrano chiaramente l'effetto di un valore limite troppo basso.
 

Un buco nero inesistente Rappresentazione corretta dell'immagine precedente
Figg. 10 e 11 - Effetto di un numero massimo di iterazioni insufficiente

Dalla fig. 10 si ha l'impressione di aver trovato un sottoinsieme di M di forma approssimativamente circolare ma in realtà questo "buco nero" non esiste: nei punti di colore nero la successione diverge dopo un numero di iterazioni maggiore di quello fissato e quindi questi punti vengono erroneamente attribuiti ad M; è sufficiente raddoppiare il limite (da 1500 a 3000) per rendersi conto di come stanno realmente le cose (fig. 11).  Per evitare di prendere abbagli bisogna ricordarsi di aumentare progressivamente il numero limite di iterazioni al crescere del fattore di zoom.  Nel farlo, però, bisogna anche tenere presente che un limite troppo alto rallenta la generazione delle immagini, in particolare di quelle che contengono molti punti appartenenti ad M.  Nei piccoli sorgenti visti prima ho privilegiato la velocità a scapito della precisione ponendo MAXCONT=61: si tratta di un valore appena accettabile per ottenere una vista complessiva di M ma risulta del tutto insufficiente non appena si inizia a zoomare.
In Fractint il numero limite di iterazioni può essere modificato dal menu Basic Options (tasto X).

Come è facile immaginare, la scelta della palette (la tavolozza dei colori) è determinante per la resa estetica dell'immagine; per questo motivo Fractint fornisce numerose palette già pronte (ce ne sono anche alcune ottimizzate per l'uso con occhiali stereoscopici!).  Le figg. 6 e 7 usano la palette BLUE.MAP mentre la 8 e la 9 usano VOLCANO.MAP.  E' possibile applicare una nuova palette ad una immagine premendo C e poi L.
La scelta di una buona palette, tuttavia, non è sufficiente a garantire un buon risultato.  Le due immagini seguenti mostrano uno stesso particolare di M e usano la stessa palette (BLUE.MAP), ciò che cambia è il modo in cui i colori della palette vengono assegnati ai pixel.
 

Metodo lineare Metodo logaritmico
Figg. 12 e 13 - Differenza tra palette lineare e logaritmica

Nel primo caso ho utilizzato il criterio predefinito: l'assegnazione lineare 1:1.  Questo criterio assegna a ciascun pixel il colore N, dove N è il numero di iterazioni effettuate; se N è maggiore del numero di colori disponibili si ricomincia a contare dal colore 0.  Il criterio lineare dà buoni risultati con immagini poco ingrandite ma diventa subito inadeguato al crescere del fattore di ingrandimento e del numero massimo di iterazioni.
Per la figura di destra, invece, ho usato il criterio logaritmico ottenendo un migliore contrasto.  E' possibile scegliere il criterio di assegnazione dal menu Basic Options (tasto X).
Immagine adatta al color cycling
Fig. 14 - Immagine adatta al color cycling

Un'altra interessante funzione riguardante la palette è il color cycling ovvero una rotazione continua dei colori che in alcuni casi (immagini dalla forma spiraleggiante) ha degli effetti quasi ipnotici.  Il color cycling si attiva con il tasto C seguito da "+" o "-" per scegliere il verso della rotazione; è anche possibile modificarne la velocità con i tasti Up e Down.  Provatelo con l'immagine di fig. 14 che usa la palette CHROMA.MAP.

L'eseguibile FRACTINT.EXE, di grosse dimensioni, presenta al suo interno un ricco manuale consultabile a run-time; è anche possibile estrarre il manuale ed ottenere così un testo pronto per la stampa: basta lanciare il programma con il parametro MAKEDOC.  La lettura del manuale vi permetterà di apprendere tutte le altre interessanti funzionalità del programma (ad esempio la possibilità di creare stereogrammi) e di sfruttarlo al meglio per esplorare M e tutti gli altri frattali disponibili.  Buon viaggio!  ;-)
 

Per saperne di più

In biblioteca

In rete



Terza edizione, 31 marzo 1999
Copyright © 1998-1999 Pino Navato
 
Vai alla mia home page