目次
Pythonで「バーンズリーのシダ」っぽいのを描く
今回は、Pythonで「バーンズリーのシダ」を描画してみます。
フラクタルは、全体と一部が自己相似(つまり、全体を見ても、それを構成する一部を見ても同じ形状が現れる)になっている図形です。
今回は、それを`Pythonとmatplotlibのグラフ描画機能を使って描きます。
ただ、散布図グラフを使い、ドットで描く実装にしたせいか、できあがった図をみるとたしかに「シダ」なんですけど、フラクタルっぽくはないです。
なので、「バーンズリーのシダ」っぽい・・としてます(笑)
ソースコード
ソースコードです。
class_graphics.py
from matplotlib import pyplot as plt import random class Fern(): def __init__(self): self.__tx = [0] self.__ty = [0] self.__title = "バーンズリーのシダっぽいの" def __tran_1(self, p): x = p[0] y = p[1] x1 = 0.85 * x + 0.04 * y y1 = -0.04 * x + 0.85 * y + 1.6 return x1, y1 def __tran_2(self, p): x = p[0] y = p[1] x1 = 0.2 * x - 0.26 * y y1 = 0.23 * x + 0.22 * y + 1.6 return x1, y1 def __tran_3(self, p): x = p[0] y = p[1] x1 = -0.15 * x + 0.28 * y y1 = 0.26 * x + 0.24 * y + 0.44 return x1, y1 def __tran_4(self, p): # x = p[0] y = p[1] x1 = 0 y1 = 0.16 * y return x1, y1 def __get_index(self): prob = [0.85, 0.07, 0.07, 0.01] r = random.random() c = 0 sump = [] for p in prob: c += p sump.append(c) for item, sp in enumerate(sump): if(r <= sp): return item return len(prob) - 1 def __tran(self, p): trans = [self.__tran_1, self.__tran_2, self.__tran_3, self.__tran_4] tindex = self.__get_index() t = trans[tindex] x, y = t(p) return x, y def __draw(self, n): x1 = 0 y1 = 0 for i in range(n): x1, y1 = self.__tran((x1, y1)) self.__tx.append(x1) self.__ty.append(y1) return self.__tx, self.__ty def draw(self, n=10000): x, y = self.__draw(n) plt.plot(x, y, '.') plt.title(self.__title) plt.show()
ソースコードの補足説明
メインの処理は「__draw()」です。
座標を示す「x1、y1」を更新しながら、「n」で指定した回数繰り返します。
nは、デフォルトで10000回にしてます。
ここの数字を変えると、図形の密度が変わります。
x1,y1を更新する処理は「__tran()」です。
pというタプルで(x1,y1)を受け取り,それを引数にして「tran_1」「tran_2」「tran_3」「tran_4」のいずれかのメソッドをよびだします。
どのメソッドを呼び出すかを決めるのは「__get_index()」です。
prob=[0.85,0.07,0.07,0.01]のリストを順番に加算した値と、乱数を比較して、乱数が合計値よりも小さかったら、そのインデックスを返します。
この数字を変更すると、できあがる図形の形が変わります。
シダの葉っぱのような図形にするには、この値が適切といわれてます。
入力された「x1とy1」の変換の仕方が4パターンあります。
1パターン目
x1 = 0.85*x + 0.04*y
y1 = -0.04*x + 0.85*y + 1.6
2パターン目
x1 = 0.2*x - 0.26*y
y1 = 0.23*x + 0.22*y + 1.6
3パターン目
x1 = -0.15*x + 0.28*y
y1 = 0.26*x + 0.24*y + 0.44
4パターン目
x1 = 0
y1 = 0.16*y
このパターンをランダムに繰り返していくことで、図形を描き出していくわけです。
実行して描かれたイメージ
ソースはこんな感じです。
デフォルトで実行すると、こういう図形が描けます。
ただ、点をうつことで描画しているので、回数を減らして1000回くらいにすると。
上記のように、スカスカになります(笑)
おまけの情報
こちらの記事と見比べてもらうとわかると思うのですが.
今回の「シダの葉」を描くプログラムと、「シェルピンスキーのギャスケット」を描くプログラムは、x1・y1の変換する部分の比率と、__get_index()のリストの数値が違うだけで、ほぼ、構造は同じです。
なので。
この構造のままで、いろいろと数値を変えrると他の図形も描けそうだなと、思ってはいますが試してはいません。。
いちおう、参考情報です。
ではでは。
*1:x1, y1