Fractales

De FrozenWiki
Aller à la navigation Aller à la recherche

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()

Howtos