Pythonでフラクタルを描画しよう
July 31, 2023

Pythonでフラクタルを描画しよう

PythonはAI・機械学習で利用されるプログラミング言語です。この講義ではPythonでフラクタルを描画することにチャレンジします。ここでフラクタルとは、ある図形の一部がその図形の全体の一部としてくり返してできる(自己相似性)図形のことで、たとえばリアス式海岸線、枝分かれした樹木の形など自然界にもたくさんあります。講義ではタートルグラフィックス(亀が絵を描く)を使って、再帰的に実行(描画)するプログラムについて学びます。


  • 担当:山里敬也 (名古屋大学 教養教育院,工学研究科 情報・通信工学専攻)
  • 日時:2023年 8月8日(火),9日(水) 時間:10:30~14:30(昼食含む)
  • 講義場所:名古屋大学教育学部附属中・高等学校 コンピュータ教室
    名古屋大学教養教育院CALL教室(キャンパスマップB4-1の2階にあります)に変更になりました
  • 受入人数:20名程度

重要(事前準備) 

この講義では Google Colaboratory (コラボと呼びます) を使います.

  • コラボの利⽤には Google アカウントが必要です.事前に取得しておいてください.
  • コラボは PC のブラウザから利⽤できます.⾃宅からでも OK︕
  • ブラウザは何でも良いと思います.もし,うまくいかないようであれば Google Chrome をダウンロードしてご利⽤ください.
  • コラボの使い方はこちらを参照してください.

このページでは高大接続探究セミナーの「Python でフラクタルを描画しよう」を受講する高校生の皆様に,事前に知っておいて欲しい内容について書きます.

今年度は,ベーシックコースとアドバンスコースとに分けて実施します.

ベーシックコースは高校一年生,つまりプログラミングの初心者を対象にします.

アドバンスコースはプログラミングの知識が少しはあり,プログラミングをやってことがある方を対象にします.

2つのコースを同時に進めるので,講義はややトリッキーな感じで進行しますが,心配しないでください.一日目はベーシックコースを中心に進み,ベーシックコースの人は二日目は復習も兼ねて,少し発展的な内容を学習します.一方,アドバンスコースの人は二日目に再帰関数とフラクタル,つまり大学で習うようなプログラミングについて学習します.それぞれ午前中は講義,午後は演習といった感じで進めていきます.

おおよそのスケジュールは以下のようになります.

日時 ベーシックコース アドバンスコース
8月8日(火)
10:30~12:00
講義
Google Colabortory (Python)入門
Turtle Graphics入門
Google Colabortory (Python)入門
Turtle Graphics入門
8月8日(火)
13:00~14:30
演習
Turtle Graphics で自分のイニシャルを描こう Turtle Graphics で多角形を描こう
8月9日(水)
10:30~12:00
講義
Turtle Graphics で多角形を描こう 再帰関数とフラクタル
・コッホ曲線
・シェルピンスキーのガスケット
・2分木
・Levy曲線
・Drangon曲線
8月9日(水)
13:00~14:30
演習
Turtle Graphics で絵を描こう Turtle Graphics でフラクタルを描こう

資料

2022 年度の資料を公開します.2023年度もほぼ昨年度を踏襲しております.

2021 年度とほぼ同じ内容です.

2022 年度のサイト(アーカイブ)もご参照ください。

また,コラボのファイルも公開します.ご自身のコラボにアップロードしてご利用ください.

以下に目次を示します.

このうち「座標」については中学校で習った内容です. 1 日目の講義でも,座標については利用しますので予め復習しておいてください.

一方「座標と三角関数」は高校で習う内容です.数学 I(三角比)で習いますね. 高校一年生だとまだ習っていないかも知れませんが,ご安心ください. 大丈夫です.難しく無いので,この機会に勉強してみてください. とりわけ「余弦定理」はいろいろと使えますので,理解しておくと良いです.

逆三角関数は大学で習うものです.これはまだ知らなくても大丈夫です.

2 日目の講義では「関数」の再帰呼び出しについて勉強します. 数学 B(数列)の漸化式が分かるのであれば大丈夫です. とはいえ,いかにも大学でのプログラミングという内容ですので,難易度は高そうに思われますが,そうでもありません. コツをつかめば,なんてことありませんので是非チャレンジしてみてください.


