5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

「プログラムでシダを描画する」をPythonで描画する - 再帰なし+ジェネレータ版 -

Posted at

「プログラムでシダを描画する」にようやく参加できた!

@noc06140728 さんのコードをベースに作成しました。ありがとうございます。

##変更点

  • 再帰をなくしてジェネレータだけを使用
  • 画像に濃淡を持たせた
  • 関数をパラメータを各々ひとまとめにした

##出力結果
fern.png

##コード


# coding: utf-8
import random

N = 1000000

WIDTH = 500
HEIGHT = 500

fern = [
    [1.0, [+0.836, +0.044, 0.0, -0.044, +0.836, 0.169]],
    [0.3, [-0.141, +0.302, 0.0, +0.302, +0.0141,0.127]],
    [0.3, [+0.141, -0.302, 0.0, +0.302, +0.141, 0.169]],
    [0.3, [0.0, 0.0, 0.0, 0.0, 0.175337, 0.0]],
]

p_table = []


def W(n,v):
    c = fern[n][1]
    return (c[0] * v[0] + c[1] * v[1] + c[2], c[3] * v[0] + c[4] * v[1] + c[5])
 

# Python 2.7 には itertools.accumulate がないので以下から借用して簡略化
# http://docs.python.jp/3.3/library/itertools.html#itertools.accumulate 
def accumulate(iterable):
    it = iter(iterable)
    total = next(it)
    yield total
    for e in it:
        total = total + e
        yield total

        
def g(v, n):
    it = 0
    while it < n:
        it += 1
        yield v
        r = random.random()
        for i, p in enumerate(p_table):
            if r < p:
                v = W(i,v)
                break;
                
                
if __name__ == '__main__':
    # 確率の値ををならす
    p_total = sum(f[0] for f in fern)
    p_table = [a/p_total for a in accumulate([f[0] for f in fern])]
    
    # 点の軌跡を溜めておくバッファ
    acc = [0] * 3 * WIDTH * HEIGHT
    # 最初の点
    v = (0.0, 0.0)
    acc_max = 1
    for p in g(v, N):
        x, y = (int((p[0] + 0.5) * WIDTH), HEIGHT - int(p[1] * HEIGHT))
        if x >=0 and x < WIDTH and y >= 0 and y < HEIGHT:
            acc_index = x + y * HEIGHT
            acc[acc_index] += 1
            if acc[acc_index] > acc_max:
                acc_max = acc[acc_index] 
    
    from math import pow
    from PIL import Image
    im = Image.new("RGB", (WIDTH, HEIGHT), (255, 255, 255))
    pix = im.load()
    
    for i in xrange(WIDTH * HEIGHT):
        #if acc[i]:
        # 暗いところを持ち上げる
        d = int(pow(float(acc[i]) / float(acc_max),1.0/15.0) * 255.0)
        pix[i % WIDTH, i / WIDTH] = (0, d, 0)
            
    im.show()

##まとめ
楽しかった!

5
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?