Craig Hales me hizo activar la creación de imágenes de conjunto de Mandelbrot y secuencias de video (ver https://community.jmp.com/t5/Uncharted/Mandelbrot-shallow-tour/ba-p/53295 por donde comencé). Ha sido una experiencia de aprendizaje interesante, no solo sobre las características de los conjuntos de fractales, sino también sobre la programación JSL, la edición de videos y la creación de contenido para YouTube.
Hace poco encontré algunos videos sobre el conjunto de energía de Mandelbrot (a veces también se lo conoce como el "Conjunto de Multibrot" ( https://en.wikipedia.org/wiki/Multibrot_set)). No voy a entrar en todos los detalles de la función de potencia de Mandelbrot, pero la forma en que la usa es la siguiente:
- Dejar f_c (z) = z ^ d + c (donde z es el numero complejo z = x + iy, c = xc + i yc).
- Para un valor dado de do , iterar como sigue
- dejar z_0 = 0
- Dejar f_c (z_i) = (z_ (i-1)) ^ d + c
- repetir hasta que o
- se ha cumplido el número de iteraciones de "rescate" (es decir, i> iteraciones máximas especificadas ) O
- || z || = (x ^ 2 + y ^ 2)> (radio de parada) ^ 2 (dónde radio de parada suele ser igual a 2, pero podría ser más pequeño)
- registrar el valor yo como el número de iteraciones (o la profundidad) del punto do
Si bien hay una función JSL Mandelbrot () que ayudará con la generación de imágenes de conjunto de mandelbrot, para realizar un conjunto de multibrot, necesitaba escribir mi propia función 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 sabe un poco acerca de los números complejos y la multiplicación de números complejos, puede ver que estoy utilizando la identidad que
z = x + iy = R e ^ (i Theta)
dónde
R = sqrt (x ^ 2 + y ^ 2), Theta = ArcCosine (x / R) ( Theta está limitado a estar entre (-Pi, Pi)
La sintaxis es:
f_mandelbrotpowercount (xc, yc, , , )
La potencia predeterminada es 2, el radio predeterminado es 2 y las interaciones de rescate predeterminadas son 100, lo que debería devolver el mismo resultado que la función Mandelbrot () de JSL.
Si calcula el resultado de esta función, cuando potencia = 2, a través del rectángulo definido por
valor de x izquierdo = -2.27, valor de x derecho = 2.27
valor superior de y = 1.5, valor inferior de y = -1.5
y luego haga una escala de los resultados y establezca colores RGB en función de los resultados a escala, puede obtener una imagen como esta
El clásico conjunto de imágenes de Mandelbrot!
Cuando power = 7, obtienes una imagen como esta!
Conjunto de potencia Mandelbrot, potencia = 7
El JSL para crear el archivo de imagen está aquí
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");tenga en cuenta que esto aprovecha la función de Asignación Paralela (JSl) que me permite usar todos los núcleos de mi máquina para realizar los cálculos. Incluso con eso, una sola imagen en esta resolución tarda un poco más de 2 minutos en generarse.
Una imagen realmente genial es observar lo que sucede a medida que varía la potencia de 2 a 10 y viceversa. Creé un video de esto y Lo publicaste en YouTube, si quieres verlo. La secuencia es para la potencia = 2 a 10 en incrementos de 0.005. Le tomó aproximadamente 53 horas crear las secuencias de imágenes.
Aquí está el código completo para crear las secuencias de imágenes (aviso justo, ver arriba, ¡me tomó 53 horas generar las imágenes!)
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;
);Déjame saber lo que piensas o si tienes alguna pregunta.