Python Turtleで円を描く!初心者向けcircle()徹底解説

2025-06-06

基本的な使い方

turtle.circle(radius, extent=None, steps=None)

  • steps (オプション)

    • 円または円弧を構成する多角形の辺の数を指定します。
    • デフォルトはNoneで、これは円滑な円を描画するために適切な数のステップが自動的に選択されることを意味します。
    • stepsの値を小さくすると、円が多角形に見えるようになります(例えば、steps=4とすると正方形が描画されます)。
  • extent (オプション)

    • 描画する円弧の角度を度数で指定します。
    • デフォルトはNoneで、この場合、完全な円(360度)が描画されます。
    • 例えば、90と指定すると四半円が描画されます。
    • 円の半径を数値で指定します。
    • 正の値を指定すると、カメの左側に円の中心があるように描画されます(反時計回り)。
    • 負の値を指定すると、カメの右側に円の中心があるように描画されます(時計回り)。

import turtle

# タートルスクリーンの設定
screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("white")

# タートルの作成
pen = turtle.Turtle()
pen.shape("turtle")
pen.color("blue")
pen.speed(1) # 描画速度を遅くする

# 1. 半径100の完全な円を描く
pen.penup()
pen.goto(-150, 0)
pen.pendown()
pen.circle(100) # 半径100の円

# 2. 半径50の半円を描く(時計回り)
pen.penup()
pen.goto(50, 0)
pen.pendown()
pen.circle(-50, 180) # 半径-50(右側に中心)、180度の半円

# 3. 半径70で、ステップ数を指定して多角形のように描く(六角形)
pen.penup()
pen.goto(-50, -150)
pen.pendown()
pen.circle(70, steps=6) # 半径70の六角形

# 描画ウィンドウを閉じるまで待機
screen.mainloop()

turtle.circle()は、実際には非常に短い直線セグメントを多数連続して描画することで円を近似しています。steps引数を指定しない場合、turtleモジュールは自動的に円滑に見えるように適切なsteps数を計算します。stepsを指定すると、その数の辺を持つ正多角形が描画されます。



turtle.circle()は比較的直感的な関数ですが、いくつか一般的な問題が発生することがあります。

画面が表示されない、またはすぐに消えてしまう

これはturtleグラフィックス全般によくある問題です。

  • トラブルシューティング

    • プログラムの最後にturtle.done()またはscreen.mainloop()screen = turtle.Screen()を使用している場合)を追加してください。これにより、ユーザーがウィンドウを閉じるまでプログラムが待機します。
    import turtle
    
    pen = turtle.Turtle()
    # ... circle()の呼び出し ...
    
    turtle.done() # または screen.mainloop()
    
  • エラーの原因
    プログラムが終了すると、タートルグラフィックスウィンドウも閉じられてしまいます。

円が描画されない、または期待した場所に描画されない

  • エラーの原因3: ペンが上がっている
    pen.penup()の呼び出し後、pen.pendown()を忘れていると、描画は行われません。

    • トラブルシューティング
      描画したい場所で必ずpen.pendown()を呼び出しているか確認してください。
  • エラーの原因2: 半径の指定ミス
    半径を極端に小さい値にしたり、タートルが画面外に描画しようとしたりしている可能性があります。

    • トラブルシューティング
      radiusの値を調整して、画面内に収まるようにしてください。負の半径は円の中心が逆になることに注意してください。
  • エラーの原因1: タートルの位置や向き
    circle()は、タートルの現在の位置と向きに基づいて円を描画します。タートルが意図しない場所にいるか、意図しない方向を向いている可能性があります。

    • トラブルシューティング
      • pen.penup()pen.goto(x, y)pen.pendown()を使って、描画を開始したい位置にタートルを移動させます。
      • pen.setheading(angle)pen.right(angle)pen.left(angle)を使って、タートルの向きを調整します。
    import turtle
    screen = turtle.Screen()
    pen = turtle.Turtle()
    
    pen.penup() # ペンを上げる
    pen.goto(0, 50) # (0, 50)に移動
    pen.pendown() # ペンを下ろす
    
    pen.setheading(0) # 東(右)を向く
    pen.circle(50) # ここから円を描く
    turtle.done()
    

