Fractales
Mandelbrot et Julia
Comment que l'on les calcule donc ?
Mandelbrot et Julia sont définies par la suite :
<math>Z_{n+1} = Z_n^2 + C</math>
- Z et C sont deux nombres complexes :
- <math>Z = a + bi</math>
- <math>C = c + di</math>
- Pour Mandelbrot C est le point à calculer :
- c est l'absisse
- di est l'ordonnée
- on part avec Z = 0
- Pour Julia Z est le point à calculer :
- a est l'absisse
- bi est l'ordonnée
- on prend une constante pour C
On aura donc :
<math>(a + bi)_{n+1} = (a_n + bi_n)^2 + c + di</math>
soit
<math>(a + bi)_{n+1} = a_n^2 +2a_nbi_n + (bi_n)^2 + c + di</math>
avec <math>i^2 = -1</math> ça donne
<math>(a + bi)_{n+1} = a_n^2 + 2a_nbi_n - b_n + c + di</math>
donc pour <math>n+1</math>:
<math>a_{n+1} = a_n^2 -b_n + c</math> et <math>bi_{n+1} = 2a_nbi_n + di</math>
- le point Z appartient à la fractale si la longueur du vecteur Z (<math>\bar{z}</math> ne tend pas vers l'infini, il est dit un peu partout que si cette longueur dépasse 2, on va tendre vers l'infini...
<math>\bar{z} = \sqrt{a^2 + b^2}</math>
on peut se passer de l'opération avec la racine carrée car <math>\sqrt{4} = 2</math>
donc on peut juste tester <math>\bar{z} < a^2 + b^2</math>
Et hop, des chtis algorithmes
Pour dessiner la fractale Julia :
c = -0.7 d = -0.1 WHILE x < WIDTH WHILE y < HEIGHT a = x bi = y DO tmp = a a = a * a + b * b + c bi = 2 * tmp * bi + di zbar = a * a + bi * bi i = i + 1 WHILE i < MAXITER) AND zbar < 4) IF zbar < 4: PIXEL(x, y) y = y + 1 x = x + 1
Et pour Mandelbrot (à tester)...:
a = 0 bi = 0 WHILE x < WIDTH WHILE y < HEIGHT c = x di = y DO tmp = a a = a * a + b * b + c bi = 2 * tmp * bi + di zbar = a * a + bi * bi i = i + 1 WHILE i < MAXITER) AND zbar < 4) IF zbar < 4: PIXEL(x, y) y = y + 1 x = x + 1
Du code, at last !
Voici une version Python de la chose (pygame doit être installé pour faire fonctionner ce petit programme...)
import sys, pygame from pygame.locals import *
WIDTH = 512 HEIGHT = 512
def show_text(t): text = font.render(t, 1, (255, 255, 255)) textpos = text.get_rect(centerx=screen.get_width()/2, centery=screen.get_height()/2) screen.blit(text, textpos) pygame.display.flip()
def julia(surface):
c = -0.78 di = -0.1 maxiter = 64
xmin = -1.5 ymin = -1.5 xmax = 1.5 ymax = 1.5
dx = (xmax - xmin) / WIDTH dy = (ymax - ymin) / HEIGHT
x = 0 while x < WIDTH: y = 0 while y < HEIGHT: a = xmin + x * dx bi = ymin + y * dy zbar = a * a + bi * bi
i = 0 while i < maxiter and zbar < 4: tmp = a a = a * a - bi * bi + c bi = 2 * tmp * bi + di zbar = a * a + bi * bi
i += 1
surface.set_at((x, y), (48, 48, 64+i))
y += 1
x += 1
def mandelbrot(surface): maxiter = 64
xmin = -2.0 ymin = -1.25 xmax = 1.25 ymax = 1.25
dx = (xmax - xmin) / WIDTH dy = (ymax - ymin) / HEIGHT
x = 0 while x < WIDTH: y = 0 while y < HEIGHT: a = 0 bi = 0 c = xmin + x * dx di = ymin + y * dy
zbar = a * a + bi * bi
i = 0 while i < maxiter and zbar < 4: tmp = a a = a * a - bi * bi + c bi = 2 * tmp * bi + di zbar = a * a + bi * bi
i += 1
surface.set_at((x, y), (64+i, 48, 48))
y += 1
x += 1
pygame.init() screen = pygame.display.set_mode( (WIDTH,HEIGHT) ) surface = pygame.Surface( (WIDTH,HEIGHT) ) font = pygame.font.Font(None, 24)
is_julia = False first = True while True:
event = pygame.event.poll() if event.type == QUIT: break if event.type == KEYDOWN and event.key == K_ESCAPE: break if (event.type == KEYDOWN and event.key == K_SPACE) or first: first = False if is_julia: show_text("Computing Mandelbrot...") mandelbrot(screen) is_julia = False else: show_text("Computing Julia...") julia(screen) is_julia = True
pygame.display.flip() pygame.time.wait(1000/60)