중급 · 카오스 게임

4강: 기억하는 반복문

Python으로 “카오스 게임” 패턴을 만들면서 배워요:

  • 단계에서 단계로 상태를 이어 가는 반복문
  • 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. vertex = np.column_stack([np.cos(angles), np.sin(angles)])

    다각형의 꼭짓점들이에요. x 값과 y 값을 나란히 놓아 꼭짓점 하나에 행 하나예요.

  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. 복사본 다섯 개가 딱 닿는 오각형을 그려 보세요.

    힌트

    한 줄에서 corners와 r을 바꾸세요.

    정답

    corners, r, no_repeat = 5, 0.618, False

  2. 그림에서 처음 20개의 점을 건너뛰는 이유는 무엇일까요?

    힌트

    점은 어디에서 출발하나요?

    정답

    점은 프랙털 위에 있지 않은 중심에서 출발해요. 점프할 때마다 프랙털까지의 거리가 절반이 되므로, 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번 열.

  • 축소 사상

    어떤 두 점이든 더 가깝게 만드는 단계. 꼭짓점을 향한 절반 점프처럼요.

  • 끌개

    되풀이되는 단계가 모든 점을 끌어오는 모양: 여기서는 시에르핀스키 삼각형.

이 플래시카드만 따로 보기 →