Abstract
The Mandelbrot set is a fractal object of the complex plan defined by the set of points c for which the serie defined by :
converges after a few iterations.
I'll explain a simple algorithm to plot the Mandelbrot set and provide two implementations, one in C and the second in Python.
Algorithm
The algorithm uses the following properties of the Mandelbrot set :
property 1 : The Mandelbrot set is bound into the square between (-2.0, 1.25i) and (0.5,-1.25i).
property 2 : if |Zn| > 2, then the serie will increase towards infinity after n.
property 3 : The series converges if for n in [0,40], |Zn| is less than 2.
property 4 : The set is symetrical across the real axis.
To draw the Mandelbrot set, we take all pixels, calculte the scaled real and imaginary value of the point, iterate the serie for n from 0 to 40 - if |Zn| > 2, we break the iteration. the pixel it plot using a grey value mapped to n : black for n near to zero, white for n near to 40. The intensity of grey is proportional to the speed with which the value of Z goes to infinity.
for each pixel (Px, Py) on the screen do
x0 := scaled x coordinate of pixel (scaled to lie in the Mandelbrot X scale (-2.5, 1))
y0 := scaled y coordinate of pixel (scaled to lie in the Mandelbrot Y scale (-1, 1))
x := 0.0
y := 0.0
iteration := 0
max_iteration := 40
while (x*x + y*y ≤ 2*2 AND iteration < max_iteration) do
xtemp := x*x - y*y + x0
y := 2*x*y + y0
x := xtemp
iteration := iteration + 1
color := palette[iteration]
plot(Px, Py, color)
Implementation in C
This implementation uses minimal function from the SDL2 library to create a window and plot pixels directly in its frame buffer.
#include <SDL2/SDL.h>
#define WIDTH 800
#define HEIGHT 800
int main(int argc, char* args[]){
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window = SDL_CreateWindow("Mandelbrot set in c", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, 0);
SDL_Surface *winSurf = SDL_GetWindowSurface(window);
Uint32 *pixels = winSurf->pixels;
SDL_Event event;
const int max_iter = 40;
const float zoom = 2.5;
const float colorFactor = 256 / max_iter;
const float widthFactor = WIDTH / zoom;
const float heightFactor = HEIGHT / zoom;
float cr, ci, zr, zi, tmp;
int x, y, iteration, color;
// compute the set for every point
for (x=0; x<WIDTH; x++) {
for (y=0; y<HEIGHT/2; y++) {
cr = x / widthFactor - 2 ;
ci = y / heightFactor - 1.25;
zr = 0;
zi = 0;
// recurse
for (iteration=0; iteration<max_iter; iteration++) {
tmp = zr;
zr = zr*zr - zi*zi + cr;
zi = 2*tmp*zi + ci;
if ((zr*zr + zi*zi) >= 4) break;
}
// update the frame buffer
color = (int)(iteration*colorFactor);
pixels[x + y * WIDTH] = SDL_MapRGBA(winSurf->format, color, color, color, SDL_ALPHA_OPAQUE);
pixels[x + (HEIGHT -1 - y) * WIDTH] = SDL_MapRGBA(winSurf->format, color, color, color, SDL_ALPHA_OPAQUE);
}
}
// display the results
SDL_UpdateWindowSurface(window);
// wait for a key press
while(SDL_TRUE)
if (SDL_PollEvent(&event) && (event.type == SDL_QUIT || event.type == SDL_KEYDOWN)) break;
else SDL_Delay(256);
//releases the ressources and quit
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Result
Implementation in Python
This implementation uses the pygame module to create a window and plot the pixels and make use of Python native complex mumbers type.
#!/usr/bin/env python3
import math
import pygame
from pygame.locals import *
lenght=800
width=800
white = (255,255,255)
black = (0,0,0)
pygame.init()
gameDisplay=pygame.display.set_mode((lenght,width))
pygame.display.set_caption('Mandelbrot set in Python')
clock = pygame.time.Clock()
pixAr = pygame.PixelArray(gameDisplay)
gameDisplay.fill(black)
max_iter=40
zoom=2.5
colorFactor=255/max_iter
lengthFactor=lenght/zoom
widthFactor=width/zoom
for x in range(lenght):
for y in range(int(width/2)):
c = complex(((x/lengthFactor)-2), (y/(widthFactor)-1.25 ))
z = 0.0j
for i in range (max_iter):
z = z*z+c
if (z.real*z.real + z.imag*z.imag) >= 4:
break;
c = i*colorFactor
pixAr[x][y] = (c,c,c)
pixAr[x][width-1-y] = (c,c,c)
pygame.display.update()
while True:
pygame.time.wait(10)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
Result
Going further
I you want to know more about fractals, I can only recommend the best book on this matter :
Chaos: Making a New Science
James Gleick
1987
ISBN 0-7493-8606-1
Enjoy !