YutaKa Notebook | Python徹底図解ブログ!

Python の文法やモジュール、Python関連のAPIについて画像・ソースコード付きで徹底解説!

Python turtle|組み込みモジュールturtleで桜を描こう!

pythonの標準ライブラリには、turtleという絵画用ライブラリがあります。

操作も簡単で、子供たちのプログラミング入門にも人気だそうです。

今回は、簡単な使用方法とその応用例としてturtleで桜を描く方法を紹介します。

turtleの基本的な使用方法

絵画を描くのに必要な最低限の機能をサンプルコード付きで紹介します。

詳しく知りたい方は、公式ドキュメントを参照してください。

絵画領域とタートルの作成

まずturtule.setup()関数で絵画領域を作成します。

その中に、タートルインスタンスturtle.Turtle()を作成します。

このタートルが、絵画領域内を走り回って、線を描きます。

import turtle
turtle.setup(width=300, height=300)  # 絵画領域の作成
my_turtle = turtle.Turtle()  # タートル

絵画領域の座標は(x, y)形式で、中心が(0, 0)です。

タートルを移動させる:forward(), setpos()

次の2つの移動方法を紹介します。

タートルの移動方法

forward(n):タートルが向いている方向に、nだけ前進

setpos(x, y):引数で指定した座標(x, y)に、タートルが移動

⇒移動する際に、タートルは線を描きます。

実際に移動してみます。

my_turtle.forward(100)  # 100前進
my_turtle.setpos(0, -100) #(0, -100)に移動

タートルが移動した際に、線を引きたくない場合には、penup()を実行します。

すると、次にpendown()が実行されるまで線が引かれなくなります。

my_turtle.penup() # 筆を上げる
my_turtle.forward(50)  # 100前進(筆が上がってるので線ひかない)
my_turtle.pendown() # 筆を下ろす
my_turtle.forward(-50)  # 100前進(筆が下がってるので線ひく)

タートルを回転させる:setheading()

setheading()では、指定した角度にタートルが回転します。

タートルの向き

右向き:setheading(0)

上向き:setheading(90)

左向き:setheading(180)

下向き:setheading(270)

回転と前進を、組み合わせると様々な線が引けます。

my_turtle.setheading(90)  # 上を向く
my_turtle.forward(100)  # 100前進

点を描く:dot()

dot()関数で、タートルがいる場所に●を描けます。

dot(n, "color")とすると、nでサイズを指定、"color"で色を指定できます。

my_turtle.dot(10, "red") # 赤丸を描く

これで線と●が自由に描けます。

あとはアイデアしだいで、いろいろなことができますよ!

応用turtleで桜を描く

タートルの基本機能を組む合わせて、桜を描いてみましょう。

ここで説明するスクリプトを実行すると、こんな桜が描けます。

サンプルコードのgistもありますので、ぜひ遊んでみてください!

hanasaka_python_simple.py · GitHub

桜を描く方法は次のサイトを参考に作成しました。

How to draw a beautiful tree 2.0 with Python - Programmer Sought

使用ライブラリ

turtlerandomのみです。

どちらも組み込みライブラリなので、importするだけです。

import turtle
import random

メインスクリプト

まずは、メインスクリプトを紹介します。

(クラスを作成すればもう少しすっきりします。今回は多くの人に楽しんでいただきたいので関数で作りました)

初期設定、種まき、木の成長、開花というフローになっています。

if __name__ == "__main__":
    # 絵画領域の準備
    turtle.setup(width=300, height=300)
 
    # タートルの用意
    my_turtle = turtle.Turtle()
    my_turtle.speed(0)  # タートルの移動速度の設定
    my_turtle.setheading(90)  # 上向きにする
 
    # 枝の短点を格納するリストを用意しておく
    bloom_point = []
 
    # 木が生える場所に種をまく
    seed(x=0, y=-150, my_turtle=my_turtle)
 
    # 木を成長させる
    tree(n=5, length=40, my_turtle=my_turtle, bloom_point=bloom_point)
 
    # 花を咲かせる
    bloom(my_turtle=my_turtle, bloom_point=bloom_point)
 
    # 終了後も絵画領域を表示させたままにする
    turtle.done()

次に各関数の中身を作成していきます。

種まき

オシャレに種まきseedと名付けましたが、木が生える場所にタートルを移動させるだけです。

def seed(x, y, my_turtle):
    # (x, y)にタートルを移動させる
    my_turtle.pu()  # 移動時、線を引かない
    my_turtle.setposition(x, y)

木を育てる

枝や幹を描く再起関数を作成します。

再起関数のフロー

幹から枝の先端まで、n回の分岐をするとする。

①幹を描いたら、先端でn1減らして、枝を描く。

n1減らして、枝を描く。

n0になったら、n=1に戻って分岐があればまた枝を描く。

③'分岐がなければ、n1増やして分岐があるか調べる。

このフローを再起関数で実現します。

def tree(n, length, my_turtle, bloom_point):
    # 幹または枝を描く
    my_turtle.pd()
    my_turtle.pensize(n)
    my_turtle.forward(length)

    # 描いている枝が、先端(n=0)でなければ、さらに分岐した枝を描く
    if n > 0:
        # 枝が生える分岐点の座標を記録
        branch_point = my_turtle.pos()

        # 分岐点から生える枝の数を2~4本でランダムに選ぶ
        branch_number = random.randint(2, 4)

        # 枝を1本ずつ
        for _ in range(branch_number):
            # 枝の角度、長さをランダムに決める
            branch_angle = random.uniform(-45, 45)
            branch_length = length * random.uniform(0.75, 0.9)

            # 枝の方向を向く
            my_turtle.right(branch_angle)
            # 再起関数で、もう一段細い枝を描く
            tree(n - 1, branch_length, my_turtle, bloom_point)
            # 枝の方向からもとの角度に戻る
            my_turtle.left(branch_angle)

            # 枝の分岐点に戻る
            my_turtle.pu()
            my_turtle.setpos(branch_point)

    # 描いている枝が、先端(n=0)であれば、座標を記録する
    else:
        # 枝の先端を記録
        bloom_point.append(my_turtle.pos())

ここではカウンターnを減らしながら、再起関数を呼ぶテクニックを利用しています。

再起関数のテクニック

・カウンターnを減らしながら実行

n>0nn-1にして、再起関数を内部で呼ぶ

・条件を満たしたら終了処理

n=0:先端の位置の記録

このテクニックを使用すれば再起関数を簡単に自作できます。

花が咲く

枝の先端にタートルを移動して、ピンクの円を描きます。

def bloom(my_turtle, bloom_point):
    my_turtle.pu()
    for position in bloom_point:
        # 花の場所に移動
        my_turtle.setpos(position)
        # 花が咲く
        my_turtle.dot(8, "pink")

あとはメインスクリプトを実行するだけです!

おわりに

今回はturtleを使用して、桜を描く方法を紹介しました。

工夫次第でいろいろなことができそうです!

ちなみに、クラスを作成したサンプルコードはこちらです。

hanasaka_python.py · GitHub

少しすっきりしてますね、桜を2本描くのも楽々です!