目次 


なぜ事前学習が必要なのか

この講義ではプログラミング言語 Python を使い,お絵かきをしていきます. 実際には,タートルグラフィックスというツールを使い「亀(タートル)」さんに絵を描いてもらいます.

亀さんに絵を描いてもらうためには,亀さんに以下のようなことを教えてあげる必要があります.

  • 画面上のある点まで移動する
  • ペンを降ろす(描画開始)
  • 指定された方向に向く
  • 指定された長さだけ線を描く(描画)
  • ペンを持ち上げる(描画終了)

これをプログラムとして記載し,亀さん絵を描いてもらうのです. このためには,画面上の点を示す座標の基本的な知識と角度(方向)と長さを求めること(実際には図形の一辺として扱います)ができないと せっかくの講義もちんぷんかんぷんで,ちっとも面白くありません. とりわけ,1 日目の講義では,亀さんに皆さんのイニシャル(アルファベット)を描いてもらいますが,座標や図形の基本的なことが分からないと何もできないまま終わってしまいます.

以下,簡単に本講義で必要となる座標と図形について説明していきます. なお,座標と図形の基本的な知識の殆どが,中学校で習ったことですので高校生の皆さんにとっては何も難しくありません.

2 日目の講義では,関数の再帰呼び出しについて学びます. 具体的には,再帰呼び出しを使ってフラクタルを亀さんに描いてもらいます.

この関数と再帰呼び出しについても,数学的なことについて簡単に説明します.

座標

コンピュータでは,画面の位置を「座標」として表します. ここで座標とはxxyyの組で表される点の位置を表したものです.

中学校で習いましたね.

たとえば(x,y)=(1,2)(x,y)=(1,2)は下図に示す座標(方眼紙)の点として表すことができます.

座標

この図では,原点を(0,0)(0,0)とし,横軸をxx,縦軸をyyとしています. xx軸とyy軸は原点で垂直に交わります.このxx軸とyy軸を座標軸と呼びます.

点の移動 

左右への移動

(1,2)(1,2)を右(xx軸方向)に長さ 3 だけ移動してみましょう. そうすると点(1,2)(1,2)は点(1+3,2)=(4,2)(1+3,2)=(4,2)に移動します.

今後は左(xx軸方向とは逆)に長さ 3 だけ移動してみましょう. そうすると点(1,2)(1,2)は点(13,2)=(2,2)(1-3,2)=(-2,2)に移動します.

このように点(x,y)(x,y)が右に長さllだけ移動する場合は座標xxx+lx+lになり(x+l,y)(x+l,y),左に移動する場合は(xl,y)(x-l,y)になります. yy座標は変わりません.

なお,下図から分かるように 2 点間の長さllは,ただ単に 2 点のxx座標成分の差の絶対値になります.

上下への移動

(1,2)(1,2)を上(yy軸方向)に長さ 3 だけ移動すると点(1,2+3)=(1,5)(1,2+3)=(1,5)になります. 下に,つまりyy軸方向とは逆に長さ 3 だけ移動すると点(1,2)(1,2)は点(1,23)=(1,1)(1,2-3)=(1,-1)になります.

このように点(x,y)(x,y)が上に長さllだけ移動する場合は座標yyy+ly+lになり(x,y+l)(x,y+l),下に移動する場合はが(x,yl)(x,y-l)になります. xx座標は変わりません.

この場合も 2 点間の長さ ll は,ただ単に 2 点のyy座標成分の差の絶対値になります.

点の移動

7 セグメントディスプレイ

7-segment Indicator 図:ウィキペディアより引用

驚くかもしれませんが,亀さんを上下左右に動かすことで数字の 0〜9,そしてアルファベットの A, C, E, F, G, H, J, L, O, P, S, U を描くことができます. 言い換えると,縦の線と横の線の組み合わせで数字とアルファベットの一部を表すことができます.

この仕組みを使ったディスプレイに 7 セグメントディスプレイがあります.

7 セグメントディスプレイでは,7 つの線(セグメントと呼びます)をそれぞれ点灯(あるいは消灯)させることで数字とアルファベットの一部を表現できます.

7-segment Display Example

上の図では,セグメント a, f, g, e を点灯させることでアルファベット「F」を表示しています.

