L-system(2日目)
L-systemで帰納的に作った文字列を図形として解釈してプロットします。解釈の方法をturtle interpretationと言います。
コッホ曲線
植物を作るときに使う記号は6種類あります:
- F:線を描きながら単位長さ進む
- f:線を描かずに単位長さ進む
- +:亀の向きを回転させる
- -:亀の向きを回転させる
- [:亀の位置と向きをスタックにプッシュする
- ]:亀の位置と向きをスタックからポップする
まずは、使っている記号が少ないものを試すため、置換規則「F → F+F--F+F」(は60°)を使います。これはコッホ曲線の置換規則で、置換前後でFの数が1つから4つになっているので、1つの線分が4つの線分になっていると分かります。また、使っている文字は、F+-だけなので一筆書きできる経路が生成されます。
from math import sin, cos, pi import matplotlib.pyplot as plt import matplotlib.cm as cm import matplotlib.collections as mc n = 3 s = 'F' for i in range(0,n): ss = s.translate(s.maketrans({'F' : 'F+F--F+F'})) s = ss print(s) # Make lines from string delta = 60 / 180 * pi # Angle for +/- symbol p0 = (0., 0.) # Initial point theta = 0 / 180 * pi # Initial direction of a turtle lines = [] for i in range(1,len(s)): if s[i] == 'F': p1 = tuple([x + y for (x, y) in zip(p0, (cos(theta), sin(theta)))]) line = [p0, p1] lines.append(line) p0 = p1 elif s[i] == '-': theta -= delta elif s[i] == '+': theta += delta print(lines) # Visualize the result colors = [cm.viridis(i/len(lines)) for i in range(len(lines))] lc = mc.LineCollection(lines, colors=colors) fig, ax = plt.subplots() ax.add_collection(lc) ax.autoscale() ax.set_aspect('equal') plt.show() print(s)
植物らしい形
次に、ブラケットを使ってもっと植物らしい形を作ります。上のコードの中の文字列を線分に解釈する部分に、現在の状態をスタックに保存するコードと、スタックに保存した状態を呼び出すコードを追加します。置換規則は「F → F[+F]F[-F]F」とします。
stack = [] for i in range(1,len(s)): if s[i] == 'F': p1 = tuple([x + y for (x, y) in zip(p0, (cos(theta), sin(theta)))]) line = [p0, p1] lines.append(line) p0 = p1 elif s[i] == '-': theta -= delta elif s[i] == '+': theta += delta elif s[i] == '[': state = (theta, p0) stack.append(state) elif s[i] == ']': state = stack.pop() theta = state[0] p0 = state[1]
参考文献
https://aidiary.hatenablog.com/entry/20131125/1385385271 ー aidiaryさんのブログ http://www.kk62526.server-shared.com/Lsys/index.html ー KK62526さんのホームページ https://repository.kulib.kyoto-u.ac.jp/dspace/bitstream/2433/95243/1/KJ00004760964.pdf ー 京大の発表レポジトリ