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
使用ライブラリ
turtle
とrandom
のみです。
どちらも組み込みライブラリなので、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
回の分岐をするとする。
①幹を描いたら、先端でn
を1
減らして、枝を描く。
②n
を1
減らして、枝を描く。
③n
が0
になったら、n=1
に戻って分岐があればまた枝を描く。
③'分岐がなければ、n
を1
増やして分岐があるか調べる。
このフローを再起関数で実現します。
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>0
:n
をn-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
を使用して、桜を描く方法を紹介しました。
工夫次第でいろいろなことができそうです!
ちなみに、クラスを作成したサンプルコードはこちらです。
少しすっきりしてますね、桜を2本描くのも楽々です!