Mathematica でフラクタル図形を作ろう

演習問題を行う前に Mathematica を使うときの注意を良く読んでください.


内容

  1. タートルグラフィックス
  2. 複素力学系のフラクタル
  3. 実数の写像によるフラクタル
  4. 課題

タートルグラフィックス

今、画面上に一匹のカメがいるとします。このカメは始めは上を向いてとまっています。このカメに次の命令を送って、カメを画面上で動かします。

 z  カメの位置を初期状態( 位置(0,0), 方向(0,1) )にセットする。
 f  カメを今向いている方向に向かって 1ほど 動かす。
 r  カメの向きを右へ決められた角度ほど回転させる。
 l  カメの向きを左へ決められた角度ほど回転させる。
 g  カメが動いた軌跡を線で表す.

命令 g を実行することで、カメが動いた後は線となって残ります。 これを使って図形を描いてみましょう。

変数 ichi で、カメの位置 を、変数 houkou でカメの向き を表すことにします。変数 kiseki でカメの通った軌跡の座標をリストで表します. 命令 z を実行されると、カメの位置が、(x,y)=(0,0) 、カメの向いている方向が、上( (0,1) の方向)となるのですから、move[z] を次のように定義します.

入力
出力

move[z] が実行されると、変数 houkou に {0, 1} が、変数 ichi に {0,0} が、kiseki に {{0,0}} が代入されることがわかりますね.

次に、f に対する動きを定義します。これは、カメが今いる座標 ichi に、向いている方向 houkou を足し、その結果の ichi を kiseki にリストとして加えればよいのですから、次のように定義します.

入力
出力

次に r に対する動きを定義します。このために角度を th ほど回転させる命令 kaiten を定義しましょう。これは、今の向き houkou を th ほど回転させればよいので、次のように定義します。

入力
出力

回転角度は Pi/3 にします。 move[r] は次のように書けます。

入力
出力

l に対する動きも同様に定義できます。

入力
出力

次にリストに対して move が使えるようにするために次のように置きます。

入力
出力

こうすると move[{x1, x2, ..., xn}] が {move[x1], move[x2], ..., move[xn]} となります。ちょっとやってみましょう。

まず、{z,f} を考えます。これは、{move[z], move[f]} となり、カメが真っ直ぐ進むだけです.

入力
出力

として、カメの軌跡を表す変数 kiseki の値を見てみると

入力
出力

となり、(x,y)=(0,0) と (x,y)=(0,1) がカメの軌跡として得られました.これを線で表示してみましょう.

入力
出力

上と同じことを move[g] で行えばよいので、move[g] を次のように定義します.

入力
出力

move[g] を実行してみます.

入力
出力

それでは、move[{z,f,g}] を実行してみましょう.これも上と同じ軌跡が描かれるはずです.

入力
出力

次に {z,f,r,f,l,f,g} とカメを動かしてみます。今度は、まず1ほど前に進み、右に 60度回転し、また前に進み、その次に今度は左に 60度回転し、前に進み、最後にこれまで通ってきた軌跡を表示します。よってカメの通った後は次のようになります。

入力
出力

上の入力の最後にセミコロン ; をつけたのは move[{z,f,r,f,l,f,g}] の出力を抑えるためです.セミコロンをつけても、上の軌跡は表示されますが、それともにリストが表示されます.これはmove[{z,f,r,f,l,f,g}] の返り値なのですが、今回は返り値に意味はないので、それを画面に表示しないようにセミコロンをつけています.

次は {z,f,r,r,f,r,r,f} とカメを動かしてみますmove[{z,f,r,r,f,r,r,f,g}] は {move[z], move[f], move[r], move[r], move[f], move[r],move[r], move[f], move[g]} となります。このとき、カメはまず1ほど前に進み、その後 120度右に回転、また1ほど進み、また120度
右に回転し1ほど進み、最後にその軌跡が表示されます。つまり、カメの通った後は正三角形になるはずです。やってみましょう。

入力
出力
入力
出力

次に上の s={z,f,r,r,f,r,r,f} に対して、 {f -> {f,l,f,r,r,f,l,f}} の置き換えを行うことを考えます。この置き換えを rule2 とおきます。

入力
出力

s に対して、この rule2 を適用してみます。

入力
出力

これは、直線

を折れ曲がった直線

で置き換えることに相当します。表示してみましょう。
まず、s2 の二重のリストを Flatten で一重にします。

入力
出力

s2 にそってカメを動かします。

入力
出力

正三角形の直線の部分が、置き換わっていることがわかります。次に上の s2 に対してさらに rule2 を適用してみましょう。更に直線が上の折れ曲がった直線に置き換えられるはずです。

入力
出力
入力
出力

このときのカメの動きを表示してみましょう。

入力
出力

かなり形が変わってきました。さらに置き換えを行ってみます。

入力
出力
入力
出力
入力
出力
入力
出力

