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...)...
On trouve la version téléchargeable du code ici.
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 # on est obligé de faire une conversion coordonnées des pixels à l'écran <==> coordonnées des points # dans le repère (xmin, ymin) / (ymin, ymax) 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()