2015年11月15日日曜日

【プログラミング】Pythonの勉強 その5 - turtleで六芒星を描く -

プログラミング初心者の学習記録です。
今回は趣向を変えて、turtleモジュールで遊んでみようと思います。

turtleモジュールで何をしようかなと考えた結果、六芒星を書いてみることにしました。
六芒星というのは、上向きの正三角形と下向きの正三角形が組み合わさった図形です。
六芒星 - Wikipedia



正三角形を描くことはそれほど難しくはないのですが、2つの正三角形をバランスよく組み合わせるのは難しそうです。
今回は原点(turtle.home()で戻るポイント)を中心に持つ正三角形の書き方を検討してみます。
具体的には、原点Oから頂点Aまでの長さを基準に、正三角形の辺ABの長さを求めたいと思います。
直角三角形ABCは正三角形を半分にしたものなので、角ABCは60°、角BACは30°です。

辺の長さを求めるには三角関数を使う必要がありそうです。サイン、コサイン、タンジェントなんて高校以来なのでよく覚えていませんが、次のサイトを参考にしてやってみました。
直角三角形とcos,sin,tanの意味:ビジュアル数学(数学1:三角比・三角関数)

cos(BAC) = AC / AB   なので、
AB = AC / cos(30°) になります。

また直角三角形OBCをみてみると、角BOCは60°、角OBCは30です。
cos(BOC) = OC / OB なので、
OC = cos(60°) * OB になります。

OA = OB なので、
OC = cos(60°) * OA になります。

AC = OA + CA なので、
AB = (OA + (cos(60°) * OA) ) / cos(30°) となります。


プログラムの内容を考えてみます。
中心から頂点までの距離をbase、ひく線の長さをlineとしておきます。
上向きの正三角形を描く → 下向きの正三角形を描く → 最初の位置に戻る
という動作にしようと思います。

実行手順は細かく分割すると、次のとおりになります。
(01) ペンアップ
(02) 90°左向く(真上を向く)
(03) baseほど前に進む
(04) ペンダウン
(05) 150°(180°-30°)左を向く
(06) lineほど前に進む
(07) 120°(180°-60°)左を向く
(08) lineほど前に進む
(09) 120°(180°-60°)左を向く
(10) lineほど前に進む
(11) 150°(180°-30°)左を向く(真下を向く)
(12) ペンアップ
(13) (base * 2)ほど前に進む
(14) ペンダウン
(15) 150°(180°-30°)左を向く
(16) lineほど前に進む
(17) 120°(180°-60°)左を向く
(18) lineほど前に進む
(19) 120°(180°-60°)左を向く
(20) lineほど前に進む
(21) 150°(180°-30°)左を向く(真上を向く)
(22) ペンアップ
(23) baseほど前に進む(原点に戻る)
(25) 90°右を向く
(26) ペンダウン


関数「hexagram」を「turtle_hex.py」に定義します。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# coding:shift-jis
import math

def hexagram(target,base):
    target.radians()
    #角度は弧度法を使用。math.pi -> 180°
    line = (base+(math.cos(math.pi/3)*base))/math.cos(math.pi/6)
    #line = (base + (cos(60°) * base) ) / cos(30°) 

    target.penup()
    target.left(math.pi / 2)
    # 90° -> math.pi / 2
    target.fd(base)
    target.pendown()
    target.left(math.pi / 6 * 5)
    # 180°-30° -> 150° -> math.pi / 6 * 5
    target.fd(line)
    target.left(math.pi / 3 * 2)
    # 180°-60° -> 120° -> math.pi / 3 * 2
    target.fd(line)
    target.left(math.pi / 3 * 2)
    target.fd(line)
    target.left(math.pi / 6 * 5)
    target.penup()
    target.fd(base * 2)
    target.pendown()
    target.left(math.pi / 6 * 5)
    target.fd(line)
    target.left(math.pi / 3 * 2)
    target.fd(line)
    target.left(math.pi / 3 * 2)
    target.fd(line)
    target.left(math.pi / 6 * 5)
    target.penup()
    target.fd(base)
    target.right(math.pi / 2)
    target.pendown()
syntax2html

対話モードで次のように打ち込んで試してみます。
1
2
3
4
5
6
import turtle
kame = turtle.Turtle()
import turtle_hex
turtle_hex.hexagram(kame,300)
turtle_hex.hexagram(kame,200)
turtle_hex.hexagram(kame,400)
syntax2html


こんな感じに図形が描けました。

エラーの連発で予想以上に苦労しました。

0 件のコメント:

コメントを投稿