子どもの頃、下の写真のようなおもちゃで遊んだ人も多いのではないでしょうか?
画像おもちゃはスピログラフと言う名前で、内側の歯車の穴にペン先を入れて、外側の歯車に噛み合うようにグルグルと回すと奇麗な幾何学模様が現れます。
スピログラフという名は商標名なのですが、このスピログラフで描かれる曲線を数学用語では内トロコイドまたはハイポトロコイド(hypotrochoid)と呼ぶそうです。
昔よく遊んだなぁと思いながら、コンピュータ上で描いてみました。
内トロコイド計算のお試しがてら、基本的な特性を軽く調べてみた動画がこちらです。
曲線の方程式はWikipediaに載っているので、それを写せばすぐに計算できるのですが、方程式を理解するためにも始めから求めてみました。
方程式の求め方
基準となる位置を定めるため図1を初期位置とします。

内円が外円に沿って転がると図2のようになります。
このとき角度$\theta$まで滑らずに転がったときの点$D$の位置を求めます。
$O_f$を原点とし、便利なため、複素平面で考えます。虚数単位は$j$で表します。

外円の半径を$R_f$、内円の半径を$R_r$、$\angle \mathrm{実軸}O_fO_r$を$\theta$とすると$O_r$の位置は
\begin{eqnarray} O_r = (R_f – R_r)\exp(\theta j) \end{eqnarray}
$\angle BO_rD$を$\theta’$、$O_r$から点$D$までの距離を$R_d$とすると、点$D$の位置は
\begin{eqnarray} D &=& O_r + R_d \exp(-\theta’ j) \end{eqnarray}
内円が図2まで転がったときの外円と内円が接した長さは
\begin{eqnarray} R_f \theta &=& R_r (\angle AO_rB+\theta’) &=& R_r (\theta+\theta’) \end{eqnarray}
となるので、
\begin{eqnarray} \theta’ &=& \frac{R_f – R_r}{R_r} \theta &=& (\frac{R_f}{R_r}-1) \theta \end{eqnarray}
となり、式(2)に式(1),(4)を代入すると点$D$の位置は
\begin{eqnarray} D &=& O_r + R_d \exp(-(\frac{R_f}{R_r}-1) \theta j) \\ &=& (R_f – R_r)\exp(\theta i) + R_d \exp((1 – \frac{R_f}{R_r}) \theta j) \\ \end{eqnarray}
となります。これを$xy$平面に直すと、
\begin{eqnarray} D = \begin{cases} x = \mathrm{Re}(D) = (R_f – R_r) \cos \theta + R_d \cos ((1 – \frac{R_f}{R_r})\theta)\\ y = \mathrm{Im}(D) = (R_f – R_r) \sin \theta + R_d \sin ((1 – \frac{R_f}{R_r})\theta)\\ \end{cases} \end{eqnarray}
となります。
元の位置に戻るために必要な周回数
こちらの動画を見て頂くと分かりやすいですが、点$D$は内円が外円を一周すると元に戻るとは限らず、$R_f$、$R_r$の関係で必要な周回数が変わってきます。
そこで本節では点$D$が元の位置に戻るために必要な周回数$N$を求めてみます。
内円が元の位置に戻るときの$\theta$は
\[ \theta = 2\pi N (N \in\mathbb{Z}(\mathrm{整数}))\\ \]
このとき、点$D$が元に戻る場合の関係式は
\begin{eqnarray} (1-\frac{R_f}{R_r})\theta = (1-\frac{R_f}{R_r}) 2\pi N = 2 \pi M \\ (M \in\mathbb{Z}) \end{eqnarray}
となり、$R_f, R_r$が自然数の場合は
\begin{eqnarray} &(1-\frac{R_f}{R_r}) N \in\mathbb{Z} \mathrm{}\\ N \in\mathbb{Z}\mathrm{より} &\\ &\frac{R_f}{R_r} N \in\mathbb{Z} \end{eqnarray}
$R_fとR_r$の最大公約数を$g$とし、$R_f=mg$、$R_r=ng$とおくと
($m,n,g$は自然数)
\[ \frac{R_f}{R_r} N = \frac{mg}{ng}N = \frac{m}{n}N \in\mathbb{Z} \]
となることから
\[ N = ni \]
となります。
これより、必要な最低周回数は$n$となります。
$n$をプログラムで求める手順は2通りあり、pythonの場合はnumpyの最大公約数を求める関数gcdか最小公倍数を求めるlcmを使って求めます。
import numpy as np
#gcdの場合
Rr/np.gcd(Rf, Rr)
#lcmの場合
np.lcm(Rf, Rr)/Rf
gcd($mg,ng$)からは$g$が求まり、lcm($mg,ng$)からは$nmg$が求まるので、$R_r=ng$からgを割るか$nmg$から$R_f=mg$を割ることで$n$が求まります。
以上のように、方程式と周回数が求まると図3のような図形を描くことができます。

余談ですが、点$D$が内円を回る回数は式(8),(11)より
\[ M = (1 – \frac{mg}{ng})*ni = ni – mi = (n-m)i \]
となります。
いろいろな条件による計算結果
求めた関係式を使って様々な条件で計算してみました。その結果動画を紹介します。補足ですが、時計回りに内円を転がしたかったので、縦が実軸($X$)、横が虚軸($Y$)になっています。
糸かけ曼荼羅風
以前つくった糸かけ曼荼羅 : 素数ピッチの動画を模してみたのですが、結構近しいものが出来ました。必要な周回数を周回させると時間がかかるので、代わりに点$D$を増やして計算しています。車輪が転がるように見えるのも面白いです。
点描画
線ではなく一定間隔$\Delta \theta$で点を打っていく描画方法です。この動画は一例ですが$\Delta \theta$の値を変えるだけでも模様が変わってきます。
転がる円の半径を変化させる
転がる円の半径$R_r$を変化させていく場合です。実物ではできませんが、シミュレーションでは動画のように$R_r$を$R_f$より大きくすることもできます。
$O_r$から点$D$までの距離$R_d$を変化させる
$R_d$をだんだんと大きく変化させる場合です。こちらもシミュレーションなので$R_d$を$R_r$より大きくすることができます。前半と後半で様相ががらりと変わるのがお気に入りです。
内円の中でさらに円を転がしてみる
内円の中にさらに円を転がし、その円の中心を基点として点$D$の軌跡を描く計算です。先行研究で名前があると思いますが、すぐに見つけられなかったので「内々トロコイド」を名付けておきました。本記事の式だけではこの計算はできないので、別途記事にする予定です。
終わり。