2002後期
情報グラフィックス論U
担当 鳥海有紀
2002後期 情報グラフィックス論U

フラクタル

フラクタルは自己相似性を持った図形の総称である。 図形の一部分を取り出すとその部分が図形全体を縮小したものになっているような図形のことを言う。 フラクタルによって、コンピュータで自然の風景を構成することが可能になってきている。 フラクタルの例として、マンデルブロ集合、ジュリア集合、再帰呼び出しによる木の表現を挙げる。

マンデルブロ集合
マンデルブロが発見したフラクタルで、複素定数Cの平面でZn-1=Zn2+Cが発散しない領域のことである。マンデルブロ集合が存在する領域は実部が-2.0から0.5、虚部が-1.3から1.3の範囲に収まっている。この範囲のどの部分を表示するかによって、様々に変化する模様を見ることができる。

ジュリア集合
ジュリア集合は、マンデルブロ集合に用いた式と同じものを使って、Zに複素平面を指定しCに任意の値を用いたものである。

再帰呼び出し
自己相似性を作る方法はマンデルブロ集合やジュリア集合を求めるときのように漸化式をつかう。あるいは、同じ処理を繰り返し呼び出す「再帰呼び出し」を使う。この方法で作成される図形には、コッホ曲線やツリーなどがある。

マンデルブロ集合

今回は、マンデルブロ集合を取り上げる。 以下はマンデルブロ集合を表示するためのプログラムである。


#include <stdio.h>

int main(void)
{
    int     i, j, k;
    double  a, b;
    double  x, y;
    double  nextX, nextY;

    gopen(500, 500);

    /*  実部(X方向)のループ */
    for (i = 0; i < 500; i++) {

        a = i * 2.6 / 500.0 - 2.0;

        /*  虚部(Y方向)のループ  */
        for (j = 0; j < 500; j++) {

            b = j * 2.6 / 500.0 - 1.3;


            /* 変数の初期値を設定する  */     /*---------  @ Zn-1=Zn2+Cの計算部分 -------*/     
            x = 0.0;
            y = 0.0;
            /* 変数を繰り返し計算した結果が発散するか調べる */
            for (k = 0; k < 100; k++) {
                nextX = x * x - y * y + a;
                nextY = 2.0 * x * y + b;
                x = nextX;
                y = nextY;
                if (4.0 < x * x + y * y) {
                    /* 変数の大きさが4.0より大きい場合は
           発散したものとしてループを終了する */
                    break;
                }
            }                                  /*---------  Zn-1=Zn2+Cの計算部分 終わり -------*/

            if (k % 5 == 0)                    /*--------- A 発散した計算回数によって色分けをする */
                gpoint(i, j, 255, 255, 255);
            else if (k % 5 == 1) 
                gpoint(i, j, 255, 0, 0);
            else if (k % 5 == 2) 
                gpoint(i, j, 255, 200, 200);
            else if (k % 5 == 3) 
                gpoint(i, j, 200, 200, 255);
            else if (k % 5 == 4) 
                gpoint(i, j, 200, 100, 255);   /*--------- 色分けをする 終わり----------------- */

        }
    }
    gclose();

プログラムの構成を見てみる。 マンデルブロ集合は、画像の各画素の色を複素数の式Zn-1=Zn2+Cを使って計算結果(Zn+1の値)が発散する(ある値より大きくなる)かどうか、いつ発散するかで決定することによってできるものである。
@、Aの計算を各画素に対して実行する。このため、2重ループが必要である。ここではカウンタ変数iを使ってX方向の画素のループ、カウンタ変数jを使ってY方向の画素のループになっている。
マンデルブロの計算では、実数を使う必要がある。 実数を使う場合は変数の宣言でdoubleを使う。 上記のプログラムでは画像の大きさは500x500である。表示している範囲は、Xが-2.0から0.6、Yが-1.3から1.3である。表示している範囲はX方向もY方向も2.6である。この範囲を表示するためにプログラムでは、次のように指定している。


    /*  実部(X方向)のループ */
    for (i = 0; i > 500; i++) {
        a = i * 2.6 / 500.0 - 2.0;

ここで、2.6はX方向の表示範囲、 500.0はX方向の画素数(ループ回数) -2.0はXの開始位置を示している。Y方向は


        /*  虚部(Y方向)のループ  */
        for (j = 0; j < 500; j++) {

            b = j * 2.6 / 500.0 - 1.3;

2.6はY方向の表示範囲、 500.0はY方向の画素数(ループ回数) -1.3はYの開始位置を示している。

上記のプログラムで表示される図形は右図のようになる。マンデルブロ集合のはおおよそこの範囲に入る。 図中の四角の範囲を表示する場合にはプログラムを次のようにすればよい。


 /*  実部(X方向)のループ */
 for (i = 0; i < 500; i++) {
    a = i * 0.4 / 500.0 - 0.35;
    
    /*  虚部(Y方向)のループ  */
    for (j = 0; j < 500; j++) {
        b = j * 0.4 / 500.0 + 0.6;


情報グラフィックス論U 2002後期

Copyright 2002-2003 Yuki Toriumi