円が滑らかでない、または多角形に見える

  • トラブルシューティング

    • 滑らかな円を描きたい場合は、steps引数を指定しないでください。デフォルトで適切な値が選ばれます。
    • 意図的に多角形を描きたいのでなければ、steps引数を削除するか、非常に大きな値に設定してください(ただし、大きな値は処理が重くなる可能性があります)。
    import turtle
    screen = turtle.Screen()
    pen = turtle.Turtle()
    
    # スムーズな円(stepsを指定しない)
    pen.circle(50)
    
    # 意図的に多角形(例: 六角形)
    # pen.penup()
    # pen.goto(100, 0)
    # pen.pendown()
    # pen.circle(50, steps=6)
    
    turtle.done()
    
  • エラーの原因
    steps引数を小さい値で指定している場合、円ではなく多角形が描画されます。

turtle.circle()の引数エラー

  • トラブルシューティング
    radius引数には必ず数値を指定してください。extentstepsも同様に数値である必要があります。

    # 悪い例 (TypeError)
    # pen.circle("50")
    
    # 良い例
    pen.circle(50)
    
  • エラーの原因
    circle()関数に数値以外の型(文字列など)を渡したり、引数の数が間違っていたりする場合。

描画速度が遅すぎる、または速すぎる

  • トラブルシューティング
    pen.speed(speed_value)を使用します。

    • 0 (最速)
    • 1 (最も遅い)
    • 1から10までの数値(1が遅く、10が速い)
    import turtle
    screen = turtle.Screen()
    pen = turtle.Turtle()
    
    pen.speed(0) # 最速で描画
    pen.circle(100)
    
    turtle.done()
    
  • エラーの原因
    デフォルトの描画速度が目的に合わない場合。



例1: 基本的な円の描画

最もシンプルなcircle()の使い方です。

import turtle

# 画面とタートル(ペン)のセットアップ
screen = turtle.Screen()
screen.setup(width=600, height=400) # 画面サイズを設定
screen.bgcolor("lightblue") # 背景色を設定
screen.title("基本的な円の描画") # ウィンドウのタイトル

pen = turtle.Turtle()
pen.shape("turtle") # タートルの形をカメにする
pen.color("red") # ペンの色を赤にする
pen.speed(1) # 描画速度を遅くする (1が最も遅い、0が最速)

# 円を描画
pen.circle(100) # 半径100ピクセルの円を描く

# 画面を閉じないようにする
turtle.done()

説明

  • turtle.done(): 描画が完了した後、ユーザーがウィンドウを閉じるまで画面を保持します。これを忘れると、すぐにウィンドウが消えてしまいます。
  • pen.circle(100): タートルの現在の位置と向きから、半径100ピクセルの円を描画します。デフォルトでは反時計回りです。
  • pen.shape("turtle"), pen.color("red"), pen.speed(1): タートルの見た目や描画速度を設定します。
  • pen = turtle.Turtle(): タートル(ペン)オブジェクトを作成します。
  • screen.setup(...), screen.bgcolor(...), screen.title(...): 画面のサイズ、背景色、タイトルを設定します。
  • screen = turtle.Screen(): 描画ウィンドウ(スクリーン)を作成します。
  • import turtle: turtleモジュールをインポートします。

例2: 複数の円と負の半径

複数の円を描いたり、負の半径を使って描画方向を変えたりする例です。

import turtle

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lightgreen")
screen.title("複数の円と負の半径")

pen = turtle.Turtle()
pen.shape("arrow") # タートルの形を矢印にする
pen.color("blue")
pen.speed(3) # 少し速くする

# 最初の円 (正の半径 = 反時計回り)
pen.penup() # ペンを上げる(描画しない)
pen.goto(-150, 0) # 左に移動
pen.pendown() # ペンを下ろす(描画開始)
pen.circle(50) # 半径50の円

# 次の円 (負の半径 = 時計回り)
pen.penup()
pen.goto(50, 0) # 右に移動
pen.pendown()
pen.circle(-70) # 半径70、時計回りの円

# 画面を閉じないようにする
turtle.done()

