Craig Hales mi ha permesso di creare immagini di set Mandelbrot e sequenze video (vedi https://community.jmp.com/t5/Uncharted/Mandelbrot-shallow-tour/ba-p/53295 per dove ho avuto la mia partenza). È stata un'esperienza di apprendimento interessante, non solo per quanto riguarda le intrecci dei set frattali, ma anche per quanto riguarda la programmazione JSL, l'editing video e la creazione di contenuti per YouTube.
Recentemente ho incontrato alcuni video sul set di potenza Mandelbrot (a volte chiamato anche "Multibrot Set" ( https://en.wikipedia.org/wiki/Multibrot_set)). Non entrerò in tutti i dettagli della funzione di alimentazione di Mandelbrot, ma il modo in cui lo usi è il seguente:
- Permettere f_c (z) = z ^ d + c (dove z è il numero complesso z = x + iy, c = xc + i yc).
- Per un dato valore di c , iterare come segue
- permettere z_0 = 0
- Permettere f_c (z_i) = (z_ (i-1)) ^ d + c
- ripetere fino a entrambi
- il numero di "salvataggio" delle iterazioni è stato raggiunto (es i> numero massimo di iterazioni specificato ) O
- || z || = (x ^ 2 + y ^ 2)> (raggio di arresto) ^ 2 (dove raggio di arresto è solitamente uguale a 2, ma potrebbe essere più piccolo)
- registra il valore io come il numero di iterazioni (o la profondità) del punto c
Mentre c'è una funzione JSL Mandelbrot () che aiuterà a generare le immagini del set di mandelbrot, per fare un set multibrot, avevo bisogno di scrivere la mia funzione JSL.
f_mandelbrotpowercount = Function( {x, y, d = 2, radius=2, max_n = 100},
{zx, zy, n_iter = 0, r = 0, theta = 0},
if ( x ^ 2 + y ^ 2 <4,
While( (r < radius) & (n_iter < max_n),
zx = r ^ d * Cos( d * theta ) + x;
zy = r ^ d * Sin( d * theta ) + y;
r = Sqrt( zx ^ 2 + zy ^ 2 );
theta = ArcCosine( zx / r ) * ((zy > 0) * 2 - 1);
n_iter++;
);
);
n_iter;
);Se conosci un po 'di numeri complessi e la moltiplicazione di numeri complessi, puoi vedere che sto utilizzando l'identità che
z = x + iy = R e ^ (i Theta)
dove
R = sqrt (x ^ 2 + y ^ 2), Theta = ArcCosine (x / R) ( Theta è costretto a stare tra (-Pi, Pi)
La sintassi è:
f_mandelbrotpowercount (xc, yc, , , )
La potenza predefinita è 2, il raggio predefinito è 2 e le interazioni di salvataggio predefinite sono 100, che dovrebbe restituire lo stesso risultato della funzione JSL Mandelbrot ().
Se si calcola il risultato di questa funzione, quando power = 2, attraverso il rettangolo definito da
left x value = -2.27, right x value = 2.27
valore y superiore = 1,5, valore y inferiore = -1,5
e quindi eseguire un ridimensionamento dei risultati e impostare i colori RGB in base ai risultati ridimensionati, è possibile ottenere un'immagine come questa
La classica immagine di Mandelbrot!
Quando power = 7, ottieni un'immagine come questa!
Mandelbrot Power Set, power = 7
Il JSL per creare il file immagine è qui
pow=7;<BR />xleft = -1.5*1640/1080;<BR />xright = 1.5*1640/1080;<BR />ytop = 1.5;<BR />ybottom = -1.5;
Parallel Assign(
{f = Name Expr( f_mandelbrotpowercount ), p = pow},
mat[r( ytop, ybottom ), c( xleft, xright )] = f( c, r, p )
);
mat = mat / 100;
green = mat ^ .3;
red = mat ^ 6;
blue = 1 - mat ^ .2;
img = New Image( "rgb", {red, green, blue} );
img << Save image("power7.png");nota che questo sfrutta la funzione JSl di Parallel Assign () che mi permette di usare tutti i core della mia macchina per fare i calcoli. Anche con quello, una singola immagine a questa risoluzione richiede un po 'più di 2 minuti per generare.
Un aspetto davvero interessante è guardare ciò che succede mentre si varia la potenza da 2 a 10 e viceversa. Ho creato un video di questo e pubblicato su YouTube, se vuoi guardarlo. La sequenza è per la potenza = da 2 a 10 con incrementi di 0,005. Ci sono voluti circa 53 ore per creare le sequenze di immagini.
Ecco il codice completo per creare le sequenze di immagini (avviso corretto, vedi sopra, mi ci sono voluti 53 ore per generare le immagini!)
Names Default To Here( 1 );
f_mandelbrotpowercount = Function( {x, y, d = 2, radius=2, max_n = 100},
{zx, zy, n_iter = 0, r = 0, theta = 0},
if ( x ^ 2 + y ^ 2 <4,
While( (r < radius) & (n_iter < max_n),
zx = r ^ d * Cos( d * theta ) + x;
zy = r ^ d * Sin( d * theta ) + y;
r = Sqrt( zx ^ 2 + zy ^ 2 );
theta = ArcCosine( zx / r ) * ((zy > 0) * 2 - 1);
n_iter++;
);
);
n_iter;
);
xleft = -1.5*1640/1080;
xright = 1.5*1640/1080;
ytop = 1.5;
ybottom = -1.5;
xres = 1640;
yres = 1080;
filenamebase="m000";
fileindex=100000;
mat = J( yres, xres, . );
For( pow = 2, pow <= 10, pow += .005,
Parallel Assign(
{f = Name Expr( f_mandelbrotpowercount ), p = pow},
mat[r( ytop, ybottom ), c( xleft, xright )] = f( c, r, p )
);
mat = mat / 100;
green = mat ^ .3;
red = mat ^ 6;
blue = 1 - mat ^ .2;
img = New Image( "rgb", {red, green, blue} );
img << Save image("D:\mandelbrot\powerbrosequence\m"||char(fileindex)|| ".png");
fileindex+=1;
);Fatemi sapere cosa ne pensate o se avete domande.