見出し画像

プログラミング今昔:コッホ曲線

「フラクタルCGコレクション」渕上季代絵:サイエンス社 という本がある。
口絵にはマンデルブロ集合,ジュリア集合がカラフルに描かれている。
昭和62年(1987年)の発行。MS-DOS,BASIC全盛期の頃だ。
したがって,プログラムは BASIC。マンデルブロ集合を描くのに数分かかっていた。

 勤務校がSSH指定校だったころ,「情報」の代替として「サイエンス探究」という授業をやっていた。SSHなので,複素数平面を使って,マンデルブロ集合やジュリア集合を描かせる授業を行った。言語はCindyScript。タートルグラフィクスでコッホ曲線もやった。コッホ曲線は大学入試問題として出題されたこともあるので,題材としてもよい。
 描画に何分もかかっていたのでは授業では使えないが,そこはパソコンの性能向上とプログラミング言語のおかげで,数秒待つだけでよい。

 今年,理数科の3年生の情報で,プログラミングをやっている。媒介変数と曲線はCindyScript,統計(ヒストグラム,箱ひげ図,相関)はRで。
その演習問題として,フラクタルを取り上げようかと思った。しかし

・タートルグラフィクスはそのためのシステムを作って渡す必要がある。
 Pythonならばタートルグラフィクスが使えるが,Pythonはやっていない。
・マンデルブロ集合は,原理は難しくないし,プログラム量も少ないが,描画のためにはCindyScriptの colorplot という関数を使う。Mathematica の DensityPlot と同じようなものだ。

 以前やった経験から,1コマの内容としてはどうかな,と思うところがある。テキスト通りに打ち込んでパラメータを変えてみるだけでは面白くない。主眼が「マンデルブロ集合とはなにか」ではなく「複素数平面とプログラミング」だからだ。

 そこで,複素数平面を使ってコッホ曲線を描くことを考えた。

 1本の線分を三等分し,中央で正三角形状に折り曲げる。はじめの線分をイニシエータ,折り曲げた折れ線をジェネレータと呼び,イニシエータの線分をジェネレータで置き換える。できた図形の各線分を再びジェネレータで置き換えると次のようになる。

画像1

さらに置き換えを続けると次のようになっていく。 

画像2

イニシエータを正三角形にすると,次のようになっていく。

画像3

これがコッホ曲線で,前者を雲形曲線,後者を雪片曲線という。
これらを描画するにあたって,ジェネレータの描き方を考えてみよう。
線分を3等分して,中央を正三角形にする。このとき,座標で計算するより,複素数を使う方が簡単なのだ。
以前の教育課程なら,数学で行列を学んでいるので,回転行列が使える。今は行列がない代わりに複素数平面があるので,複素数を利用する。数学の復習にもなる。
 つぎに,線分をジェネレータで置き換えていく手続きを関数として作る。それぞれの頂点(線分の両端の点)はリストで表せるのでリスト処理でできる。

// 2点(複素数)を与えて,ジェネレータの点リストを返す
generator(z1,z2):=(
 z3=(2*z1+z2)/3;
 z4=(z1+2*z2)/3;
 z5=z3+(z4-z3)*(cos(pi/3)+i*sin(pi/3));
 [z1,z3,z5,z4,z2];
);
// 線分(折れ線)の置き換えをする
replacing(plist):=(
 work=[];
 repeat(length(plist)-1,s,
   work=work++generator(plist_s,plist_(s+1));
 );
 ret=[work_1];
 repeat(length(work)-1,s,
   if(work_s!=work_(s+1),
     ret=append(ret,work_(s+1));
   );
 );
 ret;
);
// ここから描画
apex=[0,6];
repeat(4,
 apex=replacing(apex);
);
pt=apply(apex,gauss(#));
connect(pt);
​

コメント行を除くと26行(空行1つ含む)だから,1コマの授業分としては適切な量だ。プログラミングをやったことのない人には読めないと思うが,Python などを使ったことのある人ならだいたいわかるだろう。そうでない人も,repeat は繰り返しだし,append は適用,apex は頂点 ,connect は繋ぐ なので,なんとなくわかるかもしれない。

冒頭に挙げた「フラクタルCGコレクション」では次のようになっている。

画像4

行数も多いし,読んでも何をしているのか一度ではわからない。GOTOであっちこっち飛ぶのもなつかしいといえばなつかしい。
JavaScript や Python でプログラミングを始めた人には一苦労だろう。

まさに隔世の感がある。