Lekcja 4: Pętle, które pamiętają
Zbuduj w Pythonie wzór „Gra w chaos” i po drodze naucz się:
- pętla, która przenosi swój stan z kroku na krok
- losowe liczby całkowite z rng.integers
- pętla while z warunkiem
- tablice punktów i wycinki
- np.column_stack
Najpierw obejrzyj
Film gra z YouTube po kliknięciu.
"""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)
Nie masz Pythona na tym komputerze? Notatnik uruchamia ten sam skrypt, zadania i odpowiedzi w przeglądarce, w Google Colab. Notatnik jest po angielsku.
Linijka po linijce
vertex = np.column_stack([np.cos(angles), np.sin(angles)])Wierzchołki wielokąta: ich wartości x i y obok siebie, po jednym wierszu na wierzchołek.
c = rng.integers(corners)Losowa liczba całkowita od 0 do corners − 1: wierzchołek, do którego skaczemy.
while no_repeat and c == last:Gra z ograniczeniem: dopóki nowy wierzchołek jest tym samym co ostatnio, losuj jeszcze raz.
x = x + r * (vertex[c] - x)Reguła: przesuń punkt o część r drogi do wierzchołka. Przy r = 0.5 w połowę drogi.
points[i], chosen[i], last = x, c, cZapamiętaj punkt i jego wierzchołek, a wierzchołek zachowaj na następny krok.
plt.scatter(points[20:, 0], points[20:, 1], s=0.3, c=chosen[20:], cmap="rainbow")Pomiń pierwsze 20 punktów, które są jeszcze w drodze do fraktala, a resztę pokoloruj według wierzchołka.
Twoja kolej
Narysuj pięciokąt, którego pięć kopii ledwo się styka.
Podpowiedź
Zmień corners i r w jednej linijce.
Odpowiedź
corners, r, no_repeat = 5, 0.618, False
Dlaczego wykres pomija pierwsze 20 punktów?
Podpowiedź
Gdzie zaczyna punkt?
Odpowiedź
Zaczyna w środku, który nie leży na fraktalu. Każdy skok zmniejsza o połowę jego odległość od fraktala, więc po 20 skokach jest od niego dalej niż o jedną milionową (2⁻²⁰) obrazka.
Zagraj w kwadrat z no_repeat i bez. Co się zmienia?
Podpowiedź
corners = 4, r = 0.5.
Odpowiedź
Bez ograniczenia punkty po prostu wypełniają kwadrat; przy no_repeat = True pojawia się fraktal.
Quiz
Fiszki
Przeczytaj przód, powiedz sobie, co jest z tyłu, potem otwórz kartę.
rng.integers(n)
Losowa liczba całkowita od 0 do n − 1.
while condition:
Powtarza swój blok, dopóki warunek jest True.
a[20:, 0]
Wiersze od 20 do końca, kolumna 0, tablicy dwuwymiarowej.
Odwzorowanie zwężające
Krok, który zbliża do siebie dowolne dwa punkty, jak skok w połowę drogi do wierzchołka.
Atraktor
Kształt, na który powtarzane kroki ściągają każdy punkt: tutaj trójkąt Sierpińskiego.