2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

マンデルブロ集合で遊ぶ(描画編)

Last updated at Posted at 2019-12-23

mandel_loop_gray.png

マンデルブロ集合の描画バリエーションを考える

前記事「マンデルブロ集合で遊ぶ(基本編)」では、マンデルブロ集合の基本的な計算方法を紹介しましたが、描画については最も単純な方法を示しただけでした。
「集合に含まれるか含まれないか」なのですから、基本的には2値で表現され、したがって2色で色分けすれば十分ではあります。

ただ、マンデルブロ集合の計算プログラムをみたとき、次のような値が描画のバリエーションとして使えないでしょうか。

  • 値が発散したときの繰り返し数(for文の制御変数の値)
  • 値が発散の条件を超えたときの超えた瞬間のabs(z)の値

これらの値は、主にマンデルブロ集合から外れた座標のものです。以下、イメージを付けるために、実際に得られた値を描いてみます。

mandelbrot_base.png

値が発散したときの繰り返し数(for文の制御変数の値)

mandel_loop_val.png

マンデルブロ集合に含まれる座標の値は、収束判定のための繰り返し数の最大値(20)になっています。

値が発散の条件を超えたときの超えた瞬間のabs(z)の値

mandel_divergence_val.png

傾向としては、マンデルブロ集合から外側に離れるにしたがって発散判定されたabs(z)の値が、大きくなっていますね。

コード

データを出力する c++ のコードは以下。

#include <iostream>
#include <complex>
using namespace std;
int main()
{
  for(float x = -2.0; x <= 2.0; x += 0.01 ) {
    for(float y = -2.0; y <= 2.0; y += 0.01 ) {
      complex<float> c(x, y);
      complex<float> z(0, 0);
      int i;
      float r;
      for(i = 0; i < 20; i++) {
         r = abs(z);
         if(r > 10.0) {
            break;
         }
         z = z*z + c;
      }
      cout << x << " " << y << " " << i << endl;  // 繰り返しの値をz値として出力
      //cout << x << " " << y << " " << r << endl;  // 発散判定された値をz値として出力
    }
  }
}

最後のcout出力の行のコメントを切り替えて出力データ(tt.dat)をgnuplotの以下のコマンドで描画します。

gnuplot> set size ratio -1
gnuplot> splot "tt.dat" w d

画像表示する

マンデルブロ集合の2次元的な描画は、「画像データ」に近い情報になります。gnuplotでは画像情報の描画機能があるので、それを使って表示してみます。まず出力プログラムを若干変更します。次の4点です。

  • x軸方向のループとy軸方向のループの順を入れ替える
  • yのfor文の初期値、脱出の判定条件、インクリメントを逆にする
  • 出力するのは、x,y座標ではなく、x,y座標でのrの値とする
  • xのループの終了時点で改行する
#include <iostream>
#include <complex>
using namespace std;
int main()
{
  for(float y = 2.0; y >= -2.0; y -= 0.01 ) {
    for(float x = -2.0; x <= 2.0; x += 0.01 ) {
      complex<float> c(x, y);
      complex<float> z(0, 0);
      int i;
      float r;
      for(i = 0; i < 20; i++) {
         r = abs(z);
         if(r > 10.0) {
            break;
         }
         z = z*z + c;
      }
      cout << r << " ";
    }
    cout << endl;
  }
}

上記で出力したデータ(tt.dat)を次のgnuplotのコマンドで描画します。

set size ratio -1
set palette greys
plot "tt.dat" matrix with image

mandelbrot_gnuplot_image.png

まとめ

これらの値( 発散値、繰り返し数)をに対応するカラーマップや濃淡を使って多彩な色分けを行うとさらに不思議な絵を描画する事ができます。

以上です。

2
2
0

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?