Craig Hales s’est intéressé à la création d’images et de séquences vidéo de Mandelbrot (voir https://community.jmp.com/t5/Uncharted/Mandelbrot-shallow-tour/ba-p/53295 pour où j'ai eu mon début). Cette expérience d’apprentissage a été intéressante, non seulement à propos des intracies des ensembles fractals, mais également à propos de la programmation JSL, du montage vidéo et de la création de contenu pour YouTube.
J'ai récemment vu des vidéos sur le groupe électrogène de Mandelbrot (parfois aussi appelé "groupe Multibrot" ( https://en.wikipedia.org/wiki/Multibrot_set)). Je n'entrerai pas dans tous les détails du fonctionnement de Mandelbrot, mais voici comment vous l'utilisez:
- Laisser f_c (z) = z ^ d + c (où z est le nombre complexe z = x + iy, c = xc + i yc).
- Pour une valeur donnée de c , itérer comme suit
- laisser z_0 = 0
- Laisser f_c (z_i) = (z_ (i-1)) ^ d + c
- répéter jusqu'à ce que
- le nombre de "renflouements" a été atteint (c.-à-d. i> maximum d'itérations spécifiées ) OU
- || z || = (x ^ 2 + y ^ 2)> (rayon d'arrêt) ^ 2 (où rayon d'arrêt est généralement égal à 2, mais pourrait être plus petit)
- enregistrer la valeur je comme le nombre d'itérations (ou la profondeur) du point c
Bien qu’il existe une fonction JSL, Mandelbrot (), qui aide à générer des images de jeu mandelbrot. Pour créer un jeu multibrot, j’avais besoin d’écrire ma propre fonction 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;
);Si vous en savez un peu sur les nombres complexes et la multiplication de nombres complexes, vous pouvez voir que j'utilise l'identité qui
z = x + iy = R e ^ (i Thêta)
où
R = sqrt (x ^ 2 + y ^ 2), Thêta = ArcCosine (x / R) ( Thêta est contraint d'être entre (-Pi, Pi)
La syntaxe est la suivante:
f_mandelbrotpowercount (xc, yc, , , )
La puissance par défaut est 2, le rayon par défaut est 2 et l'interaction de sauvetage par défaut est 100, ce qui devrait donner le même résultat que la fonction JSL Mandelbrot ().
Si vous calculez le résultat de cette fonction, lorsque puissance = 2, sur un rectangle défini par
valeur x gauche = -2,27, valeur x droite = 2,27
valeur y supérieure = 1,5, valeur y inférieure = -1,5
et ensuite, redimensionnez les résultats et définissez les couleurs RVB en fonction des résultats redimensionnés, vous pouvez obtenir une image comme celle-ci.
L'image du jeu classique de Mandelbrot!
Lorsque power = 7, vous obtenez une image comme celle-ci!
Mandelbrot Power Set, puissance = 7
La JSL pour créer le fichier image est ici
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");notez que cela exploite la fonction JSl de Parallel Assign () qui me permet d’utiliser tous les cœurs de ma machine pour effectuer les calculs. Même avec cela, une seule image à cette résolution prend un peu plus de 2 minutes à générer.
Un visuel vraiment cool consiste à regarder ce qui se passe lorsque vous faites varier la puissance de 2 à 10 et inversement. J'ai créé une vidéo de cela et posté sur YouTube, si vous voulez le regarder. La séquence correspond à la puissance = 2 à 10 par incréments de 0,005. Il a fallu environ 53 heures pour créer les séquences d'images.
Voici le code complet pour créer les séquences d'images (bon avertissement, voir ci-dessus, il m'a fallu 53 heures pour générer les images!)
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;
);Faites-moi savoir ce que vous pensez ou si vous avez des questions.