kedzkiestの日記

普段の発見や開発の進捗について書いていきます。

pythonのturtleモジュールを使ってお絵かきしてみる

pythonのturtleを使っていくつか絵を書いてみました。

はじめに

turtleとは、初心者や子供向けのグラフィカルなpython学習環境です。(ソースは古いですがこのサイトを参考にしました)
これを使うと簡単に図形を描くことができます。公式ドキュメントはおそらくここです。

では、どんな事ができるのか見ていきましょう。

サンプルプロジェクト

from turtle import *
color('red', 'yellow')
begin_fill()
while True:
    forward(200)
    left(170)
    if abs(pos()) < 1:
        break
end_fill()
done()

解説
公式ドキュメントに載っているプログラムです。
begin_fill()からend_fill()までの間にペンが動いてできた領域の内側を塗りつぶしています。停止条件のabs(pos()) < 1は、はじめペンの位置が(x, y) = (0, 0)から始まることを考えると、「はじめの位置に戻ってきたら処理を停止」と読み替えても良いかもしれません。

実行結果
youtu.be

ケース1

from turtle import *
import time
import random

pendown()
ht()
speed(0)
begin = time.time()

while True:
    end = time.time()
    if end-begin > 30:
        break
        
    num = random.random()
    if(num < 0.5):
        left(90)
        color('red')
    else:
        right(90)
        color('blue')
        
    forward(10)
    
penup()
done()

解説
ランダムウォーク的なやつです。30秒間処理が続き、その間半々の確率で右か左に向きを変え、塗る色を変えたあと10進むプログラムになっています。この後も出てくるht関数ですが、hide turtleの略で、ペン先(向きを変えて進む三角形)を描画しないよう指定できます。

実行結果
youtu.be

ケース2

from turtle import *
import math

ht()
penup()
setx(-300)
sety(-300)
pendown()
speed(10)
t = 0
while True:
    t = t + 1
    if t > 150:
        break
    
    forward(40)
    left(math.sin(t/360) * 180)
    
    
penup()
done()

解説
三角関数を取り入れてらせんのような動きを表現しました。初めにsetx関数とsety関数で明示的にペン先のスタート位置を指定してからwhileループで描画を始めることで、空間を広く使っています。

実行結果
youtu.be

ケース3

from turtle import *
import random
import time

pendown()
ht()
begin = time.time()
t = 100
speed(0)
while True:
    end = time.time()
    if(end-begin > 100):
        break
    
    num = random.uniform(-300, 300)
    num2 = random.uniform(-300, 300)
    
    goto(num, num2)

penup()
done()

解説
x、yともに-300から300の範囲でランダムにペン先を移動させることで、徐々に空間が線によって埋め尽くされ、全体の輪郭が正方形に近づいていくプログラムです。

実行結果
youtu.be

ケース4

from turtle import *

pendown()
ht()
speed(0)
for i in range(500):
    if i % 2 == 0:
        left(i)
    else:
        right(i)
        
    if i % 4 == 0:
        left(180)
        
    forward(i)
    
penup()
done()

解説
このプログラムだけはwhileループでなくforループの中で描画をしています。ループ変数iが奇数のときは右に、偶数のときは左にiだけ回転し、4の倍数のときは向きを反転させ、いつでもiだけ前に進むプログラムになっています。実行結果を見るとなんだか立体的に見える気もします。

実行結果
youtu.be

おわりに

どうでしたか?20行ほどの簡潔なプログラムで複雑な図形を描画できるのがturtleのすごいところです!思い通りにペンを動かすのは難しいかもしれませんが、ランダム要素や数学関数などを取り入れることで表現の幅を広げられそうです。ぜひお試しあれ。