Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonでフラクタルツリーを描画する方法|pygame・Turtleモジュールの実装例

フラクタルパターンは自然界のいたるところに存在します。例えば、シダの葉の一部を切り取ってみると、その小さな部分が葉全体とよく似た形をしていたり、小さな石ころが山のシルエットに resembling していたりします。このように「小さなパターンの繰り返しによって大きなパターンを生み出す」という考え方を、フラクタルと呼びます。

Pythonプログラミングでは、標準的・サードパーティ製のさまざまなモジュールを活用することで、こうしたフラクタルツリーを簡単に生成できます。本記事では、代表的な2つの手法――pygameモジュールTurtleモジュールを使った実装方法を、サンプルコード付きで解説します。

pygameモジュールを使う方法

pygameは、グラフィックス描画に必要な関数を豊富に備えたモジュールです。フラクタルツリーを描く際には、まず画面(ウィンドウ)のサイズを定義し、次にパターンを繰り返す深さ(深層度)を指定します。

ポイントとなるのは再帰処理です。同じ描画パターンを一定の深さに達するまで繰り返し呼び出すことで、幹から枝へと分岐していく木の構造が自動的に描かれます。

サンプルコード

import pygame, math

pygame.init()
screen = pygame.display.set_mode((750, 650))
pygame.display.set_caption("Fractal Tree")
display = pygame.display.get_surface()

def drawTree(a, b, pos, deepness):
    if deepness:
        c = a + int(math.cos(math.radians(pos)) * deepness * 10.0)
        d = b + int(math.sin(math.radians(pos)) * deepness * 10.0)
        pygame.draw.line(display, (127,255,0), (a, b), (c, d), 1)
        drawTree(c, d, pos - 25, deepness - 1)
        drawTree(c, d, pos + 25, deepness - 1)

def process(event):
    if event.type == pygame.QUIT:
        exit(0)

drawTree(370, 650, -90, 10)
pygame.display.flip()
while True:
    process(pygame.event.wait())

このコードでは、drawTree 関数が三角関数(cos・sin)を使って枝の先端座標を計算し、線を描画した後に左右それぞれ25度ずつ角度を変えて自分自身を再帰呼び出ししています。引数 deepness が0になると再帰が停止し、木全体の描画が完了します。

実行結果

上記のコードを実行すると、以下のように美しいフラクタルツリーが表示されます。

Pythonでフラクタルツリーを描画する方法|pygame・Turtleモジュールの実装例

Turtleモジュールを使う方法

Python標準ライブラリのturtleモジュールでも、同様のアプローチでフラクタルツリーを描けます。タートル(カメ)が描画の向きを変えながら枝を描いていくイメージです。関数が自分自身を繰り返す際の回転角度を定義しておけば、プログラムが自動的に完全な木の形を描き上げてくれます。

サンプルコード

import turtle

def tree(Length, n):
    if Length > 10:
        n.forward(Length)
        n.right(25)
        tree(Length - 15, n)
        n.left(50)
        tree(Length - 15, n)
        n.right(25)
        n.backward(Length)

def function():
    n = turtle.Turtle()
    data = turtle.Screen()
    n.left(90)
    n.up()
    n.backward(100)
    n.down()
    n.color("green")
    tree(85, n)
    data.exitonclick()

function()

このコードでは、tree 関数が枝の長さ Length を受け取り、前進→右25度回転→再帰呼び出し→左50度回転→再帰呼び出し、という流れで対称的な枝を描きます。長さが10以下になった時点で再帰を終了する仕組みです。

実行結果

上記のコードを実行すると、緑色のフラクタルツリーが描画されます。画面をクリックするとウィンドウが閉じます。

Pythonでフラクタルツリーを描画する方法|pygame・Turtleモジュールの実装例

まとめ

フラクタルツリーの描画は、再帰処理の理解に最適な題材です。pygameを使えば高速で柔軟な描画が可能になり、turtleを使えば直感的でシンプルなコードで実現できます。角度や深さ、枝の長さの減少量などを変更してみると、まったく異なる樹形が生まれるので、ぜひいろいろ試してみてください。

  1. Pythonで2つの二分木の葉の走査(リーフトラバーサル)が同じかどうかを判定する方法

    問題概要2つの二分木が与えられたとき、それらの「葉の走査(リーフトラバーサル)」が同じかどうかを判定する問題を考えてみましょう。葉の走査とは、木を左から右へと辿ったときに現れる葉ノードの値の並び順のことです。例えば、次のような2つの二分木が入力として与えられた場合を考えます。この場合、両方の木の葉の走査順序は [5, 7, 8] で同一であるため、出力は True になります。アルゴリズムの考え方この問題は、再帰を使わずにスタック(LIFO構造)を利用して反復的に解くことができます。各木について、内部ノードの子をスタックに積みながら葉ノードを1つずつ取り出し、2つの木から取り出した葉の値を順番

  2. 【初心者向け】Pythonのissuperset()メソッドの使い方をわかりやすく解説

    はじめにこの記事では、Pythonのissuperset()メソッドについて、基本的な仕組みから実際のコード例まで詳しく解説します。issuperset()は、セット(集合)に対して使用できるメソッドで、引数として渡されたセットのすべての要素が、呼び出し元のセットに含まれているかどうかを判定します。呼び出し元のセットBが、引数のセットAのすべての要素を含んでいる場合 → True を返すセットAの要素がすべてBに含まれていない場合 → False を返すつまり、「BがAの上位集合(スーパーセット)であるかどうか」を判定するためのメソッドです。基本構文B.issuperset(A)この式は、Bが