お気づきの方もいるかと思いますが,同じ長さのセグメントを 7 つ,縦横に組み合わせることで数字とアルファベットの一部を表現しています. なので,つまようじを 7 つ用意して,その組み合わせでもできますね.

興味のある方は,7 つのセグメントのオン(点灯),オフ(消灯)させることで数字の 0〜9, A, C, E, F, G, H, J, L, O, P, S, U を表示できることを確かめてみてください. ぜひ,つまようじ 7 本使って,試してみて下さい.

点と点を結んだ線 

長さを求める(三平方の定理)

亀さんに線を描いてもらうためには長さを教えてあげる必要があります. 長さはどのように求めれば良いのでしょうか? 縦や横の線の長さを求めるのは簡単ですね.では,斜めの場合は? より一般的にある点と点を結んだ長さを求めるのはどうすればよいのでしょうか.

点と点を結んだ線の長さを求めるには,中学校で習った三平方の定理(ピタゴラスの定理)を使います.

三平方の定理

直角三角形の斜辺をcc,他の辺をaba,bとすると次の関係が成り立つ.

a2+b2=c2a^2 + b^2 = c^2

三平方の定理

つまり,

c=a2+b2c = \sqrt{a^2 + b^2}

ここで,2つの点の座標を(xa,ya)(x_a, y_a)(xb,yb)(x_b, y_b)とすると,

c=(xbxa)2+(ybya)2c = \sqrt{(x_b-x_a)^2 + (y_b-y_a)^2}

となります.

たとえば,点(1,2)(1,2)(3,4)(3,4)を結んだ線の距離は

(31)2+(42)2=22+22=8=22\sqrt{(3-1)^2 + (4-2)^2} = \\ \sqrt{2^2 + 2^2} = \sqrt{8} = 2\sqrt{2}

となります.

三平方の定理(点(1,2)と(3,4)を結んだ線の距離)

角度を求める(特別な直角三角形)

それでは,亀さんに線を描いてもらう方向を求めるのはどのようにすれば良いのでしょうか.

まずは,中学校でも習った特別な直角三角形を見てみましょう. そう,三角定規になっている直角二等辺三角形と正三角形を半分にした直角三角形です.

直角二等辺三角形の角度は 45°45\degree, 45°45\degree, 90°90\degreeとなっており,3 辺の比は 1:1:21:1:\sqrt{2} です.

もう一つの直角三角形は角度が 30°30\degree, 60°60\degree, 90°90\degree,また,3 辺の比も 1:2:31:2:\sqrt{3} となります.

特別な直角三角形

上で示した点(1,2)(1,2)(3,4)(3,4)の場合,1 辺の長さが 2 の直角二等辺三角形になりますので,これら 2 点を結んだ線の角度は 45 度になります. このように中学校で習った特別な直角三角形を応用することで,30°30\degree, 45°45\degree, 60°60\degree, 90°90\degreeの方向については角度と長さを求めることができます. これらを回転,あるいは拡大・縮小させることでいろいろな線を(図形の一辺として)描くことができます.

14 セグメントディスプレイ

14セグメントディスプレイ 図:ウィキペディアより引用

7 セグメントディスプレイでは,一部のアルファベットしか表示できませんでした. そこで,7 セグメントディスプレイに斜めと間のセグメントを追加して,全ての数字とアルファベットを表示できるようにしたのが14 セグメントディスプレイです.

14セグメントディスプレイ

この例では,a, b, c, d, e, f と m を点灯させることでアルファベット「Q」を表示しています.

なお,ご覧頂くと分かるように直角三角形を組み合わせることで構成されています. この図ですと 30°30\degree, 60°60\degree, 90°90\degree の直角三角形(たとえば j, g2, b )ですが,直角二等辺三角形でも構成することはできます.

座標と三角関数

中学校で習った特別な直角三角形を使って求めることができる角度は 30 度,45 度,60 度,90 度です. では,それ以外の角度の場合の点の座標はどのように求めれば良いのでしょうか.

これも簡単です.三角関数を利用することで求めることができます.

ようやく高校生の数学がでてきましたね.数学 I(三角比)の内容になります.

座標と三角関数

まずは三角関数の定義から.

