タートルグラフィクスとL-system
Cinderellaでタートルグラフィクスのシステムを構築します。ただし、LOGOのような命令体系とは少し異なり、リンデンマイヤーのL-systemに準拠したものとします。
タートルに与えるコマンドは次のものです。
A,B,F 描画しながら前に進む
f 描画しないで前に進む
−, + 右・左を向く
S,R,L 何もしない
[ 現在の状態をスタックに入れる(位置と向きを記憶する)
] スタックからひとつ取り出す(記憶した位置と向きに戻す)
描画しながら前に進むのと、何もしないのが複数あるのは、置き換えシステムを使うからです。
置き換えシステムとは、ある文字列を別の文字列で置き換えて亀に与えるコマンドを作ることです。
初めの図形を描く命令文字列をイニシエータ
置き換える命令文字列とその規則をジェネレータといいます。
【例】シェルピンスキーのギャスケット
有名な図形ですが、これを作るにはちょっとしたテクニックが必要です。(山口大学のテキストを参考にしました)
イニシエータ S-F-F
ジェネレータ F→FF および S→F-S+S+S-F
角度 120°
【例】ヒルベルト曲線
これも有名な図形です。
イニシエータ L
ジェネレータ R→-LF+RFR+FL- と L→+RF-LFL-FR+
角度 90°
【例】植物の生長モデル
イニシエータ ++++A
ジェネレータ F→FF と A→F-[[A]+A]+F[+FA]-A
角度24°
植物の成長も出るでは、[ と ] を用いることにより枝分かれを実現しています。
これらは、KETCindyのListplot() だけを用いていますが、描く線分が多いので、現在のシステムではあまり大掛かりな図はできません。
システムは次のスクリプトで,これをInitializaitonスロットに書きます。(ここからカット・アンド・ペーストできます)
// 回転行列
rt(th):=[[cos(th),-sin(th)],[sin(th),cos(th)]];
// 前に Tstep だけ進む
forward():=(
regional(p);
p=Tpos+Tstep*Tdirec;
Tlist=append(Tlist,p);
Tpos=p;
);
// 亀を命令に従って動かす
turtle(command,angle):=(
if(command=="A",forward());
if(command=="B",forward());
if(command=="F",forward());
if(command=="f",Tpos=Tpos+Tstep*Tdirec);
// if(command=="S",);
if(command=="+",Tdirec=rt(angle)*Tdirec);
if(command=="-",Tdirec=rt(-angle)*Tdirec);
if(command=="[",Tstack=prepend([Depth,Tpos,Tdirec],Tstack);
Depth=Depth+1;
ketpicoutput();
Tlist=[Tpos];
);
if(command=="]",Tpos=Tstack_1_2;
Tdirec=Tstack_1_3;
Tstack=Tstack--[Tstack_1];
ketpicoutput();
Tlist=[Tpos];
);
);
// Tlist を Listplot() にデータ書き出し,Tlistは空に
ketpicoutput():=(
if(length(Tlist)>1,
Count=Count+1;
Listplot(text(Count),Tlist);
);
Tlist=[];
);
// 亀を動かして描画
drawturtle(pos,th,n,angle):=(
regional(str);
Count=0;
Tlist=[pos];
Tpos=pos;
Tdirec=[cos(th),sin(th)];
Tstack=[];
Depth=1;
str=Initiator;
repeat(n,str=replace(str,Generator));
repeat(length(str),turtle(str_#,angle));
ketpicoutput();
);
描画に関することはDraw スロットに,亀の設定などを書きます。
以下はヒルベルト曲線の場合です。
Ketinit();
Setfiles("turtle");
Setparent("fig");
Addax(0);
// ヒルベルト曲線
initpos=[0,0];
initdeg=0;
kaku=90°;
initiator="L";
generator=[["R","-LF+RFR+FL-"],["L","+RF-LFL-FR+"]];
// n=6 くらいまで n=7 は時間がかかる
n=5;
Tstep=0.2;
drawturtle(initpos,initdeg,n,kaku);
Figpdf();
Windispg();
シェルピンスキーのギャスケットは次のようにします。Tstepは適当に設定します。
initpos=[0,0];
initdeg=-pi/3;
kaku=120°;
initiator="+S-F-F";
generator=[["F","FF"],["S","F-S+S+S-F"]];
//n=7 まではいける n=8 も可能だけど結構時間がかかる
植物の成長モデルは次のようにします。
initpos=[5,0];
initdeg=-6°;
kaku=24°;
initiator="++++A";
generator=[["F","FF"],["A","F-[[A]+A]+F[+FA]-A"]];
// 分岐が多いため n=4 まで それ以上は、Cinderellaでは書けるが Scilabで処理できない
< 戻る >