Treeを描く
Last-modified: 2019-01-27 (日) 01:45:36 (1518d)
#ref(): File not found: "StarLogo_Tutorial_Title_Fine1.PNG" at page "Treeを描く" Logoを用いたタートルグラフィックスの1つの醍醐味は、「再帰的な図形」 を比較的簡単に描けることではないでしょうか*1。 ここでは、典型的な再帰的図形である「木」を描きます(枝分かれは2つ、左右対称)。 よく知られた(タートル一匹に描かせる)方法に加えて、タートルがたくさん存在するStarLogoならではの方法についても紹介します。 なお、この話題、プログラムに関しては、文献を参考にしました。 目次 タートル一匹に描かせる方法 †次の様な数字で特徴付けられる「木」を描きます。それなりには説明しますが もっと丁寧で詳しい説明が必要であれば、Logoの参考書(サイト)を参照ください。
これを描くタートルへの命令列(手続き)は次の様なものです。 タートルのペンは下ろしているものとします。 <木を描け(len, th)>
というものです。StarLogoでは、次の様に実装します。 まず、上に示した手続きに対応するtreeは、Turtle Procedureとして、次の様になります。 to tree :len :th if :len < 2 [stop] fd :len lt (:th / 2) tree (:len * 0.7) :th rt :th tree (:len * 0.7) :th lt (:th / 2) bk :len end この手続きの特徴はなんといっても、手続きtreeの定義の中で、自分自身と同じ手続きtreeを(2回)呼んでいるというものです。この再帰構造は、描く木の構造と同じものです(樹状再帰と呼ばれます)。 Observer Procedureとしては、初期設定とタートルへの命令を両方書いた次の様な手続きを用意します*2。 to setup_and_draw ca crt 1 ask-turtles [ setxy 0 -60 seth 0 pd tree 10 90 ] end 実行するには、Observer Command Centerのエリアに、次の様なコマンドラインを 打ち込みます setup_and_draw 線がパッチのサイズになっており、多少太めですが、確かに木が描かれているはずです。 #ref(): File not found: "StarLogo_Tutorial_SingleTurtle_Tree0.PNG" at page "Treeを描く" たくさんのタートルに描かせる方法 †StarLogoでは、多くのタートルの生成/消滅が扱えますから、それを利用して木を描かせる方法を紹介します。 基本的な手順は次の様なものです。
タートル側の手続きの実装は次の様なものです。 to draw-branch :len :th fd :len hatch [lt (:th / 2)] hatch [rt (:th / 2)] die end hatchという命令で、タートルは自分のコピーを生成しています。1匹目のタートルを生成したあとは、その方向を左にth/2だけ回転し、2匹目のタートルは右にth/2だけ方向を回転しています。生成されたタートルは、この時点ではまだ先の枝を描く動作を行っていません。 次に、上のタートルの手続き実行を制御するためのObserver側の手続きを書きます。この方法では、現在存在するタートルに対して、上記draw-branch手続きを行わせるというものです。 to tree :len :th ask-turtles [ if (:len < 2) [stop] draw-branch :len :th ] tree (:len * 0.7) :th end この手続き内で、再帰的に手続きが呼び出されていますが、これは、一匹のタートルでの手続きとは違い、最後に1度だけ呼ばれています*3。 最後に、初期設定とタートルへの命令を両方書いた手続きを用意します to setup_and_draw ca crt 1 ask-turtles [ setxy 0 -60 seth 0 pd ] tree 10 90 end treeの呼び出しが、ask-turtlesの外側にある事に注意してください。 実行するには、1匹の場合と同様、Observer Command Centerのエリアに、次の様なコマンドラインを打ち込みます setup_and_draw #ref(): File not found: "StarLogo_Tutorial_SingleTurtle_Tree0.PNG" at page "Treeを描く" もう一つの実装 †前の例では、StarLogoらしく多くのタートルが出てきましたが、比較的「中央集権的」 な感じがします。もう少しタートルの自立的な行動を前面にだす実装を考えて見ます。 まず、進む距離は、上から与えられるのではなく、「タートルが自分で保持する」という様にします。各々のタートルにそれぞれが独自にもつ変数stepを割り当てるには、Turtle Prodedures エリアに、次の様に記述します。 turtles-own [ step ] 次に、タートルの初期設定の手続きを書きます。 to turtle-setup :length setxy 0 -60 seth 0 set step :length pd end 本体は多少長くなりますが、方針的には、前回のものと同じです。 to draw-branch :th ifelse step < 2 [die] [ forward step hatch [ set step (step * 0.7) lt (:th / 2) ] hatch [ set step (step * 0.7) rt (:th / 2) ] die ] end Resnikの本によれば、Observerからの制御の代わりに、「タートルデーモン」という ものを追加し、次の様に書くことによってタートルの自立制御を行うといっています。 activate-demon [ draw-branch ] しかし、現在配布されているStarLogo(Version2.x)のコマンドマニュアルにはこの activate-demonコマンドは見当たりませんでした。 そこで、タートルデーモンの考え方に近い動きをさせるため、この手続きを実行する ボタンを作成し、「foreverチェックボックス」をONにして、実行する事とします。 さもなければ、生成されたタートルの方向を決めたあと、この手続きを再帰的に呼ぶ という手もあります。 to draw-branch :th ifelse step < 2 [die] [ forward step hatch [ set step (step * 0.7) lt (:th / 2) draw-branch :th ; 追加:再帰的にこの手続きを適用 ] hatch [ set step (step * 0.7) rt (:th / 2) draw-branch :th ; 追加:再帰的にこの手続きを適用 ] die ] end 最後に、Observer Procedureには次の様な手続きを書きます。 to setup :length ca crt 1 ask-turtles [turtle-setup :length] end 実行は、Observer Command Centerで、 turtle-setup 10 などとし、Turtle Command Centerで、 draw-branch 90 の様にします。与える数字に関しては、いろいろためしてみると面白いかもしれません。 なお、上の数字で実行するとこれまでと描かれる絵は同じです。] 更新 †2005/06/26 †先頭の画像を変更。少しパッチを高解像度にした。
Counter: 333,
today: 1,
yesterday: 0
|