PPと原点を結ぶ PO の長さをrrとし,xx軸方向の長さをaa, yy軸方向の長さをbbとする直角三角形を考えます. 角度θ\thetaxx軸と PO のなす角度です.このとき,正弦,余弦,正接は次式で与えられます.

  • 正弦(サイン,sin)
sinθ=br \sin{\theta} = \frac{b}{r}
  • 余弦(コサイン,cos)
cosθ=ar \cos{\theta} = \frac{a}{r}
  • 正接(タンジェント,tan)
tanθ=ba \tan{\theta} = \frac{b}{a}

これより点 P の座標は

P(a,b)=(rcosθ,rsinθ) P(a, b) = ( r \cos{\theta}, r \sin{\theta})

になります(上の図を参照してください).

ここで単位円(r=1r=1)で考えると正弦(サイン)と余弦(コサイン)はとても簡単になります.

sinθ=b \sin{\theta} = b
cosθ=a \cos{\theta} = a

正接(タンジェント)も,サイン,コサインで表すことができます.

tanθ=sinθcosθ \tan{\theta} = \frac{\sin{\theta}}{\cos{\theta}}

先に示した特別な直角三角形の場合,正弦(サイン)と余弦(コサイン)は次のとおりです.

θ\theta 0°0\degree 30°30\degree 45°45\degree 60°60\degree 90°90\degree 120°120\degree 135°135\degree 150°150\degree 180°180\degree
sinθ\sin \theta 0 12\frac{1}{2} 12\frac{1}{\sqrt{2}} 32\frac{3}{\sqrt{2}} 1 32\frac{3}{\sqrt{2}} 12\frac{1}{\sqrt{2}} 12\frac{1}{2} 0
cosθ\cos \theta 1 32\frac{\sqrt{3}}{2} 12\frac{1}{\sqrt{2}} 12\frac{1}{2} 0 12\frac{1}{2} 12\frac{1}{\sqrt{2}} 32\frac{\sqrt{3}}{2} 1

余弦定理

直角三角形の場合,先にみたようにピタゴラスの定理が成り立ちますので,一辺の長さを求めることができました. これを拡張して直角三角形で無い場合でも一辺の長さを求めることができるのが余弦定理です. 一般化されたピタゴラスの定理ともいえます.

三角形の角と辺の関係 図:ウィキペディアより引用

上の図のように ABC\triangle ABC において、a=BCa = BC, b=CAb = CA, c=ABc = AB, α=CAB\alpha = \angle CAB, β=ABC\beta = \angle ABC, γ=BCA\gamma = \angle BCA としたとき

a2=b2+c22bccosαa^2 = b^2 + c^2 -2bc \cos \alpha
b2=c2+a22cacosβb^2 = c^2 + a^2 -2ca \cos \beta \\
c2=a2+b22abcosγc^2 = a^2 + b^2 -2ab \cos \gamma \\

が成り立ちます.

余弦定理を使うことで,任意の角度をもつ三角形の一辺の長さを求めることができます.

なお,直角三角形の場合,つまりα=90°\alpha = 90 \degree だと cosα=0\cos \alpha = 0なので,ピタゴラスの定理

a2=b2+c2a^2 = b^2 + c^2

となります.

逆三角関数

さて,2 点間の長さは余弦定理(直角三角形の場合は三平方の定理)で求めることができます. 一方,始点を原点としてxx軸となす角θ\thetaは逆三角関数で求めることができます.

逆三角関数は高校数学の範囲ではありません.大学に入ってから勉強します. 逆三角関数は,任意の三角比から角度を求めることができるため,工学,物理学,幾何学などで広く使われます.

逆三角関数はそれぞれ次のように書きます.なお,簡単のため(r=1r=1)の場合を示しています.

  • arcsine(sinθ\sin \thetaの逆関数)
θ=arcsinb \theta = \arcsin b
  • arccosine(cosθ\cos \thetaの逆関数)
θ=arccosa \theta = \arccos a
  • arctangent(tanθ\tan \thetaの逆関数)
θ=arctanba \theta = \arctan{ \frac{b}{a} }

関数と再帰呼び出し

関数

まず関数から説明しましょう.

2 つの変数 xxyyについて、xxの値を決めるとそれに応じてyyの値がただ一つ定まるとき、yyxxの関数である,といいいます.

