« Fractales » : différence entre les versions
(20 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 11 : | Ligne 11 : | ||
** <math>C = c + di</math> | ** <math>C = c + di</math> | ||
<table border="0"> | |||
<tr> | |||
<td> | |||
* Pour '''Mandelbrot''' C est le point à calculer : | * Pour '''Mandelbrot''' C est le point à calculer : | ||
** c est l'absisse | ** c est l'absisse | ||
** di est l'ordonnée | ** di est l'ordonnée | ||
** on part avec Z = 0 | |||
</td> | |||
<td> | |||
[[Image:Mandelbrot.png]] | |||
</td> | |||
</tr> | |||
</table> | |||
<table border="0"> | |||
<tr> | |||
<td> | |||
* Pour '''Julia''' Z est le point à calculer : | * Pour '''Julia''' Z est le point à calculer : | ||
** a est l'absisse | ** a est l'absisse | ||
** bi est l'ordonnée | ** bi est l'ordonnée | ||
** on prend une constante pour C | |||
</td> | |||
<td> | |||
[[Image:Julia.png]] | |||
</td> | |||
</tr> | |||
</table> | |||
On aura donc : | On aura donc : | ||
Ligne 32 : | Ligne 53 : | ||
donc pour <math>n+1</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> | <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... | * 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... | ||
Ligne 40 : | Ligne 63 : | ||
on peut se passer de l'opération avec la racine carrée car <math>\sqrt{4} = 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> | donc on peut juste tester <math>\bar{z} < a^2 + b^2 < 4</math> | ||
=== Et hop, des chtis algorithmes === | === Et hop, des chtis algorithmes === | ||
Ligne 53 : | Ligne 76 : | ||
bi = y | bi = y | ||
DO | DO | ||
a = a * a | tmp = a | ||
bi = 2 * | a = a * a - b * b + c | ||
bi = 2 * tmp * bi + di | |||
zbar = a * a + bi * bi | zbar = a * a + bi * bi | ||
i = i + 1 | i = i + 1 | ||
Ligne 63 : | Ligne 87 : | ||
x = x + 1 | x = x + 1 | ||
Et pour '''Mandelbrot''' | Et pour '''Mandelbrot''' : | ||
a = 0 | a = 0 | ||
Ligne 72 : | Ligne 96 : | ||
di = y | di = y | ||
DO | DO | ||
a = a * a | tmp = a | ||
bi = 2 * | a = a * a - b * b + c | ||
bi = 2 * tmp * bi + di | |||
zbar = a * a + bi * bi | zbar = a * a + bi * bi | ||
i = i + 1 | i = i + 1 | ||
Ligne 81 : | Ligne 106 : | ||
y = y + 1 | y = y + 1 | ||
x = x + 1 | x = x + 1 | ||
=== Du code, at last ! === | |||
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> | |||
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() | |||
</pre> | |||
== Howtos == | == Howtos == | ||
* http://home.hia.no/~fgill/fractal.html | * http://home.hia.no/~fgill/fractal.html |
Dernière version du 21 avril 2012 à 08:04
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>
|
|
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 < 4</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()