Fract-ol
Fract-ol
A graphical project that generates beautiful, infinite geometric patterns. This implementation stands out by using a single mathematical engine to compute multiple fractal types and leveraging the mlx_loop_hook for continuous, high-speed rendering.
Features
- Mandelbrot & Julia Sets: Seamlessly toggle between fractal types using unified logic.
- High-Performance Rendering: Smoothly handles thousands of iterations using the
mlx_loop_hook. - Infinite Zoom: Fully interactive zoom functionality using the mouse wheel.
- Color Schemes: Dynamic coloring based on the escape time of each pixel.
Implementation Highlights
1. The “Unified” Math Engine
Instead of writing separate loops for Mandelbrot and Julia, I designed a math_init function. It abstracts the starting parameters (z and c) while keeping the iterative escape-time math identical.
- Mandelbrot: z starts at 0.0, and c is the current pixel coordinate.
- Julia: z starts at the pixel coordinate, and c is a constant provided as an argument.
static void math_init(double x, double y, t_fractol *fractol, t_math *math_obj)
{
if (fractol->name) // Mandelbrot
{
math_obj->z_real = 0.0;
math_obj->z_imag = 0.0;
math_obj->c_real = x;
math_obj->c_imag = y;
}
else // Julia
{
math_obj->z_real = x;
math_obj->z_imag = y;
math_obj->c_real = fractol->julia_cx;
math_obj->c_imag = fractol->julia_cy;
}
}
2. High-Performance Loop Hook
To ensure the program remains responsive and renders as fast as the GPU allows, I utilized mlx_loop_hook. This hook constantly calls my render_main function, allowing for real-time updates and the ability to handle thousands of iterations without freezing the UI.
// In main.c
mlx_loop_hook(mlx.mlx, render_main, &mlx); // Continuous high-speed rendering
mlx_loop(mlx.mlx);
3. The Core Fractal Loop
The escape-time logic is contained in fract_math, which calculates whether a point diverges using the formula z = z^2 + c.
t_color fract_math(double x, double y, t_fractol *fractol)
{
int i;
double tmp;
t_math math_obj;
i = 0;
math_init(x * fractol->zoom, y * fractol->zoom, fractol, &math_obj);
while (i < fractol->iteration)
{
if ((math_obj.z_real * math_obj.z_real) + (math_obj.z_imag * math_obj.z_imag) > 4)
return (coloring(i)); // Point escaped
tmp = (math_obj.z_real * math_obj.z_real) - (math_obj.z_imag * math_obj.z_imag) + math_obj.c_real;
math_obj.z_imag = 2 * math_obj.z_real * math_obj.z_imag + math_obj.c_imag;
math_obj.z_real = tmp;
i++;
}
return (BLACK); // Point is part of the set
}
Usage
1. Compilation
make
2. Run Mandelbrot
./fractol mandelbrot
3. Run Julia
./fractol julia -0.4 0.6
Skills Learned
- Complex Math: Implementing calculations in the complex plane (z = z^2 + c).
- Graphic Optimization: Using hooks and memory-mapped address offsets (
mlx_get_data_addr) to push pixels efficiently. - Event Handling: Managing keyboard and mouse input to create a seamless user interface.
- Code Abstraction: Reducing code duplication by unifying fractal initialization logic.
👤 Author
- GitHub: cuteKittenArri