説明

  • pen.circle(-70): 半径に負の値を指定すると、円の中心がタートルの右側になり、時計回りに描画されます。
  • pen.goto(x, y): 指定された座標へタートルを瞬時に移動させます。
  • pen.penup()pen.pendown(): 描画せずにタートルを移動させたいときに使います。penup()でペンを上げ、pendown()でペンを下ろして描画を再開します。

例3: 円弧(extent引数の使用)

extent引数を使って、円の一部(円弧)を描画する例です。

import turtle

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lavender")
screen.title("円弧の描画")

pen = turtle.Turtle()
pen.shape("circle") # タートルの形を円にする
pen.color("purple")
pen.speed(2)

# 半径80の円の1/4を描画 (90度)
pen.penup()
pen.goto(-100, 0)
pen.pendown()
pen.circle(80, 90) # 半径80、90度の円弧

# 半径120の円の半円を描画 (180度)
pen.penup()
pen.goto(50, 0)
pen.pendown()
pen.circle(120, 180) # 半径120、180度の円弧

# 画面を閉じないようにする
turtle.done()

説明

  • pen.circle(radius, extent): extent引数は、描画する円弧の角度を度数で指定します。
    • 90は四半円(1/4円)
    • 180は半円
    • 360は完全な円(extentを指定しない場合と同じ)

例4: 多角形を描画する(steps引数の使用)

steps引数を使って、円を近似する多角形を描画する例です。

import turtle

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("peachpuff")
screen.title("多角形の描画")

pen = turtle.Turtle()
pen.color("darkorange")
pen.speed(1)
pen.pensize(2) # ペンの太さを設定

# 正三角形 (3ステップ)
pen.penup()
pen.goto(-200, 50)
pen.pendown()
pen.circle(60, steps=3) # 半径60の正三角形

# 正方形 (4ステップ)
pen.penup()
pen.goto(-50, 50)
pen.pendown()
pen.circle(60, steps=4) # 半径60の正方形

# 正六角形 (6ステップ)
pen.penup()
pen.goto(100, 50)
pen.pendown()
pen.circle(60, steps=6) # 半径60の正六角形

# 画面を閉じないようにする
turtle.done()

説明

  • pen.pensize(size): ペンの太さを設定します。
  • pen.circle(radius, extent, steps): steps引数は、円を構成する辺の数を指定します。これにより、多角形を描画できます。

forループと組み合わせて、複雑なパターンを作成する例です。

import turtle

screen = turtle.Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black") # 背景を黒に
screen.title("円を使ったパターン")

pen = turtle.Turtle()
pen.speed(0) # 最速
pen.color("white") # 白いペン
pen.pensize(1)
pen.hideturtle() # タートル自身を非表示にする

for i in range(36): # 36回繰り返す
    pen.circle(100) # 半径100の円を描く
    pen.left(10) # 左に10度回転

# 画面を閉じないようにする
turtle.done()
  • pen.left(10): タートルを左に10度回転させます。これにより、次の円が少しずれた位置に描画され、美しいパターンが生まれます。
  • for i in range(36):: 36回ループを実行します。
  • pen.hideturtle(): 描画中にタートルのアイコンを表示したくない場合に使用します。


turtle.circle()の代替方法

主な代替方法は、非常に短い直線セグメントを多数描画し、少しずつ回転させるというアプローチです。これは、circle()関数自体が内部で行っていることと本質的に同じです。

forループとforward() / left()(またはright())の組み合わせ

これが最も一般的で理解しやすい代替方法です。円は多数の短い直線で近似できます。

import turtle

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lightyellow")
screen.title("circle()の代替 - forループ")

pen = turtle.Turtle()
pen.shape("turtle")
pen.color("green")
pen.speed(0) # 最速

# 円を描画する代替方法
segments = 360 # 円を構成するセグメントの数 (多いほど滑らか)
length_per_segment = 1 # 各セグメントの長さ (半径とsegments数で調整)

# 例: 半径50の円を描く
# 円周 = 2 * pi * 半径
# 各セグメントの長さ = 円周 / セグメント数
# 回転角度 = 360 / セグメント数

# 半径50の円を描く場合 (おおよそ)
radius = 50
circumference = 2 * 3.14159 * radius
# 小さな円の場合、segmentsを多くすると計算が厳密でなくても滑らかに見える
# より正確な近似をしたい場合、各セグメントの長さと回転角度を計算する
# 例えば、各ステップで1度回転させるなら、長さは 2 * pi * r / 360 となる

