
目次
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