昨日に引き続きフラクタル図形の話です。

Pythonには便利なライブラリが有るので
それを使ってみましょう。

解説動画はこちら




Pythonには
タートル(turtle)と言う描画用の
ライブラリがあります。

これは亀さんを操作して
亀さんが色々作図してくれるという
ライブラリです(笑)。


ライブラリの呼び出しは
from turtle import *

主なメソッドとしては
fd(距離):タートルを距離分前に進ませ線を描く
rt(角度):タートルの向きを右向きに角度分変える
circle(大きさ):円を描く
done():最後につける

などがあります。

早速作図してみましょう。

四角形を描画するなら
from turtle import *

for _ in range(4):
    fd(100)
    rt(90)

done()
スクリーンショット 2020-12-13 16.53.22
多角形を描くなら
角度を変えてあげます。
from turtle import *

N=12
for _ in range(N):
    fd(50)
    rt(360//N)

done()
スクリーンショット 2020-12-13 16.53.35
円形に円を並べて描いてみます。
circle()で円を小さな描いています。
from turtle import *

speed(0)
pu()
setpos(0, 50)
pd()
pensize(4)

n = 30
angle = 360//n

for i in range(n):
    pencolor(((i/n), 0, 1.0-(i/n)))
    fd(15)
    rt(angle)
    circle(30)

done()
スクリーンショット 2020-12-13 16.53.48
色々組み合わせると面白いものが描けます。
六角形を並べてオウムガイっぽいのを
描いてみます。
from turtle import *

def hexagon(length):
    for _ in range(6):
        fd(length)
        rt(60)

def spindle(n, length, angle):
    for _ in range(n):
        hexagon(length)
        rt(angle)
        length = length*1.05

n = 100
length = 3
angle = 10
speed(0)

spindle(n, length, angle)
done()
スクリーンショット 2020-12-13 16.54.20
次は森っぽいものです。
三角形の木を描きますが
その途中で三角形を再帰を用いて
付け足していくと
木から森っぽくなります。
from turtle import *

def forest(n, length=1500):
    if n <= 0:
        fd(length)
        return
    forest(n-1, length * 0.5)
    rt(80)
    forest(n-1, length / 3)
    lt(160)
    forest(n-1, length / 3)
    rt(80)
    forest(n-1, length * 0.3)

pu()
setpos(500, -200)
pd()
lt(180)
speed(0)
forest(5)
done()
スクリーンショット 2020-12-13 16.55.13
お次はヒルベルト曲線です。
from turtle import *

def hilbert(n, length):
    l_turn(n, length)

def l_turn(n, length):
    if n <= 0:
        return
    rt(90)
    r_turn(n-1, length)
    fd(length)
    lt(90)
    l_turn(n-1, length)
    fd(length)
    l_turn(n-1, length)
    lt(90)
    fd(length)
    r_turn(n-1, length)
    rt(90)

def r_turn(n, length):
    if n <= 0:
        return
    lt(90)
    l_turn(n-1, length)
    fd(length)
    rt(90)
    r_turn(n-1, length)
    fd(length)
    r_turn(n-1, length)
    rt(90)
    fd(length)
    l_turn(n-1, length)
    lt(90)

pu()
setpos(-200, 200)
pd()
speed(0)
pensize(10)
hilbert(4, 20)
done()
スクリーンショット 2020-12-13 16.55.39
再帰を用いて描いています。

お次はシェルピンスキー曲線です。
from turtle import *

def sierpinski(n, length=8, angle=45):
    if n <= 0:
        fd(length)
        return
    rt(angle)
    sierpinski(n-1, length, -angle)
    lt(angle)
    fd(length)
    lt(angle)
    sierpinski(n-1, length, -angle)
    rt(angle)

lt(90)
speed(0)
length=10
pensize(3)
for _ in range(4):
    sierpinski(7, length)
    rt(45)
    fd(length)
    rt(45)
done()
スクリーンショット 2020-12-13 16.56.44
なんて表現すれば良いか分かりませんが
だんだん複雑になってきました。

次はドラゴン曲線です。
ラーメン丼にアリそうなやつです。
from turtle import *

def dragon(n, length=500):
    dragon_r(n, length)

def dragon_r(n, length):
    length /= 1.414
    if n <= 0:
        fd(length)
        return
    rt(45)
    dragon_r(n-1, length)
    lt(90)
    doragon_l(n-1, length)
    rt(45)

def doragon_l(n, length):
    length /= 1.414
    if n <= 0:
        fd(length)
        return
    lt(45)
    dragon_r(n-1, length)
    rt(90)
    doragon_l(n-1, length)
    lt(45)

pu()
setpos(-100, 0)
pd()
speed(0)
pensize(3)
dragon(10)
done()

複雑なやつは描くのに時間がかかりますね。

タートルにはデモスクリプトがついているので
簡単に試して結果を見ることができます。

スクリーンショット 2020-12-13 16.53.02
複雑なフラクタル図形も
有るみたいなので
色々遊んでみると面白いです。

興味がある人は
是非遊んでみてください。

それでは。