亀に訊け:Pythonの亀グラフィックス

亀(カメ)は

という単純な行動様式に従って地面を這っている。 カメが這って得られる軌跡をタートル・グラフィックスという。


Pythonにはタートル・グラフィックス を描画するための標準モジュール turtle が備わっている。 クラス turtleのオブジェクト(たとえば kame という名前にする)には次のように書く。

import turtle

kame = turtle.Turtle()

これでタートルオブジェクト(カメ)が生成される。 カメを歩かせるスクリプトを書いてその軌跡を眺めてみると思わぬ発見がある。

turtleオブジェクト kame に対する代表的メソッドを以下に紹介しておく。 次は

Turtleの動きに関するメソッド
method名使用例意味
pendownkame.pendown()kameのペンを下ろす。kame 動くと線が引かれる。
penupkame.penup()kameのペンをあげる。kame が動いても線は引かれない。
forwardkame.forward(distance)現在のkameの方向に距離 distance 進む
backwardkame.backward(distance)現在のkameの方向を向いたまま距離 distance だけ後ずさる(戻る)
setheadingkame.setheading(to_angle)kameの向きを角 to_angle 設定する。
homekame.home(distance)kameを原点(0, 0)に移動し、向きを開始方向に設定。
rightkame.right(angle)現在のkameの向きを角 angle だけ右に回転する。 単位は[度](degree)。
leftkame.left(angle)現在のkameの向きを角 angle だけ左に回転する。 単位は[度](degree)。
radianskame.radians()現在のkameの向き角度をラジアンで計るように設定。
setpositionkame.setposition(x, y)kameを位置 (x, y) に移動。ペンが下りていれば線をひく。kameの向きは変わらない。
gotokeme.goto(x,y)kame.setposition(x,y) と同じ。
setxkame.setx(x)kameのx座標を x にする。y座標値は変わらない。
setykame.sety(y)kameのy座標を y にする。x座標値は変わらない。
speedkame.speed(speed =None)kameのスピードを 1 から 10 までの範囲の整数に設定。引数が与えられないときは、現在のスピードを返す。
Turtleの状態を知るメソッド
method名使用例意味
isdownkame.isdown()ペンが下りていれば True 、上がっていれば False を返す。
positionkame.position()kameの現在位置を ベクトルとして返す。
towardskame.toward(x, y)kameの位置から指定された点 (x,y) への直線の角度を返す。
xcorkame.xcor()kameのx座標を返す。
ycorkame.xcor()kameのy座標を返す。
headingkame.heading()kameの現在の方向を返す。
distancekame.distance(x,y)kameの現在位置から、点(x,y)までの距離を返す。
penの色などのメソッド
method名使用例意味
pencolorkame.pencolor()kameのペン色を返す。
kame.pencolor(colorstring)kameのペンの色をcolorstringに設定。その値は Tk の色指定文字列で("red", "yellow", "#33cc8c" のような文字列)。
kame.pencolor(r, g, b)kameの色をRGB の色に設定。各 r, g, b は 0 から colormode(1.0から255のどちらか)。
kame.fillcolor(colorstring)kameが設定した多角形内を色文字列 colorstring で塗りつぶす。

色名文字列 colorstring として 'black'(デフォルト)以外に、blue', 'red', 'green', 'white', 'yellow', 'violet', 'orange', 'pink' が使える

カメの酔歩

カメが酔ってランダムな距離だけ進み、ランダムな角度で向きを変えながら這ったとする。 これを次のようなスクリプトで表すことができる。

import turtle
import random

wn = turtle.Screen()
tur = turtle.Turtle()
tur.goto(0, 0)

def random_walk(kame, n):
    for n in range(n):
        kame.forward(random.randrange(10, 60))
        kame.left(random.randrange(20, 180))

random_walk(tur, 30)
    
wn.exitonclick()

random.randrange(m, n) は range(m, n) の要素からランダムに選ばれた整数を返す。 この関数を使うために5行目で random モジュールをインポートしている。 7行目は(念のために)タートル用に描画スクリーンを用意した。 18行目は、このままではスクリプトが終了すると描画スクリーンも閉じてしまうので、「クリック待ち」 exitonclick() とするトリックの意味しかない。

上の関数 random_walk(kame, n) は、turtleオブジェクト kame が 距離10から59までのどれかを進んで、角度20から179度までどれかだけ向きを左に変えるて kame が指定された回数 n だけ繰り返す。 繰り返すたびにkameの進む距離や向きがランダムに変わるために、左図のような酔っている様子が描かれる。


演習: 上のようなスクリプトで、正$n\geq 3$角形を描く関数 regular_polygon(kame, n) を定義して実行して、$n=4,5,6,7,8$程度の描画ウィンドウのスクリーンショットを撮りなさい。