« Fractales » : différence entre les versions
Ligne 90 : | Ligne 90 : | ||
Voici une version Python de la chose ([http://www.pygame.org pygame] doit être installé pour faire fonctionner ce petit programme...)... | Voici une version Python de la chose ([http://www.pygame.org pygame] doit être installé pour faire fonctionner ce petit programme...)... | ||
Euh... ça se sent dans ce genre de programme que Python est un langage interprété : faut pas s'attendre à une vitesse d'exécution transcendentale ! | |||
Outre cette petite lecture, on trouve aussi la version téléchargeable du code [http://amand.frozenkiwi.net/code/fractal.py ici]. | |||
<pre> | <pre> |
Version du 25 octobre 2006 à 20:34
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 :
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...)... Euh... ça se sent dans ce genre de programme que Python est un langage interprété : faut pas s'attendre à une vitesse d'exécution transcendentale !
Outre cette petite lecture, on trouve aussi 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()