Un fractal es un conjunto definido por una iteración matemática. Partimos de la fórmula general:
Donde Z y C son números complejos de la forma
Para optimizar, reemplazamos sqrt y pow con álgebra compleja:
y verificamos escape con:
Si
-
Código:
void *mlx = mlx_init();
-
Descripción: Inicializar la librería MiniLibX es el primer paso porque nos permite conectarnos con el servidor gráfico de nuestro sistema operativo. Sin esta inicialización, no podemos crear ventanas ni imágenes en memoria. Básicamente,
mlx_init()establece el “contexto gráfico” que manejará todos los recursos durante la vida del programa. Desde este momento, cada operación de dibujo, creación de ventanas e imágenes dependerá de este punteromlx.
-
Código:
void *win = mlx_new_window(mlx, WIDTH, HEIGHT, "Fractol"); void *img = mlx_new_image(mlx, WIDTH, HEIGHT);
-
Descripción: La ventana es el área visible donde finalmente mostraremos el fractal. La imagen es diferente: es un buffer en memoria donde dibujamos píxel por píxel antes de renderizarlo en pantalla. Este enfoque evita parpadeos y nos da control total sobre los colores. Cada pixel de la imagen ocupa 4 bytes (RGBA), lo que nos permitirá manipular los colores de forma precisa.
-
Código:
char *ptr_buf_img; int bpp, size_l, endian; ptr_buf_img = mlx_get_data_addr(img, &bpp, &size_l, &endian);
-
Descripción: En este paso accedemos directamente al bloque de memoria donde vive la imagen.
bppnos dice cuántos bits ocupa cada pixel (normalmente 32),size_les el tamaño en bytes de cada fila, yptr_buf_imges el puntero al primer byte del buffer. Al trabajar a nivel de bytes, podemos escribir colores sin depender de funciones externas, pixel a pixel, usando aritmética de punteros. Esto también nos permite optimizar el rendimiento y tener un control preciso sobre la imagen final.
-
Descripción: Cada pixel
(px, py)de la ventana debe convertirse a un número complejo(x + yi)para poder evaluar la fórmula del fractal. Para ello, definimos un marco (viewport) que corresponde al área donde el fractal es visible. Por ejemplo, para Mandelbrot usamos:- Real: [-2.0, 1.0]
- Imaginario: [-1.5, 1.5]
Luego escalamos linealmente la posición del pixel a este rango. Así, cada punto en pantalla se transforma en un número complejo único que será evaluado.
-
Descripción: Aquí aplicamos la iteración fundamental de los fractales:
$$ Z_{n+1} = Z_n^2 + C $$
donde desarrollamos el cuadrado con álgebra compleja:
- Real:
$x^2 - y^2 + Re(C)$ - Imaginaria:
$2xy + Im(C)$
Repetimos esto hasta que:
-
$x^2 + y^2 > 4$ → el punto escapa - O alcanzamos el máximo de iteraciones → se considera dentro del fractal
Este bucle es el corazón del proyecto, ya que define la forma final del fractal en pantalla.
- Real:
-
Descripción: Una vez determinado si el punto escapa o no, elegimos un color. Si no escapa, pintamos el pixel de negro para representar que pertenece al fractal. Si escapa, asignamos un color basado en la iteración en la que escapó. Por ejemplo, con un máximo de 100 iteraciones:
- Iteración baja → colores claros (escapa rápido)
- Iteración alta → colores oscuros (cerca del límite)
Este gradiente genera la profundidad visual que hace reconocibles los fractales.
-
Código:
int offset = y * size_l + x * (bpp / 8); *(int *)(ptr_buf_img + offset) = color;
-
Descripción: Para pintar un pixel calculamos su desplazamiento en bytes dentro del buffer:
- Multiplicamos la fila (
y) por el tamaño de fila (size_l) - Sumamos la columna (
x) multiplicada por los bytes por pixel (bpp/8)
Luego escribimos el color como un
intde 4 bytes. Este método nos da control directo sobre la memoria y permite un dibujado muy rápido. - Multiplicamos la fila (
-
Código:
mlx_put_image_to_window(mlx, win, img, 0, 0); mlx_loop(mlx);
-
Descripción: Cuando todos los pixeles han sido calculados y coloreados, copiamos la imagen al framebuffer de la ventana con
mlx_put_image_to_window. Luego,mlx_loopmantiene el programa en ejecución y atiende eventos como:- Zoom con el mouse
- Movimiento con el teclado
- Cierre de ventana
Cada vez que interactuamos, podemos recalcular el fractal y redibujarlo dinámicamente.
- Inicializar MLX
- Crear ventana e imagen
- Obtener buffer de imagen
- Mapear cada pixel a número complejo
- Iterar
$Z^2 + C$ con álgebra compleja - Determinar si escapa y asignar color
- Escribir color en el buffer
- Mostrar imagen y mantener el loop
-
Clonar el repositorio
git clone <url_del_repositorio> cd fractol
-
Compilar el proyecto
make
-
Ejecutar el programa
./fractol <tipo_de_fractal> [coordenadas]
Ejemplos:
./fractol mandelbrot ./fractol burningship ./fractol julia -0.7 0.5675 ./fractol julia -0.8 0.156 ./fractol julia 0.285 0
-
Tipos de fractal disponibles:
mandelbrotburningshipjulia(requiere dos coordenadas entre -2.0 y 2.0)
-
Si el usuario introduce un argumento inválido, el programa muestra la ayuda:
Invalid input from user
Available input:
* Type of fractal: Julia - Mandelbrot - Burningship
* If you choose Julia, then add:
one coordinate separated by space.
* Egs.
./fractol julia -0.7 0.5675
./fractol julia -0.8 0.156
./fractol julia -0.4 0.6
./fractol julia -0.75 0.11
./fractol julia 0.285 0
* Please note values can go from -2.0 to 2.0