目次
Pythonでタートルグラフィックス:「雪の結晶風図形」(コッホ曲線)
今回は、Pythonで「雪の結晶風図形」(コッホ曲線)を描きます。
matplotlibのグラフの描画機能を使います。
亀が方向を変えて、指定の距離だけ移動して、また方向を変えて、移動するというような動きを繰り返すことで、なんらかの図形が描かれるという考え方の、タートルグラフィックという手法を使います。
図形を描くソースコード
内部で計算にNumpyを使ってます。
class_graphics.py
from matplotlib import pyplot as plt import numpy as np class KochCurve(): def __init__(self): self.__tx = [] self.__ty = [] self.__title = "コッホ曲線(雪の結晶風図形)を描く" def __move(self, leng, lpx, lpy, angle): x = lpx + leng * np.cos(angle * np.pi / 180.0) y = lpy - leng * np.sin(angle * np.pi / 180.0) self.__tx.append(x) self.__ty.append(y) return x, y def __turn(self, angle, chg_angle): ang = angle + chg_angle ang2 = ang - ang + ang % 360.0 return ang2 def __koch(self, leng, lpx, lpy, angle): leng_t = 0.0 px = lpx py = lpy ang = angle if(leng <= 60.0): px, py = self.__move(leng, px, py, ang) else: leng_t = leng / 3.0 px, py = self.__koch(leng_t, px, py, ang) ang = self.__turn(ang, 60.0) px, py = self.__koch(leng_t, px, py, ang) ang = self.__turn(ang, -120.0) px, py = self.__koch(leng_t, px, py, ang) ang = self.__turn(ang, 60.0) px, py = self.__koch(leng_t, px, py, ang) return px, py def __draw(self, r0): x0 = 0.0 y0 = 0.0 sx = x0 - r0 * np.sqrt(3.0) / 2 sy = y0 - r0 / 2 self.__tx.append(sx) self.__ty.append(sy) leng = r0 * np.sqrt(3.0) angle = 0.0 for i in range(3): sx, sy = self.__koch(leng, sx, sy, angle) angle = self.__turn(angle, -120.0) return self.__tx, self.__ty def draw(self, r0=1000.0): tx1, ty1 = self.__draw(r0) plt.plot(tx1, ty1) plt.title(self.__title) plt.show()
ソースコードの補足説明
タートルグラフィックのの「くるっと方向を変える」という部分が
です。
360度の中で、現在が「angle」度の方向を向いているのを「chg_angle」度だけターンするという働きです。
タートルグラフィックの「指定の距離だけ移動する」部分が、
です。
今いる地点(lpx、lpy)から、指定距離(leng)分、今向いている角度(angle)の方向へ移動して、新しい移動地点を記録してます。
これを使って「コッホ曲線」を描く部分が、
です。
指定距離が「60.0」以下になったら、指定距離へ移動します。
そうでない場合は、指定距離を三分の一にして、60度ターンして「__koch()」を呼出し、-120度ターンして「__koch()」を呼出し、さらに60度ターンして「__koch()」を呼び出すということをしてます。
再帰構造というやつです。
この動きで、円の三分の一分の「コッホ曲線」が描けます。
それを円形に配置して雪の結晶っぽくするのが
です。
-120度ずつ角度を変えながら、「__koch()」を3回呼び出す再帰を使ってます。
実行してみます
実行するのはこうします。
パラメータ「r0」があります。
r0 | 直径です。大きな径になるほど、複雑な図形になります。 |
デフォルト(1000.0)で実行すると。
です。
ただ、1000より増やしても、あまり変化がありません。
引数の数字少ない方向に変えていきます。
500にしてみます。
200にしてみます。
こんな感じです。
ではでは。