Leçon 4 : Des boucles qui se souviennent
Construis en Python le motif « Jeu du chaos » et apprends en chemin :
- une boucle qui garde son état d’une étape à l’autre
- des nombres entiers aléatoires avec rng.integers
- une boucle while pour une condition
- des tableaux de points et le découpage (slicing)
- np.column_stack
Regarde-le d’abord
Lecture depuis YouTube après un clic.
"""Chaos game: jump a part r of the way to a random corner of a polygon, again and again.
Run: python chaos-game.py (needs: pip install numpy matplotlib)
"""
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("dark_background")
corners, r, no_repeat = 3, 0.5, False # triangle, halfway: the Sierpinski triangle
steps = 60000
rng = np.random.default_rng()
angles = np.pi / 2 + 2 * np.pi * np.arange(corners) / corners
vertex = np.column_stack([np.cos(angles), np.sin(angles)])
points, chosen = np.zeros((steps, 2)), np.zeros(steps, dtype=int)
x, last = np.array([0.0, 0.0]), -1
for i in range(steps):
c = rng.integers(corners)
while no_repeat and c == last: # the restricted game: never the same corner twice
c = rng.integers(corners)
x = x + r * (vertex[c] - x) # the whole rule
points[i], chosen[i], last = x, c, c
plt.figure(figsize=(6, 6))
plt.scatter(points[20:, 0], points[20:, 1], s=0.3, c=chosen[20:], cmap="rainbow")
plt.axis("equal")
plt.axis("off")
plt.show()
# Try: corners, r = 5, 0.618 (a pentagon) or corners, no_repeat = 4, True (a square, restricted)
Pas de Python sur cet ordinateur ? Le notebook exécute le même script, les exercices et les réponses dans ton navigateur, sur Google Colab. Le notebook est en anglais.
Ligne par ligne
vertex = np.column_stack([np.cos(angles), np.sin(angles)])Les sommets du polygone : leurs valeurs x et y côte à côte, une ligne par sommet.
c = rng.integers(corners)Un nombre entier aléatoire de 0 à corners − 1 : le sommet vers lequel sauter.
while no_repeat and c == last:Le jeu avec restriction : tant que le nouveau sommet est le même que le dernier, on tire à nouveau.
x = x + r * (vertex[c] - x)La règle : avancer de la fraction r du chemin entre le point et le sommet. Avec r = 0.5, à mi-chemin.
points[i], chosen[i], last = x, c, cGarder le point et son sommet, et retenir le sommet pour l’étape suivante.
plt.scatter(points[20:, 0], points[20:, 1], s=0.3, c=chosen[20:], cmap="rainbow")Laisser de côté les 20 premiers points, encore en route vers la fractale, et colorer les autres selon leur sommet.
À toi de jouer
Dessine un pentagone dont les cinq copies se touchent tout juste.
Indice
Change corners et r sur une seule ligne.
Réponse
corners, r, no_repeat = 5, 0.618, False
Pourquoi le dessin laisse-t-il de côté les 20 premiers points ?
Indice
Où le point commence-t-il ?
Réponse
Il commence au centre, qui n’est pas sur la fractale. Chaque saut divise par deux sa distance à la fractale, donc après 20 sauts il en est à moins d’un millionième (2⁻²⁰) de la taille de l’image.
Joue au jeu du carré avec et sans no_repeat. Qu’est-ce qui change ?
Indice
corners = 4, r = 0.5.
Réponse
Sans la restriction, les points remplissent simplement le carré ; avec no_repeat = True, une fractale apparaît.
Quiz
Cartes mémoire
Lis le recto, dis-toi le verso, puis retourne la carte.
rng.integers(n)
Un nombre entier aléatoire de 0 à n − 1.
while condition:
Répète son bloc tant que la condition vaut True.
a[20:, 0]
Les lignes de 20 jusqu’à la fin, colonne 0, d’un tableau à 2 dimensions.
Contraction
Une étape qui rapproche deux points quelconques, comme un saut à mi-chemin vers un sommet.
Attracteur
La forme vers laquelle des étapes répétées attirent chaque point : ici, le triangle de Sierpiński.