次第に雪の結晶に似てきたと思いませんか?ある図形を拡大したときにまた同じ図形が現れることを自己相似性と呼びます。上の図形は、直線を折れ曲がった直線で置き換える操作を繰り返し行ってきたので、自己相似性を持っています。この自己相似性はフラクタル図形の特徴の一つですが、雪の結晶はこういった自己相似性を持っていることになります。自然界には、この他にも自己相似性を持っているものがたくさんあります。

次にもう少し複雑なタートルグラフィックスを考えましょう。この場合は回転角を 2Pi/3 にするので、move[r], move[l] を下のように定義し直します。

入力
出力
入力
出力

図形を書きかえるルールは、次のものを考えます。

入力
出力

上のルールでは、f を {f, f} に(つまり直線の長さを2倍に)して、y を {f, r, y, l, y, l, y, r, f}で置き換えます。この y は置き換えのためにだけ使われる変数で、y に対してカメは動きません。ですから move[y] は次のように定義します。

入力
出力

上の式の右辺の 0 の値に深い意味はありません. y という命令が来たときには何もしなければよいので、何でもよいのですが、簡単のために 0 という値にしました.

カメの始めの動き t を次のようにします。

入力
出力

上の置き換えルールを一度適用します。

入力
出力

この動きを表示すると、正三角形となります。

入力
出力
入力
出力

上の s1 に、また rule3 を適用してみましょう。

入力
出力

カメの動いた後を表示してみます。

入力
出力
入力
出力

s2 に、また rule3 を適用してみましょう。

入力
出力

カメの動いた軌跡を表示してみます。

入力
出力
入力
出力

以後、どんどん続けていきます。

入力
出力
入力
出力
入力
出力
入力
出力
入力
出力
入力
出力

上の図形はシェルピンスキーの三角形と呼ばれています。


複素力学系のフラクタル

次の写像 F を考えます。

今、複素平面内の一点 z0 に対して上の写像を zn の絶対値が 2 以上になるまで繰り返し、この時の写像を行った回数を点 z0 での値とします。例えば、

入力
出力

とすると

入力
出力
入力
出力
入力
出力
入力
出力
入力
出力
入力
出力

となり、3回写像を行ったところでその絶対値が 2 を超えるので、z0=0.5+0.6 i での値は3です。このような関数を定義します。

まず、上の写像を行う関数 g[x,c] を定義します。

入力
出力

この時、上の値を返す syazo[f,c] は Mathemtica で次のように定義できます。

入力
出力

syazo[g, 0.5+0.6I] を計算してみます。

入力
出力

先ほどの計算と一致しました。

この syazo の複素平面上での値を DensityPlot で表示してみましょう。 DensityPlot は関数の値に応じて、その点を色分けして表示してくれる関数です。まず、-2 < Re[z0] < 0.5, -1.1 < Im[z0] < 1.1 の範囲で表示してみます。

入力
出力
入力
出力

これではよく分からないので、メッシュをもう少し細かくしてみましょう。この計算は少し時間がかかります。

入力
出力

これが有名なマンデルブロー集合です。もう少し近づいて、-1.3 < Re[z0] < -1.1, 0.2 < Im[z0] < 0.4 で表示してみましょう。

入力
出力

-1.2 < Re[z0] < -1.15, 0.23 < Im[z0] < 0.28 で表示してみましょう。

入力
出力

実数の写像によるフラクタル

ここでは、実数の写像によるフラクタルを取り扱います。

次の写像を考えます。

与えられた点 (x0,y0) に上の写像を何度も適用し、得られた点 (xn,yn) を小さな点としてプロットするとフラクタル図形が得られます。ただし、a は絶対値が1未満のパラメータで、これを変えることにより、さまざまなフラクタル図形を描くことができます。

やってみましょう。まず、上の写像を定義します。

入力
出力

次に実際に図を描く、命令 fracPlot を定義します。

入力
出力

今、a=0.8, (x0,y0)=(0.1,0.2) として、n=10000 まで (xn,yn) を計算し、その点をプロットすることでフラクタル図形を描いてみます。

入力
出力
入力
出力
入力
出力

a=-0.6 にしてみましょう。

入力
出力
入力
出力

a=-0.9 から 0.3 まで、Pi/20 刻みに a を変えながら、フラクタル図形を描いてみます。

入力
出力
入力
出力








課題

(1)(i) カメの動いた後が、置き換えルールを適用していく毎に次のようになっていくような、カメの始めの動き t と置き換えルール rule5 を定義せよ。




(2)カメの動いた後が、置き換えルールを適用していく毎に次のようになっていくような、カメの始めの動き t と置き換えルール rule6 を定義せよ。
(ヒント:この図形を木とみて、枝の 部分を x と置き、この部分を置き換えるルールを考えよ)







(3)(x0,y0)=(0.1, 0.2) を次の写像で変換するときに、n=10000 まで (xn, yn) を点としてプロットせよ。ただし、a,b,c はそれぞれ 0 から 1 までの進当に選んだ 実数とし、5つの異なる a, b, c の組みに対し、プロットを行え。

(ヒント:Mathematica で sgn(x) は Sign[x], | x | は Abs[x] である)