Step07 フラクタル、マンデルブロ、コッホ曲線


#1

このところライブラリの説明ばかりで面白くありません。
そこで少し横道に逸れて、大昔のソースコードをArduboyに移植してみました。

コンピューターアート、という言葉は最近あまり耳にしないかもしれません。
ただフラクタル、マンデルブロは少ないコードで美しい表現をしてくれます。

中身は私も理解していないのですが(汗)、ただ入力するだけでも楽しいです。
ぜひ実機で試してみてください。

資料はCによるフラクタルCG(1993年発行)を使わせて頂きました。

■フラクタル

#include <Arduboy.h>

#define NX  128
#define NT  63

Arduboy ab;

void exec()
{
    int x1[NX], x2[NX];
    int t, i;

    for(i=0; i<NX; i++)
    {
        x1[i] = 0;
        x2[i] = 0;
    }

    t = 1;
    x1[NT] = 1;

    for(t=0; t<NT; t++)
    {
        for(i=NT-t; i<NT+t; i++)
        {
            x2[i] = (x1[i - 1] + x1[i + 1]) % 2;

            ab.drawPixel(i, t, x2[i]);
            ab.display();
        }

        for(i=NT-t; i<NT+t; i++)
        {
            x1[i] = x2[i];
        }
    }
}

void setup()
{
    ab.beginNoLogo();
    ab.setFrameRate(30);
    ab.clear();
    ab.display();

    exec();
}

void loop()
{
    if(!(ab.nextFrame()))
    {
        return;
    }

    // EMPTY
}

余談:

x2[i] = (x1[i - 1] + x1[i + 1]) % 2;

x2[i] = (x1[i - 1] + x1[i]) % 2;

に変えるとまた違った形が出てきます。

■マンデルブロ

#include <Arduboy.h>

#define KL        100
#define KS         64

#define RS       -2.2
#define RE        0.5
#define IS      -1.35
#define IE       1.35

Arduboy ab;

typedef struct {
    double r;
    double i;
} ST_RI;

void exec()
{
    int xx, yy, k;
    double dr, di;

    ST_RI z, z2, c;

    dr = (RE - RS) / KS;
    di = (IE - IS) / KS;

    for(xx=0; xx<KS; xx++)
    {
        for(yy=0; yy<KS; yy++)
        {
            c.r = xx * dr + RS;
            c.i = yy * di + IS;

            z.r = 0.0;
            z.i = 0.0;

            for(k=0; k<=KL; k++)
            {
                z2.r = z.r * z.r - z.i * z.i + c.r;
                z2.i = 2.0 * z.r * z.i + c.i;

                if(z2.r * z2.r + z2.i * z2.i > 4.0)
                {
                    ab.drawPixel(32 + xx, 63 - yy, (k > 6) ? 1 : 0);
                    ab.display();

                    break;
                }

                z = z2;
            }
        }
    }
}

// setup, loop関数は省略

余談:

(k > 6) ? 1 : 0

k % 2

に変えると色彩が変化します。

■コッホ曲線

#include <Arduboy.h>

#define N       10
#define KS      64
#define RS      0.0
#define RE      0.5
#define IS      -0.25
#define IE       0.25

Arduboy ab;

typedef struct {
    double r;
    double i;
} ST_RI;

double dr = (RE - RS) / KS;
double di = (IE - IS) / KS;

void exec()
{
    ST_RI a = { 0.0, 0.0 };
    ST_RI b = { 0.5, 0.2887 };
    ST_RI c = { 0.0, 0.0 };
    ST_RI d = { 0.5, -0.2887 };

    ST_RI z = { 0.0, 0.0 };

    generater(&z, &a, &b, &c, &d, N);
}

void generater(ST_RI* z, ST_RI* a, ST_RI* b, ST_RI* c, ST_RI* d, int n)
{
    int xx = (z->r - RS) / dr;
    int yy = 64+16 - (z->i - IS) / di;
    ST_RI z1;

    ab.drawPixel(xx, yy, 1);
    ab.display();

    if(--n < 0)
    {
        return;
    }

    z1.r = z->r * (a->r + b->r) - z->i * (a->i - b->i);
    z1.i = z->r * (a->i + b->i) + z->i * (a->r - b->r);

    generater(&z1, a, b, c, d, n);

    z1.r = z->r * (c->r + d->r) - z->i * (c->i - d->i) - c->r - d->r + 1.0;
    z1.i = z->r * (c->i + d->i) + z->i * (c->r - d->r) - c->i - d->i;

    generater(&z1, a, b, c, d, n);
}

// setup, loop関数は省略

Topics for 10 Part Lesson Plan [Draft]
(koteitan) #2

いやぁ、なつかしいですね。私も PC-8801 でマンデルブロ曲線を書かせてました。あのころは描画に1日かかりましたよ


#3

上記のコードだと30秒ほどで完了します。

1チップでこんなに早く処理してしまうのかと驚きです。
技術の進歩はすごいですよね。

PC98だったかwindows95のころの話ですが、僕の場合、
ASCIIから出してたCGツクール(?)という書籍で遊んでいました。

数時間かけて、たまにCRTのディスプレイを点けてみて、
ちょっとづつ浮かび上がってくる絵を見てニヤっとしてました。