-
.
Il codice del tappeto di Sierpinsky è il seguente:
Evento on-Click del pulsante disegnaCODICEprocedure TForm1.DisegnaClick(Sender: TObject);
var Rango: integer ;
Var Lato: Double;
Var x0, y0 : double;
begin
// leggo il rango del merletto
Rango:=spinRango.Value;
// fisso lato del quadrato e il punto di ancoraggio
Lato:=360;
x0:=45;
y0:=380;
// disegno il quadrato di rango 0
DisegnaTappeto0(chart1.canvas, x0,y0,Lato);
//Richiamo la procedura ricorsiva
DisegnaTappeto(chart1.canvas, x0,y0,lato, rango)
end;
Procedura per il disegno del tappeto di rango 0CODICEprocedure TForm1.DisegnaTappeto0(BoxCanvas: TCanvas; x, y, Lato: double);
var
w: double;
PuntiQ :array of Tpoint;
begin
w := Lato;
SetLength(PuntiQ, 4);
PuntiQ[0] := Point(round(x),Round(y));
PuntiQ[1] := Point(round(x+w),round(y));
PuntiQ[2] := Point(round(x+w),Round(y-w));
PuntiQ[3] := Point(round(x),Round(y-w));
BoxCanvas.Pen.Width := 1;
BoxCanvas.Pen.Color := clBlack;
BoxCanvas.Brush.Color := clred;
BoxCanvas.Polygon(PuntiQ);
end;
Procedura ricorsiva:CODICEprocedure TForm1.DisegnaTappeto(BoxCanvas: TCanvas; x, y, Lato: double; n: integer);
var
w: double;
x1, y1, x2, y2, x3, y3,x4,y4,x5,y5,x6,y6,x7,y7,x8,y8: double;
PuntiQC :array of Tpoint;
begin
// punto di uscita dalla ricorsione.
// N.B.:il Quadrato di rango 0 è già stato disegnato
if n=0 then exit;
// Determino le dimensioni del quadrato
w := Lato;
// Punto di ancoraggio Quadrato in basso a sinistra
x1 := x;
y1 := y;
// Punto di ancoraggio quadrato in basso a centro
x2 := x+w/3;
y2 := y;
// Punto di ancoraggio quadrato in basso a destra
x3 := x+2*w/3;
y3 := y;
// Punto di ancoraggio Quadrato centro sinistra
x4 := x;
y4 := y-w/3;
// Punto di ancoraggio quadrato centro destra
x5 := x+2*w/3;
y5 := y-w/3;
// Punto di ancoraggio Quadrato in alto a sinistra
x6 := x;
y6 := y-2*w/3;
// Punto di ancoraggio quadrato in alto a centro
x7 := x+w/3;
y7 := y-2*w/3;
// Punto di ancoraggio quadrato in alto a destra
x8 := x+2*w/3;
y8 := y-2*w/3;
// disegno quadrato centrale col colore bianco
SetLength(PuntiQC, 4);
PuntiQC[0] := Point(round(x1+w/3),round(y1-w/3));
PuntiQC[1] := Point(round(x1+2*w/3),Round(y1-w/3));
PuntiQC[2] := Point(round(x1+2*w/3),Round(y1-2*w/3));
PuntiQC[3] := Point(round(x1+w/3),Round(y1-2*w/3));
BoxCanvas.Brush.Color := clWhite;
BoxCanvas.Polygon(PuntiQC);
//Ricorsione : passo n-1 e il lato pari a un terzo del precedente
if n > 0 then
begin
DisegnaTappeto(BoxCanvas, x1, y1, Lato/3, n-1);
DisegnaTappeto(BoxCanvas, x2, y2, Lato/3, n-1);
DisegnaTappeto(BoxCanvas, x3, y3, Lato/3, n-1);
DisegnaTappeto(BoxCanvas, x4, y4, Lato/3, n-1);
DisegnaTappeto(BoxCanvas, x5, y5, Lato/3, n-1);
DisegnaTappeto(BoxCanvas, x6, y6, Lato/3, n-1);
DisegnaTappeto(BoxCanvas, x7, y7, Lato/3, n-1);
DisegnaTappeto(BoxCanvas, x8, y8, Lato/3, n-1);
end;
end;. -
.
E' possibile scaricare i due eseguibili ai seguenti link:
Tappeto di Sierpinsky
Merletto di Sierpinsky
Per chi volesse il codice dei due progetti da poter editare direttamente in Lazarus devo solo chiederlo.. -
.
Io pensavo che anche con il quadrato la procedura prevedesse sempre una rotazione ad ogni variazione di rango.
Ovvero anzichè un nuovo quadrato di lato L/3 si sarebbe proceduto a disegnare un quadrato ruotato di 45° con lati L/2*rad(2). -
.Io pensavo che anche con il quadrato la procedura prevedesse sempre una rotazione ad ogni variazione di rango.
Ovvero anzichè un nuovo quadrato di lato L/3 si sarebbe proceduto a disegnare un quadrato ruotato di 45° con lati L/2*rad(2)
Questa potrebbe essere altra figura frattale, ma occorre fissare bene quali parti sottrarre e poi se possiamo re-inserire parti di parti sottratte.Attached Image. -
.
Se decidiamo di reinserire il quadrato centrale e quindi proseguire sempre con la stessa logica, avremmo una cosa del genere: Attached Image. -
.
Una volta compreso come fare avvenire le ricorsioni, la costruzione del "Tappeto di Zax" è avvenuta con poche modifiche del codice.
Ecco il risultato:
che, debbo dire, non è poi tanto brutto.. -
.
Quando lo avevo proposto, senza alcuno schema grafico, non mi ero reso conto che ruotando il quadrato avrei ottenuto il quadrato al centro e non altri quadrati ai lati, ma delle "fette" triangolari laterali. E quindi è corretto come ha fatto afazio concentrarsi sulla sola zona centrale, sempre quadrata.
.......anche se guardando il disegno con le lineette bianche pubblicato adesso da afazio.....dei quadrati di rango n+2 si vedono.. -
.Quando lo avevo proposto, senza alcuno schema grafico, non mi ero reso conto che ruotando il quadrato avrei ottenuto il quadrato al centro e non altri quadrati ai lati, ma delle "fette" triangolari laterali. E quindi è corretto come ha fatto afazio concentrarsi sulla sola zona centrale, sempre quadrata.
.......anche se guardando il disegno con le lineette bianche pubblicato adesso da afazio.....dei quadrati di rango n+2 si vedono.
Interessante osservazione quest'ultima, che può dare luogo ad altra variante del Tappeto di zax, in cui anche i quadratini di lato L/4 subiscono la stessa sorte del quadrato originario, cioè anch'essi sottoposti alla sottrazione dei quattro triangolini.
Vedrò di modificare il codice quando avro tempo.. -
.
Però a me pare che ad ogni passo sottraiamo 1/2 area del quadrato originario, non 1/4. . -
.Però a me pare che ad ogni passo sottraiamo 1/2 area del quadrato originario, non 1/4.
Guarda questo schema e ti renderai subito conto che ad ogni passo viene sottratta una area pari ad 1/4 di quella iniziale.Attached Image. -
.
Ecco una prima variante al tappeto di zax, in cui per agire sui quattro quadrati di lato L/4 ho fatto ricorso alla ricorsione ricorsiva, cioè una ricorsione interna alla ricorsione stessa. Robe da pazzi che difficilmente riesco visualizzare nella testa.
Farò altre prove, ma intanto guardate il risultato.Attached Image. -
.
Facendo delle prove ho visto che la costruzione del tappeto di Zax dipende da quanto fine vogliamo che sia il tappeto, dato che ad ogni passo spuntano quadrati un po ovunque.
Tutto dipende dal numero di quadrati in cui si pensa essere costituito il tappeto di rango 0.
Se per esempio pensiamo di dividerlo in una griglia di 4*4=16 quadrati, come nella seguente figura;
dopo la prima operazione di sottrazione dei 4 triangoli , si ottiene la seguente immagine:
in cui è possibile individuare ancora 4 dei sedici quadrati in cui si era suddiviso il quadrato iniziale posti agli spigoli e 4 posti al centro.
Volendo adesso applicare la stessa procedura di sottrazione, agendo proprio sui quattro quadrati agli spigoli e sull'unico al centro, otteniamo la seguente immagine:
e a seguire il successivo di rango superiore:
Ma ci si deve decidere come procedere con le ricorsioni dato che avremmo molte diverse via.
Per esempio avremmo potuto decidere di operare su ciascuno dei 16 quadrati di partenza, oppure nel tappeto di rango 1, avremmo potuto considerare i gruppo dei 4 quadrati al centro come quadrati separati e applicare la procedura a ciascuno di essi.
Insomma i tappeti di zax sono parecchi e dipendono dalla sua volontà.
Posso però dire che una volta scritto il codice per uno è molto facile adattarlo alle diverse scelte.. -
.
Dirò la mia, magari sbagliando: la prima versione del tappeto di Zax mi sembrava "poco" frattale, questa ultima è "più" frattale. Da cosa dipende il "poco" e il "più" di cui parlo intuitivamente? Mah direi che i triangoli del rosso del primo frattale, non venivano traforati, quindi l'area rossa tendeva a crescere di iterazione in iterazione. Nella mia concezione di frattalità "compiuta" nella sua massima accezione, ad ogni iterazione l'area dovrebbe diminuire. Un po' come ha dimostrato accadere Afazio per i frattali canonici di inizio thread. Non so se esiste un canone per indicare la "classe di frattalità" dei frattali o è solo una mia interpretazione personale... mi dovrei documentare. . -
.
Il set di Benoit Mandelbrot.
Non dico nulla in merito dato che, dopo il fiocco di neve, il frattale di Mandelbrot è il più conosciuto dei frattali. Dico solo che anche io sono riuscito a riprodurlo sul mio schermo con un mio codice. Per adesso con un set di colori determinati mediante una semplice funzione di divisione intera.
Adesso cercherò di migliorare la gamma dei colori magari scegliendoli da una palette e vedrò di capire come fare per zoomare una zona del frattale.
Mio figlio vedendomi alla prese con queste strane figure, che però ha visto solo di sfuggita, mi dice che faccio programmi inutili.
E' vero, alla fine a che mi serve tutto ciò? A nulla? Forse.
Rispondo che è la vita stessa ad essere tutto sommato inutile o che è solo la somma di tante cose inutili e questa è una di quelle cose utili a riempire la vita di inutilità..