Turtle
前回、PythonのグラフィックスライブラリTurtleで四角形と再帰と塗りつぶしを使って複雑な図形を描く方法を紹介しました。
今回は前回の記事を作成している際に見つけた塗りつぶしをする際の注意点に関して紹介していきます。
その注意点とは「塗りつぶしの判定は軌跡に対して行われる」ということです。
それでは始めていきましょう。
塗りつぶしの判定
前回、四角形と再帰、塗りつぶしを使って複雑な図形を描いてみましたが、その際、思ったように塗りつぶしができない場合がありました。
まずは四角形全体を塗りつぶしできるのはこんな感じです。
import turtle
import random
def square(a):
for _ in range(4):
t.forward(a)
t.right(90)
if __name__ == "__main__":
t = turtle.Turtle()
pencolor = (random.random(), random.random(), random.random())
fillcolor = (random.random(), random.random(), random.random())
t.color(pencolor, fillcolor)
t.begin_fill()
square(250)
t.end_fill()
turtle.done()
四角形の内部全体が塗りつぶされています。
次に四角形全体を塗り潰せなかったプログラムはこちらです。
import turtle
import random
def square(a):
t.penup()
t.backward(a/2)
t.left(90)
t.forward(a/2)
t.right(90)
t.pendown()
for _ in range(4):
t.forward(a)
t.right(90)
t.penup()
t.forward(a/2)
t.right(90)
t.forward(a/2)
t.left(90)
t.pendown()
if __name__ == "__main__":
t = turtle.Turtle()
pencolor = (random.random(), random.random(), random.random())
fillcolor = (random.random(), random.random(), random.random())
t.color(pencolor, fillcolor)
t.begin_fill()
square(250)
t.end_fill()
turtle.done()
四角形のうち左上の領域は色が塗られておらず、他の4分の3の領域だけ色が塗られました。
まずこの2つのプログラムでは塗りつぶしの開始点「t.begin_fill()」と終了点「t.end_fill()」は同じです。
違うのは四角形の書き方です。
四角形の描き方は「square関数」で定義されています。
最初の四角形全体を塗り潰せたプログラムの「square関数」はこんな感じです。
def square(a):
for _ in range(4):
t.forward(a)
t.right(90)
つまり単純に辺を引き、90度回転して線を引き、を繰り返して四角形を描いています。
一方、四角形全体を塗り潰せなかったプログラムの「square関数」はこんな感じです。
def square(a):
t.penup()
t.backward(a/2)
t.left(90)
t.forward(a/2)
t.right(90)
t.pendown()
for _ in range(4):
t.forward(a)
t.right(90)
t.penup()
t.forward(a/2)
t.right(90)
t.forward(a/2)
t.left(90)
t.pendown()
こちらではまずペンを上げ、一辺の長さの半分だけ後退したのち、上に向きを変え、さらに一片の長さの半分だけ前に進んでいます。
そこからペンを下げて、四角形を描いた後、再度ペンを上げて、一片の長さの半分だけ前進し、左に90度回転し、再度一片の長さの半分だけ前進しています。
何か複雑なことをしているように見えますが、開始点を四角形の中心にしたかったので、まず描く四角形の左上に移動して、そこから四角形を描き、最後中心に戻ってくるということをしているわけです。
ただし移動だけの場合は線を描きたくないので、ペンを上げて移動して、ペンを下げるということをしています。
そして線で囲まれた範囲が塗りつぶされると思っていたのですが、そうではない形に塗りつぶされてしまったというわけです。
そこでよく考えてみると、どうやら塗りつぶしの範囲はペンの上げ下げや線の有無に関係なく、ペンの軌跡によって決まるもののようです。
ということで塗りつぶしを使う際には描かれた線ではなく、ペンの軌跡であることを注意すると思った通りに塗り潰せると思います。
次回はPythonのジェネレータと呼ばれる一つの要素を取り出すたびに処理を行う方法を紹介します。
ではでは今回はこんな感じで。
コメント