Mittelstufe · Chaosspiel

Lektion 4: Schleifen, die sich erinnern

Baue das Muster „Chaosspiel“ in Python und lerne dabei:

  • eine Schleife, die ihren Zustand von Schritt zu Schritt mitnimmt
  • zufällige ganze Zahlen mit rng.integers
  • eine while-Schleife für eine Bedingung
  • Arrays aus Punkten und Slicing
  • np.column_stack

Erst ansehen

Läuft nach einem Klick von YouTube.

chaos-game.py
"""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)

Kein Python auf diesem Computer? Das Notebook führt dasselbe Skript, die Übungen und die Lösungen in deinem Browser aus, in Google Colab. Das Notebook ist auf Englisch.

Zeile für Zeile

  1. vertex = np.column_stack([np.cos(angles), np.sin(angles)])

    Die Ecken des Vielecks: ihre x- und y-Werte nebeneinander, eine Zeile pro Ecke.

  2. c = rng.integers(corners)

    Eine zufällige ganze Zahl von 0 bis corners − 1: die Ecke, auf die gesprungen wird.

  3. while no_repeat and c == last:

    Das eingeschränkte Spiel: Solange die neue Ecke die letzte ist, wird noch einmal gezogen.

  4. x = x + r * (vertex[c] - x)

    Die Regel: Geh den Anteil r des Weges vom Punkt zur Ecke. Mit r = 0.5 auf halbem Weg.

  5. points[i], chosen[i], last = x, c, c

    Den Punkt und seine Ecke speichern und die Ecke für den nächsten Schritt merken.

  6. plt.scatter(points[20:, 0], points[20:, 1], s=0.3, c=chosen[20:], cmap="rainbow")

    Die ersten 20 Punkte auslassen, die noch auf dem Weg zum Fraktal sind, und den Rest nach seiner Ecke einfärben.

Probier es selbst

  1. Zeichne ein Fünfeck, dessen fünf Kopien sich gerade berühren.

    Hinweis

    Ändere corners und r in einer Zeile.

    Lösung

    corners, r, no_repeat = 5, 0.618, False

  2. Warum lässt das Diagramm die ersten 20 Punkte aus?

    Hinweis

    Wo startet der Punkt?

    Lösung

    Er startet in der Mitte, die nicht auf dem Fraktal liegt. Jeder Sprung halbiert seinen Abstand zum Fraktal, also ist er nach 20 Sprüngen weniger als ein Millionstel (2⁻²⁰) des Bildes entfernt.

  3. Spiel das Quadratspiel mit und ohne no_repeat. Was ändert sich?

    Hinweis

    corners = 4, r = 0.5.

    Lösung

    Ohne die Einschränkung füllen die Punkte einfach das Quadrat; mit no_repeat = True erscheint ein Fraktal.

Quiz

1. Was kann rng.integers(3) zurückgeben?
2. Was ist x + 0.5 * (corner - x)?
3. Warum behält die Schleife die Variable last?
4. Was wählt points[20:, 0] aus?
5. Warum zeichnet eine zufällige Reihenfolge trotzdem ein genaues Bild?

Lernkarten

Lies die Vorderseite, sag dir die Rückseite vor, dann öffne die Karte.

  • rng.integers(n)

    Eine zufällige ganze Zahl von 0 bis n − 1.

  • while condition:

    Wiederholt seinen Block, solange die Bedingung True ist.

  • a[20:, 0]

    Zeilen 20 bis zum Ende, Spalte 0, eines 2D-Arrays.

  • Kontraktion

    Ein Schritt, der zwei beliebige Punkte näher zusammenbringt, wie ein Sprung auf halbem Weg zu einer Ecke.

  • Attraktor

    Die Form, auf die wiederholte Schritte jeden Punkt ziehen: hier das Sierpiński-Dreieck.

Diese Lernkarten auf einer eigenen Seite →