# 実際の代替コード
# これはおおよその円を描くための調整です。
# より正確な円に近づけるには、半径とセグメント数を考慮した計算が必要です。
# 例えば、pen.circle(50) と同じ円を描くには、
# 長さ = (2 * math.pi * 50) / 360 = 約0.87
# となりますが、ここでは簡略化のため、簡単な例を挙げます。

pen.penup()
pen.goto(-100, 0)
pen.pendown()

for _ in range(segments):
    pen.forward(length_per_segment) # 少し前進
    pen.left(360 / segments)      # 少し左に回転

# より大きな円を描く代替方法 (各セグメントの長さと回転角度を調整)
pen.penup()
pen.goto(100, 0)
pen.pendown()

large_radius = 80
num_segments = 360 # 1度ずつ回転させる
segment_length = (2 * 3.14159 * large_radius) / num_segments

for _ in range(num_segments):
    pen.forward(segment_length)
    pen.left(360 / num_segments)

turtle.done()

説明

  • turtle.circle(radius, steps=N)は、本質的にこの方法のsteps=Nの部分がこのsegmentsに相当します。stepsを指定しない場合、turtleは適切なsegments数とlength_per_segmentを内部で計算します。
  • pen.left(360 / segments)360 / segments度だけタートルを左に回転させます。これにより、全体の回転が360度になります。
  • pen.forward(length_per_segment):指定された長さだけタートルを前進させます。
  • length_per_segment:各直線セグメントの長さです。
  • segments:円をいくつの小さな直線で近似するかを決めます。数が多いほど円は滑らかに見えます。

メリット

  • 特定の角度で回転を止めたり、特定の長さのセグメントを厳密に制御したりするなどの、より細かい制御が可能になる。
  • circle()関数がどのように動作しているかの理解が深まる。

デメリット

  • 円を滑らかに見せるためには、適切なsegments数とlength_per_segmentの値を試行錯誤する必要がある。
  • circle()関数を使うよりもコードが長くなる。

setheading()とgoto()の組み合わせ(複雑だが可能)

これはあまり一般的ではありませんが、数学的な計算を駆使して円周上の各点を計算し、そこにgoto()で移動することで円を描くことも理論上は可能です。しかし、これはturtle.circle()のシンプルさとはかけ離れており、通常は推奨されません。

例 (概略):

import turtle
import math

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lightcoral")
screen.title("circle()の代替 - goto()とsetheading()")

pen = turtle.Turtle()
pen.speed(0)
pen.hideturtle() # タートルを非表示に
pen.penup()

center_x, center_y = 0, 0 # 円の中心
radius = 100

pen.goto(center_x + radius, center_y) # 円の開始点に移動
pen.pendown()

for angle_degrees in range(0, 361, 5): # 5度刻みで点を計算
    angle_radians = math.radians(angle_degrees)
    x = center_x + radius * math.cos(angle_radians)
    y = center_y + radius * math.sin(angle_radians)
    pen.goto(x, y) # 計算した点に移動

turtle.done()

説明

  • pen.goto(x, y)で計算した点へ移動し、線を描画します。
  • math.cos()math.sin()を使って三角関数計算を行います。
  • 円の中心座標と半径を使って、角度ごとに円周上の点の(x, y)座標を計算します。

メリット

  • 他の描画関数と組み合わせて、より複雑な形状の描画に応用できる。
  • 数学的な理解を深めることができる。
  • circle()のように簡単に「円」を描く用途には向かない。
  • 三角関数に関する知識が必要。
  • turtle.circle()と比較してコードが大幅に複雑になる。
  • setheading()goto()の組み合わせは、特定の数学的な描画タスクや、非常に特殊な制御が必要な場合にのみ検討するべきです。
  • forループとforward() / left()の組み合わせは、circle()が内部でどのように機能しているかを理解したい場合や、円を構成する各セグメントをより細かく制御したい場合に有効です。
  • ほとんどの場合、turtle.circle()を使うべきです。 これは、円を描画するために最適化されており、最もシンプルで効率的です。