Python Turtleで思い通りの図形を描く!degrees()の基本と応用
turtle.degrees()
は Python の turtle
モジュールにおける非常に便利な関数です。これは、タートルグラフィックスで使われる角度の単位を、デフォルトのラジアン (radians) から、私たちが日常的に慣れ親しんでいる度 (degrees) に切り替えるために使用されます。
なぜ turtle.degrees()
が必要なのか?
デフォルトでは、turtle
モジュール内の left()
や right()
といった角度を指定する関数は、引数をラジアンで受け取ります。ラジアンは数学や物理学でよく使われる単位ですが、一般的には「90度右に曲がる」のように「度」で考える方が直感的です。
turtle.degrees()
を呼び出すことで、このデフォルトの挙動を変更し、それ以降の角度指定をすべて「度」で扱えるようになります。
turtle.degrees()
は引数を取らない関数です。これを一度呼び出すだけで、単位が切り替わります。
import turtle
# タートルオブジェクトを作成
t = turtle.Turtle()
# 単位をラジアンから度に変更
t.degrees()
# これ以降の角度は「度」として解釈される
# 90度右に曲がる
t.right(90)
# 100ピクセル前進
t.forward(100)
# 45度左に曲がる
t.left(45)
# 50ピクセル前進
t.forward(50)
# 画面を閉じるクリックを待つ
turtle.done()
- 引数は不要で、一度呼び出すだけで効果が持続します。
- これにより、
left()
やright()
といった関数で、直感的な「度」の単位で角度を指定できるようになります。 turtle.degrees()
は、タートルグラフィックスで使われる角度の単位をラジアンから度へ変更します。
turtle.degrees() を呼び出していない
エラーの症状
タートルの動きが意図した角度にならない(例えば、t.right(90)
と書いたのに全然違う方向を向く)。
原因
turtle.degrees()
を呼び出していないため、left()
や right()
などの角度を指定する関数が、引数をラジアンとして解釈しているためです。デフォルトではラジアンが使われます。90 ラジアンは約 5156 度なので、90 度とは全く異なる動きになります。
トラブルシューティング
角度を指定する前に、必ず turtle.degrees()
または特定のタートルオブジェクトのメソッド(例: t.degrees()
)を呼び出すようにしてください。
import turtle
t = turtle.Turtle()
# 忘れずに degrees() を呼び出す
t.degrees()
t.forward(100)
t.right(90) # これで90度右に曲がる
t.forward(100)
turtle.done()
複数のタートルオブジェクトを使用している場合
エラーの症状
複数のタートルオブジェクトを使用しているのに、一部のタートルの動きだけが意図した角度にならない。
原因
turtle.degrees()
は、それを呼び出したタートルオブジェクトにのみ影響を与えます。もし turtle.degrees()
のようにモジュールレベルで呼び出すと、すべてのタートルオブジェクトのデフォルト設定が変更されますが、個別にタートルオブジェクトを作成した後にそのオブジェクトに対して degrees()
を呼び出さなければ、そのオブジェクトはデフォルト(ラジアン)のままになります。
トラブルシューティング
すべてのタートルオブジェクトに対して「度」の単位を使いたい場合は、各オブジェクトを作成した後にそれぞれ degrees()
を呼び出すか、最初にモジュールレベルで turtle.degrees()
を呼び出しておくことで、新しく作成されるタートルも度の単位で動作するようになります。
import turtle
# モジュールレベルで設定すると、以降作成されるタートルにも適用される
turtle.degrees()
t1 = turtle.Turtle()
t1.color("red")
t1.forward(50)
t1.left(90) # t1は度で動く
t2 = turtle.Turtle()
t2.color("blue")
t2.penup()
t2.goto(-100, 0)
t2.pendown()
# t2もdegrees()が適用されている(モジュールレベルで設定したため)
t2.right(45)
t2.forward(70)
turtle.done()
もし個別に設定したい場合は:
import turtle
t1 = turtle.Turtle()
t1.degrees() # t1は度を使う
t1.forward(50)
t1.left(90)
t2 = turtle.Turtle()
# t2にはdegrees()を呼び出さない(ラジアンのまま)
t2.penup()
t2.goto(-100, 0)
t2.pendown()
t2.right(1.57) # 90度をラジアンで指定 (π/2 約1.57)
t2.forward(50)
turtle.done()
他の角度変換関数との混同
エラーの症状
turtle.radians()
と turtle.degrees()
を間違って使っている、あるいは意図せず切り替わってしまっている。
原因
turtle.radians()
は単位をラジアンに戻す関数です。これらを混同したり、コードの途中で意図せず呼び出してしまったりすると、角度の単位が切り替わってしまい、混乱が生じることがあります。
トラブルシューティング
コード内で turtle.degrees()
や turtle.radians()
がどこで呼び出されているかを確認し、意図しない場所で単位が切り替わっていないか確認してください。一般的には、プログラムの初期段階で一度設定すれば十分です。
単位が切り替わっていることを意識していない
エラーの症状
一部の処理では「度」で動かしたいが、別の処理では「ラジアン」で動かしたいと考えている場合、意図しない単位で計算してしまう。
原因
turtle.degrees()
や turtle.radians()
は、一度呼び出されるとそれ以降の角度指定に影響を与えます。もし途中で単位を頻繁に切り替えたい場合は、その都度適切な関数を呼び出す必要がありますが、これが忘れられがちです。
トラブルシューティング
どの部分でどの単位を使うのかを明確にし、必要に応じて t.degrees()
や t.radians()
を呼び出して単位を切り替えてください。しかし、コードの可読性を考えると、できるだけ統一した単位を使う方が良いでしょう。特定の単位(例: ラジアン)でしか表現できない複雑な計算がある場合を除き、通常は「度」に統一するのが最もシンプルです。
- テストとデバッグ
角度が関係する動きが意図通りでない場合は、まずdegrees()
の設定を確認し、小さな角度で試しながら動きを観察すると良いでしょう。 - コメントの活用
どの単位で角度を扱っているのか、コードにコメントで明記しておくと、後で見返したときに理解しやすくなります。 - コードの先頭で設定
turtle.degrees()
は、プログラムの初期段階、通常はタートルオブジェクトを作成した直後に一度だけ呼び出すのが最も確実で分かりやすい方法です。
ここでは、いくつかの具体的なコード例を通してその使い方を説明します。
例1: 基本的な使い方と単位の切り替え
この例では、turtle.degrees()
を呼び出すことで、タートルの回転単位が度になることを示します。
import turtle
# 1. タートルオブジェクトの作成
t = turtle.Turtle()
t.shape("turtle") # タートルの形を分かりやすくする
t.speed(1) # 動きをゆっくりにする
# 2. 単位を「度」に設定
# これ以降の t.left() や t.right() の引数は「度」として解釈されます。
t.degrees()
print("単位を「度」に設定しました。")
# 3. 度を使って図形を描画 (正方形)
print("90度ずつ回転して正方形を描きます。")
for _ in range(4):
t.forward(100) # 100ピクセル前進
t.right(90) # 90度右に回転
# 画面を閉じるクリックを待つ
turtle.done()
解説
t.degrees()
を呼び出すことで、タートルの角度単位が度に変更されます。- そのため、
t.right(90)
は私たちが慣れている通り「90度右に曲がる」動作になります。 - もし
t.degrees()
を呼び出さなかった場合、t.right(90)
は「90ラジアン」回転しようとします。90 ラジアンは非常に大きな角度(約5156度)なので、タートルは激しく回転し、正方形にはなりません。
例2: turtle.radians()
との比較(単位の重要性)
この例では、degrees()
を呼び出さなかった場合(デフォルトのラジアン)と、呼び出した場合の違いを示し、単位の重要性を強調します。
import turtle
import math # 円周率πを使うためにインポート
# ウィンドウの設定
wn = turtle.Screen()
wn.setup(width=600, height=400)
# タートル1 (ラジアンのまま)
t_rad = turtle.Turtle()
t_rad.shape("arrow")
t_rad.color("blue")
t_rad.penup()
t_rad.goto(-150, 0)
t_rad.pendown()
t_rad.speed(1)
# タートル2 (度を設定)
t_deg = turtle.Turtle()
t_deg.shape("turtle")
t_deg.color("red")
t_deg.penup()
t_deg.goto(150, 0)
t_deg.pendown()
t_deg.speed(1)
t_deg.degrees() # ここで「度」に設定
print("青いタートル(ラジアン)と赤いタートル(度)の動きを比較します。")
# 青いタートル (ラジアン) - 90度 (π/2 ラジアン) を曲がろうとする
print("\n青いタートル: 90度の動きをラジアンで指定 (math.pi / 2)")
t_rad.forward(50)
t_rad.left(math.pi / 2) # 約 1.5708 ラジアン (90度)
t_rad.forward(50)
# 青いタートル - 90ラジアンを曲がろうとする(非常に大きく回転)
print("青いタートル: 90ラジアンで回転しようとする")
t_rad.forward(50)
t_rad.left(90) # デフォルトがラジアンなので、90ラジアン回転する
t_rad.forward(50)
# 赤いタートル (度) - 90度を曲がろうとする
print("\n赤いタートル: 90度の動きを度で指定 (90)")
t_deg.forward(50)
t_deg.right(90) # t_degは degrees() を呼び出しているので、90度回転
t_deg.forward(50)
# 赤いタートル - 90ラジアンに相当する度数を曲がろうとする
print("赤いタートル: 90ラジアンに相当する度数で回転 (約 5156.6度)")
t_deg.forward(50)
t_deg.right(math.degrees(90)) # 90ラジアンを度に変換
t_deg.forward(50)
# 画面を閉じるクリックを待つ
turtle.done()
解説
t_rad
はdegrees()
を呼び出していないため、left()
やright()
の引数はラジアンとして解釈されます。そのため、t_rad.left(math.pi / 2)
でようやく90度回転します。- しかし、
t_rad.left(90)
とすると、90ラジアン(約5156度)という非常に大きな角度で回転します。 - 一方、
t_deg
はt_deg.degrees()
を呼び出しているので、t_deg.right(90)
はそのまま90度回転します。 - もし
t_deg
で90ラジアンに相当する角度を扱いたい場合は、math.degrees(90)
のように明示的にラジアンを度に変換する必要があります。
turtle.degrees()
は、特定のタートルオブジェクトのメソッドとしてだけでなく、turtle
モジュール自体に対して呼び出すこともできます。この場合、それ以降に作成されるすべてのタートルオブジェクトにその設定が適用されます。
import turtle
# モジュールレベルで単位を「度」に設定
# これ以降に作成されるすべてのタートルが「度」をデフォルトの角度単位とします。
turtle.degrees()
print("モジュール全体で単位を「度」に設定しました。")
# 最初のタートル
t1 = turtle.Turtle()
t1.color("red")
t1.penup()
t1.goto(-100, 0)
t1.pendown()
t1.speed(1)
# 2番目のタートル
t2 = turtle.Turtle()
t2.color("blue")
t2.penup()
t2.goto(100, 0)
t2.pendown()
t2.speed(1)
print("赤いタートルと青いタートルがそれぞれ90度回転して進みます。")
# 両方のタートルが度を使って動く
t1.forward(50)
t1.left(90) # t1は「度」で動く
t1.forward(50)
t2.forward(50)
t2.right(90) # t2も「度」で動く
t2.forward(50)
# 画面を閉じるクリックを待つ
turtle.done()
解説
turtle.degrees()
をプログラムの早い段階で呼び出すことで、その後に作成されるt1
とt2
の両方がデフォルトで「度」の単位を使用するようになります。- 個々のタートルオブジェクトに対して
degrees()
を呼び出す手間が省け、コードが簡潔になります。
turtle.degrees()
は、タートルグラフィックスで角度を直感的に「度」で扱いたい場合に非常に役立つ関数です。
- 重要性
単位を意識しないと、タートルの動きが予期しないものになる可能性がある。 - 影響範囲
タートルオブジェクトのメソッドとして呼び出すと、そのオブジェクトにのみ影響。モジュールレベルで呼び出すと、以降に作成されるすべてのタートルに影響。 - 基本的な使い方
タートルオブジェクト.degrees()
またはturtle.degrees()
を呼び出す。
角度をラジアンに手動で変換する
turtle.degrees()
を使わない場合、タートルモジュールはデフォルトで角度をラジアンとして扱います。したがって、私たちが「度」で考えた角度を、明示的に「ラジアン」に変換してタートルに渡すことで、同じ結果を得ることができます。
キーとなる数学的知識
- 1 ラジアン = π180度
- 1 度 = 180πラジアン
- π (パイ) ラジアン = 180 度
Pythonの math
モジュールには、この変換を簡単に行うための関数が用意されています。
math.degrees(radians)
: ラジアンを度に変換 (これはturtle.degrees()
とは逆方向の変換です)math.radians(degrees)
: 度をラジアンに変換
コード例
import turtle
import math # mathモジュールをインポート
t = turtle.Turtle()
t.shape("turtle")
t.speed(1)
print("degrees()を使わずに、度をラジアンに変換して正方形を描きます。")
# 90度をラジアンに変換
angle_in_radians = math.radians(90) # math.radians(90) は約 1.5708 ラジアン
for _ in range(4):
t.forward(100)
# 90度回転したいので、90度をラジアンに変換した値を渡す
t.right(angle_in_radians)
turtle.done()
利点
- 数学的な変換を意識することになります。
turtle.degrees()
を呼び出す必要がないため、コードの柔軟性が増す可能性があります(例えば、一部の操作は度で、一部はラジアンで厳密に制御したい場合など)。
欠点
- 計算ミスや変換忘れのリスクがあります。
- 可読性が低下する可能性があります。「90度」と書く方が「
math.radians(90)
」と書くよりも直感的です。 - すべての角度指定のたびに
math.radians()
を使う必要があり、コードが冗長になりがちです。
上記の「手動変換」の欠点を補うために、自分で角度を度で受け取り、内部でラジアンに変換してタートルのメソッドを呼び出すラッパー関数を作成する方法もあります。これは特に、タートルの動きを抽象化したい場合に有効です。
コード例
import turtle
import math
t = turtle.Turtle()
t.shape("turtle")
t.speed(1)
print("独自のラッパー関数を使って、度で正方形を描きます。")
# 独自の「度」ベースの回転関数を定義
def turn_right_degrees(t_obj, angle_in_degrees):
"""
指定されたタートルオブジェクトを、度数で右に回転させる関数。
"""
radians = math.radians(angle_in_degrees)
t_obj.right(radians)
def turn_left_degrees(t_obj, angle_in_degrees):
"""
指定されたタートルオブジェクトを、度数で左に回転させる関数。
"""
radians = math.radians(angle_in_degrees)
t_obj.left(radians)
# ラッパー関数を使って正方形を描画
for _ in range(4):
t.forward(100)
turn_right_degrees(t, 90) # 90度右に回転
turtle.done()
利点
- タートルの振る舞いをより高レベルで抽象化できます。
- 一度関数を定義すれば、何度も
math.radians()
を書く手間が省けます。 - コードの可読性が高まります。関数を使うことで「度」での操作が明確になります。
欠点
- 結局のところ、内部的には
math.radians()
による変換が行われています。 - 追加の関数定義が必要になります。
これらの代替方法は技術的には可能ですが、ほとんどの場合、turtle.degrees()
を使用する方が最もシンプルで、エラーが少なく、コードの可読性が高いため、強く推奨されます。
- 代替方法の適用シーン
- 特定の状況で、一時的にラジアンでの厳密な制御が必要な場合。
- 学習目的で、角度の単位変換の概念を理解したい場合。
- 非常に大規模なプロジェクトで、タートルの動作を高度に抽象化するカスタムAPIを構築している場合。
- 最も推奨される方法
プログラムの初期段階でturtle.degrees()
を一度呼び出す。