# installation du modul 'pygale' :
# python -p pip install pygame

import pygame

# Constantes
MAX_ITERATION = 50 # nombre d'itérations maximales avant de considérer que la suite converge
XMIN, XMAX, YMIN, YMAX = -2, +2, -1.25, +1.5 # bornes du repère
LARGEUR, HAUTEUR = 800, 600 # taille de la fenêtre en pixels
COEF_R, COEF_G, COEF_B = 5, 8, 13 # pour le fun : 3 termes successifs de la suite de Fibonacci

# Initialisation et création d'une fenêtre aux dimensions spécifiéés munie d'un titre
pygame.init()
screen = pygame.display.set_mode((LARGEUR,HAUTEUR))
pygame.display.set_caption("Fractale diverse")


# Création de l'ensemble de Mandelbrot
# Principe : on balaye l'écran pixel par pixel en convertissant le pixel en un point du plan de notre repère
# Si la suite converge, le point appartient à l'ensemble de Mandelbrot et on colore le pixel
# Sinon la suite diverge, le point n'appartient pas à l'ensemble et on colore le pixel en noir

for y in range(HAUTEUR):
  for x in range(LARGEUR):
    # Les deux lignes suivantes permettent d'associer à chaque pixel de l'écran de coordonnées (x;y)
    # un point C du plan de coordonnées (cx;cy) dans le repère défini par XMIN:XMAX et YMIN:YMAX
    cx = (x * (XMAX - XMIN) / LARGEUR + XMIN)
    cy = (y * (YMIN - YMAX) / HAUTEUR + YMAX)
    xn = 0
    yn = 0
    n = 0
    while (xn * xn + yn * yn) < 4 and n < MAX_ITERATION: # on teste si le carré de la distance est inférieur à 4 -> permet d'économiser un calcul de racine carrée coûteux en terme de performances
      # Calcul des coordonnes de Mn
      tmp_x = xn
      tmp_y = yn
      xn = 0.5*tmp_x * tmp_y + cx
      yn = 0.5*tmp_x**2 - tmp_y**2 + cy
      n = n + 1
    if n == MAX_ITERATION:
      screen.set_at((x, y), (0, 0, 0)) 
    else:
      screen.set_at((x, y), ((COEF_R * n) % 256, (COEF_G * n) % 256, (COEF_B * n) % 256))
pygame.display.flip() # Mise à jour et rafraîchissement de la fenêtre graphique pour affichage

# Boucle infinie permettant d'afficher à l'écran la fenêtre graphique
# Sans ça, la fenêtre apparaît et disparaît aussitôt
loop = True
while loop:
  for event in pygame.event.get():
    if event.type == pygame.QUIT: # Pour quitter l'application en fermant la fenêtre
      loop = False
      
pygame.quit()
