masuTomo’s blog

競技プログラミングの勉強メモです.主にPythonを使用します.数学の記事も書くかもしれません.

Pythonとturtleでシェルピンスキーのガスケット

シェルピンスキーのギャスケットの画像が必要になった。せっかくなので勉強中のPythonで書いてみることにしたました。
そもそもPythonで図形描画をしたことがなかったので「Python 図形描画」でググるところからスタート。少し調べると2つ候補が見つかりました。

  • turtle

  • matplotlib

matplotlibは以前,統計処理の勉強で少しだけ使ったことがあるが,グラフを書くことや点をプロットすることは得意そうという印象。ただ,今回は直線を引いたりするのを気軽にやりたくて,そういうのはturtleの方が得意そうに見えたので,今回はturtleを使ってみることにしました。
以下のwebサイトを参考にさせてもらいました。

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

Pythonとタートルグラフィックスによる(再帰)プログラミング教育処方案 - Read -> Blog

turtle --- タートルグラフィックス — Python 3.8.1 ドキュメント

使用する機能は基本的には2つ。

  • 指定した角度だけ回転する
  • 今向いている方向に,指定した長さの線分を引く

あとはこれをうまいこと組み合わせればよい。 解説はまた今度(眠いので)。今日はコードと描画結果だけ掲載します。

from turtle import *
from collections import deque
len = 600
stX = -250
stY = -250

#スタート地点に戻る
def setHome():
    setheading(0)
    penup()
    setposition(stX,stY)
    pendown()
#指定した場所に移動して方向を水平に変更
def setXY(x,y):
    setheading(0)
    penup()
    setposition(x,y)
    pendown()

#最初に一度だけ描く大きい三角形
def drawBigTri(l):
    setHome()
    fillcolor('blue')
    begin_fill()
    for _ in range(3):
        fd(l)
        rt(240)
    end_fill()

#再帰で小さい三角形を描画
def drawTri(l):
    l /= 2
    qq = []
    for q in Q:
        qq.append(q)
    for q in qq:
        setXY(q[0],q[1])
        fd(l)
        rt(300)
        Q.append(list(position()))
        fillcolor('white')
        begin_fill()
        for i in range(3):
            if i == 2: Q.append(list(position()))
            fd(l)
            rt(240)
        end_fill()
    drawTri(l)

speed(0)
drawBigTri(len)
Q = deque()
Q.append([stX,stY])
drawTri(len)
done()

描画結果はこちら f:id:masuTomo:20200117003325p:plain