中級 · カオスゲーム

レッスン4:覚えているループ

Pythonで 「カオスゲーム」 を作りながら、次のことを学びます:

  • 状態を1ステップから次へ引き継ぐループ
  • rng.integers による整数の乱数
  • 条件のための while ループ
  • 点の配列とスライス
  • np.column_stack

まず見てみる

クリックすると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)

このコンピューターにPythonが入っていませんか?ノートブックなら、同じスクリプト、練習問題、答えを、ブラウザ上のGoogle Colabで実行できます。ノートブックは英語です。

1行ずつ

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

    多角形の頂点です。x と y の値を横に並べ、1行が頂点1つになります。

  2. c = rng.integers(corners)

    0から corners − 1 までの整数の乱数。跳んでいく先の頂点です。

  3. while no_repeat and c == last:

    制限つきのゲームです。新しい頂点が直前のものと同じあいだは、引き直します。

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

    ルールです。点から頂点までの道のりの r の割合だけ進みます。r = 0.5 なら半分です。

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

    点とその頂点を保存し、次のステップのために頂点を覚えておきます。

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

    まだフラクタルへ向かう途中の最初の20点を飛ばし、残りを頂点ごとに色分けします。

やってみよう

  1. 5つのコピーがちょうど接し合う五角形を描いてみましょう。

    ヒント

    1行で corners と r を変えます。

    答え

    corners, r, no_repeat = 5, 0.618, False

  2. 図で最初の20点を飛ばすのはなぜですか?

    ヒント

    点はどこから出発しますか?

    答え

    点はフラクタルの上にない中心から出発します。1回跳ぶごとにフラクタルまでの距離が半分になるので、20回跳ぶと、その距離は絵の大きさの100万分の1(2⁻²⁰)より小さくなります。

  3. 正方形のゲームを、no_repeat ありとなしで試してみましょう。何が変わりますか?

    ヒント

    corners = 4、r = 0.5。

    答え

    制限なしでは点はただ正方形を埋めるだけですが、no_repeat = True にするとフラクタルが現れます。

クイズ

1. rng.integers(3) は何を返しえますか?
2. x + 0.5 * (corner - x) は何ですか?
3. ループが変数 last を保っておくのはなぜですか?
4. points[20:, 0] は何を選びますか?
5. 順番がでたらめなのに、正確な絵が描かれるのはなぜですか?

フラッシュカード

表を読み、裏に何があるかを自分で言ってみてから、カードを開いてください。

  • rng.integers(n)

    0から n − 1 までの整数の乱数。

  • while condition:

    条件が True のあいだ、そのブロックを繰り返します。

  • a[20:, 0]

    2次元配列の、20行目から最後までの行の0列目。

  • 縮小写像

    どんな2点も互いに近づけるステップ。頂点へ半分だけ跳ぶ跳躍のように。

  • アトラクター

    繰り返しのステップがすべての点を引き寄せる形。ここではシェルピンスキーの三角形。

このフラッシュカードを別のページで →