LoginSignup
2
2

More than 5 years have passed since last update.

シェルピンスキーのカーペット(Mathematicaショートフラクタルシリーズ)

Last updated at Posted at 2015-12-15

今回のテーマ

Mathematicaショートフラクタルシリーズ、第2回は前回のシェルピンスキーのギャスケットの四角形版ともいえる、シェルピンスキーのカーペットです。

ほぼ完成形

sierpinskiCarpet[x_] := ArrayFlatten[x /. {
  0 -> {
   {0, 0, 0},
   {0, 0, 0},
   {0, 0, 0}
  },
  1 -> {
   {1, 1, 1},
   {1, 0, 1},
   {1, 1, 1}
  }
}]
ArrayPlot[Nest[sierpinskiCarpet, 1, 5], PixelConstrained -> 1, Frame -> False]

sierpinski-carpet.png

描画としてはこれで充分です。

これ、自力で導出したものだったとは記憶していますが、Sierpinski carpet - Rosetta Codeでもほぼ同じ処理のコードが書いてありました。

今回もコードを紐解きながら、ショートコード化しましょう。

生成過程

In[1] = sierpinskiCarpet[1]
Out[1] = {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}

数値1に対して、

  1 -> {
   {1, 1, 1},
   {1, 0, 1},
   {1, 1, 1}
  }

のルールが適用されるので、{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}が返ってきます。

フラクタルは反復です。再帰です。ネストです。

2重にしましょう。

In[2] = sierpinskiCarpet[sierpinskiCarpet[1]]
Out[2] = {{1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 1, 1, 0, 1, 1, 0, 1}, {1, 1, 1, 
  1, 1, 1, 1, 1, 1}, {1, 1, 1, 0, 0, 0, 1, 1, 1}, {1, 0, 1, 0, 0, 0, 
  1, 0, 1}, {1, 1, 1, 0, 0, 0, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 
  1}, {1, 0, 1, 1, 0, 1, 1, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1}}

既にけっこう長いリストですが、プロットするとこうです。

ArrayPlot[sierpinskiCarpet[sierpinskiCarpet[1]]]

sierpinski-carpet_2.png

すんなり描画できてますが、仮に数字をリストに置換するだけでは、以下のようにどんどん深いネストになってしまいます。

{{{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, {{1, 1, 1}, {1, 0, 1}, {1, 1, 
    1}}, {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}}, {{{1, 1, 1}, {1, 0, 
    1}, {1, 1, 1}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, {{1, 1, 1}, {1,
     0, 1}, {1, 1, 1}}}, {{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, {{1, 1, 
    1}, {1, 0, 1}, {1, 1, 1}}, {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}}}

毎回ArrayFlattenで平坦化することにより、常に2次元リストが保たれ、いつでもプロットできる状態になります。

ショートコード化

  • 別途定義していたsierpinskiCarpet関数を即時関数化
  • 0だけの3×3のリストを作るのにConstantArrayを使う
  • 5回のネスト

で、以下の95文字のプログラムができました。

ArrayPlot[Nest[ArrayFlatten[#/.{0->ConstantArray[0,{3,3}],1->{{1,1,1},{1,0,1},{1,1,1}}}]&,1,5]]

ちなみに、128文字まで増えちゃいますが、ビットマップ書き出しする際には、PixelConstrained->1Frame->Falseのオプションを付けないと綺麗に書き出せないんですよね。

ArrayPlot[
  Nest[
    ArrayFlatten[
      #/.{
        0 -> ConstantArray[0,{3,3}],
        1 -> {{1,1,1},{1,0,1},{1,1,1}}
      }
    ]&,
    1,
    5
  ],
  PixelConstrained->1,
  Frame->False
]

それか、白黒反転して、Rasterのグラフィックプリミティブを使ってもいいかもしれませんね。

Graphics[Raster[Nest[
  ArrayFlatten[
    #/.{
      1 -> ConstantArray[1,{3,3}],
      0 -> {{0,0,0},{0,1,0},{0,0,0}}
    }
  ]&,
  0,
  5
]]]

デモ

Mathematica版のオンラインデモはまだ上げられていませんが、
JavaScript版 (jsdo.it)ならありますので、遊んでみてください。

カーペットフラクタル - jsdo.it
jsdo.itデモのサムネイル

これ、デフォルトではシェルピンスキーのカーペットですが、チェックボックスクリックでジェネレーターを変化させて、3×3だけでも他にも有名なフラクタル図形を数々描画できます。

sierpinski_carpet_small.png

↑ シェルピンスキーのカーペット

sierpinski_gasket.png

↑ シェルピンスキーのギャスケット(昨日のやつの変形版)

cantor_dust.png

↑ カントールの塵集合

vicsek_fractal.png

↑ Vicsek Fractal

hexaflake.png

↑ Hexaflake

予告

明日はコッホ曲線です。

2
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2