たとえば,

y=ax+by=cosx y = ax + b,\hskip{1em} y = \cos x

のように,yyxxの一次式で表されるとき、yyxxの 1 次関数です. ここで,a,ba, bは定数です.

同様に,

y=ax2+bx+c y = ax^2 + bx + c

のように,yyxxの 2 次式で表されるとき、yyxx の 2 次関数であるといいます. ここでもa,b,ca, b, cは定数です.

xx の関数 yf(x)y = f(x)を関数 f(x)f(x) といい,たとえば f(x)=ax2+bx+cf(x) = ax^2 + bx + c と書きます.

プログラミングでの「関数」も,考え方としては一緒で,関数への入力 xx に対して出力 yy がただ一つ定まるようにします. なお,実際には入力の変数,出力の変数は複数あることが多いです.ここでは,簡単のために 1 つの場合で説明しています.

代入

x=ax=a のとき関数 f(x)f(x) の値を f(a)f(a) で表します. この xx に値 aa をいれることを代入といいます.

  • 例)2 次関数 f(x)=x21f(x)=x^2-1x=3x=3 を代入すると f(3)=8f(3)=8 になります.

漸化式

漸化式とは,ある数列 {an}\{ a_n \}があるとき,数列の各項を,前の項を用いて求めることができる式のことをいいます.

たとえば,1 から順に数を足していく場合,数列 {an}\{ a_n \}を次式のように書くことができます.

a1=0an+1=an+n(n=1,2,3,) a_1 = 0 \\ a_{n+1} = a_n + n \hskip{1em} (n=1, 2, 3, \cdots)

実際に計算してみると,

a2=a1+1=0+1=1a3=a2+2=1+2=3a4=a3+3=3+3=6a5=a4+4=6+4=10% a_1 = 0 \\ a_2 = a_1 + 1 = 0 + 1 = 1 \\ a_3 = a_2 + 2 = 1 + 2 = 3 \\ a_4 = a_3 + 3 = 3 + 3 = 6 \\ a_5 = a_4 + 4 = 6 + 4 = 10 \\ \dots

になり ana_n がただ一つ定まります.

ここで,a2a_2a1a_1 から計算され,a3a_3a2a_2 から計算され,...an+1a_{n+1}ana_n から計算されることに気づくかと思います.つまり,前の計算結果を用いて次の値を計算しています.このような計算の仕方を「再帰」もしくは「再帰呼び出し」といいます.

プログラミング言語では,ある関数を「再帰」的に使うことで,プログラムを効率的に書くことができます. たとえば,階乗の計算や(漸化式で表すことができる)フィボナッチ数の計算を「再帰」を使うことで簡単に書くことができます.

2 日目の講義では,この再帰呼び出しについて学びます. 具体的には,再帰呼び出しを使ってフラクタルを亀さんに描いてもらいます.

以下,簡単に階乗とフィボナッチ数について説明します.

階乗

nn の階乗 n!n! は,11 から nn までの全ての整数の積です.つまり,

n!=k=1nk=n×(n1)×3×2×1 n! = \sum_{k=1}^n k = n \times (n-1) \times \cdots 3 \times 2 \times 1

これは,次式のように漸化式としても書くことができます.

n!={1,if n=0n×(n1)!,if n>0 n! = \begin{cases} 1, &\text{if } n=0 \\ n \times (n-1)!, &\text{if } n>0 \end{cases}

漸化式ですので,再帰呼び出しで関数自身を呼び出すようにプログラミングすることで,読みやすい簡単なプログラムが作れます.

フィボナッチ数

フィボナッチ数列 FnF_n は次の漸化式で定義されます.

F0=0,F1=1,Fn+2=Fn+Fn+1(n0) F_0 = 0, \\ F_1 = 1, \\ F_{n+2} = F_n + F_{n+1} \hskip{1em} ( n \ge 0 )

実際に計算してみると

0,1,1,2,3,5,8,13,21,34,55,0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, \cdots

になります.

フィボナッチ数列が生み出す「らせん」は世界で最も美しい「らせん」と知られています. たとえば,ひまわりの種はらせん状に並んでおり,その数はフィボナッチ数となります.

また,花びらの数はフィボナッチ数であることが多いです.

ひまわり