初級 · 円周上の掛け算

レッスン2:ループと余り

Pythonで 「円周上の掛け算」 を作りながら、次のことを学びます:

  • zip で組にしたものを回す for ループ
  • 余り % と、ひと回りして戻る角度
  • plt.plot で2点を結ぶ線
  • パラメーターをひとつ変えて探る

まず見てみる

クリックするとYouTubeから再生されます。

times-table.py
"""Times table on a circle: N dots, each dot n joined to dot (k * n) mod N.
Run: python times-table.py   (needs: pip install numpy matplotlib)
"""
import numpy as np
import matplotlib.pyplot as plt

plt.style.use("dark_background")

N, k = 200, 2  # the number of dots and the multiplier

start = 2 * np.pi * np.arange(N) / N  # dot n at the angle 2*pi*n/N
end = start * k  # dot k*n: angles wrap around the circle by themselves (that is the "mod N")

plt.figure(figsize=(6, 6))
for a, b in zip(start, end):
    plt.plot([np.cos(a), np.cos(b)], [np.sin(a), np.sin(b)], color="#f5c76b", linewidth=0.6)
plt.axis("equal")
plt.axis("off")
plt.show()

# Try: k = 3 for the nephroid, k = 101 to see it collapse into diameters

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

1行ずつ

  1. N, k = 200, 2

    2つの名前をいっぺんに:点が200個、倍率が2。変えてみるのは、この2つの数です。

  2. start = 2 * np.pi * np.arange(N) / N

    各点の角度です。点nは 2π·n / N の位置にあるので、200個の点が円を均等に分け合います。

  3. end = start * k

    点k·nの角度です。2πを超えた角度はただもうひと回りするだけなので、それが代わりに折り返し(k·n mod N)をしてくれます。

  4. for a, b in zip(start, end):

    zip は2つの配列を組にします。ループは1回ごとに、始点の角度をひとつ、その終点の角度といっしょに受け取ります。

  5. plt.plot([np.cos(a), np.cos(b)], [np.sin(a), np.sin(b)], color="#f5c76b", linewidth=0.6)

    plt.plot は、線の両端の x の値、次に y の値を受け取ります。1回ごとに、円の弦が1本引かれます。

やってみよう

  1. 3倍と4倍を描いてみましょう。それぞれの曲線には尖点(とがった点)がいくつありますか?

    ヒント

    k を変えます。

    答え

    3倍では尖点が2個のネフロイド、4倍では尖点が3個の曲線になります。いつも k − 1 個です。

  2. 点が200個のとき、150 × 2 はどの点に当たりますか?余りの演算子で計算してみましょう。

    ヒント

    Python では、% が割り算の余りを返します。

    答え

    (150 * 2) % 200 は100です。

  3. 点を200個ではなく20個にしてみましょう。ハートが見えにくくなるのはなぜですか?

    ヒント

    N を変えます。

    答え

    点が20個だと線も20本しかなく、すべての線が接する曲線が浮かび上がるには少なすぎるからです。

クイズ

1. zip(start, end) は、ループに1回ごとに何を渡しますか?
2. Python で 300 % 200 はいくつですか?
3. スクリプトで % を一度も使わないのはなぜですか?
4. plt.plot([x1, x2], [y1, y2]) で、先に来るのはどれですか?
5. 2倍で描かれるのはどの曲線ですか?

フラッシュカード

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

  • zip(a, b)

    2つの列を要素ごとに組にします:(a[0], b[0])、(a[1], b[1])、…

  • x % n

    x を n で割った余り。300 % 200 は100です。

  • plt.plot([x1, x2], [y1, y2])

    (x1, y1) から (x2, y2) への線。

  • 包絡線

    ひと組の線のどれもがちょうど接する曲線。ここではカージオイド。

  • 円周上のk倍

    整数の倍率kは、尖点が k − 1 個の曲線を描きます。

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