Hlavní navigace

Fraktály v počítačové grafice VI

30. 11. 2005
Doba čtení: 9 minut

Sdílet

V šestém pokračování seriálu o fraktálech používaných v počítačové grafice si popíšeme nelineární dynamické systémy, u nichž se zobrazuje jejich "orbit" v dvojrozměrném či třírozměrném prostoru. Toto pokračování již bude zaměřené více prakticky, protože bude uvedeno množství algoritmů pro vykreslování orbitů spolu s jejich praktickou implementací v demonstračních příkladech.

Obsah

1. Princip vykreslování orbitu 2D a 3D dynamických systémů
2. Lorenzův atraktor
3. Hénonův atraktor
4. Dynamický systém nazvaný Martin
5. Dynamický systém nazvaný Gingerbreadman
6. Dynamický systém nazvaný Hopalong
7. Dynamický systém nazvaný Chip
8. Dynamický systém nazvaný Quadruptwo
9. Obsah dalšího pokračování tohoto seriálu

1. Princip vykreslování orbitu 2D a 3D dynamických systémů

V předchozí části tohoto seriálu jsme si ukázali, jakým způsobem je možné vizualizovat mapy jednodimenzio­nálních nelineárních dynamických systémů. V dnešní části se zaměříme na (z pohledu grafiky) zajímavější oblast vícedimenzionálních dynamických systémů. Pro vybranou skupinu dynamických systémů s podivnými atraktory je pro účely počítačové grafiky vhodné zobrazovat jejich orbit, což není ve své podstatě nic jiného, než obraz stavového prostoru systému v dvojdimenzi­onálním nebo třídimenzionálním prostoru. Jak uvidíme v dalších pokračováních tohoto seriálu, existují také systémy (a není jich málo), pro které je z hlediska grafiky výhodnější vizualizovat jejich mapu, například počet iterací nutných pro splnění nějaké podmínky – dnes se však budeme zabývat pouze zobrazováním orbitů. Při vykreslování dvojdimenzionálního orbitu (tj. orbitu zobrazeného v rovině) je použit velmi jednoduchý algoritmus, který lze neformálně popsat následujícím způsobem:

Algoritmus vykreslení orbitu 2D dynamického systému

Zjisti počáteční hodnoty systému x0, y0
Zjisti počet iterací
Zjisti hodnoty všech parametrů p0..pn
for (n=0 to počet_iterací) do
    xn+1=f1(xn, yn, zn, p0...pn)
    yn+1=f2(xn, yn, zn, p0...pn)
    vykresli_bod(xn+1, yn+1) do plochy
done 

Vykreslení třírozměrného orbitu v prostoru je stejně snadné jako v ploše, pouze zde musí dojít k transformaci vypočteného bodu do pohledové roviny. Tento přepočet je možné buď naprogramovat přímo v aplikaci vykreslující fraktály, nebo se mohou použít prostředky grafických knihoven – v OpenGL se jedná o aplikaci transformací popsaných transformačními maticemi.

Algoritmus vykreslení 3D dynamického systému

Zjisti počáteční hodnoty systému x0,y0,z0

Zjisti počet iterací
Zjisti hodnoty všech parametrů p0..pn
for (n=0 to počet_iterací) do
    xn+1=f1(xn, yn, zn, p0...pn)
    yn+1=f2(xn, yn, zn, p0...pn)
    zn+1=f3(xn, yn, zn, p0...pn)
    transformuj_bod(xn+1, yn+1, zn+1) do pohledové roviny
    vykresli_transformovaný_bod
done 

V dalších kapitolách budou uvedeny praktické příklady ukazující vykreslování 2D systémů (resp. jejich orbitů).

2. Lorenzův atraktor

Lorenzův atraktor zaujímá mezi zde popisovanými dynamickými systémy zvláštní postavení, protože se historicky jedná o první podrobně zkoumaný a popsaný dynamický systém s podivným atraktorem. Tento systém byl objeven Edwardem Nortonem Lorenzem v roce 1963 při studiu modelů vhodných pro simulaci počasí. Výpočty již v té době probíhaly na počítači, nejprve na analogových strojích, posléze na běžných mainframech. Vzhledem k tomu, že výpočty běžely velmi pomalu, použil Lorenz značně zjednodušený model, který sestával pouze z trojice diferenciálních rovnic. U tohoto modelu si však všiml zajímavé vlastnosti, kterou později pojmenoval „citlivost na počáteční podmínky“ – systém se i při nepatrné změně původních podmínek začal chovat diametrálně odlišně. Také obraz orbitu byl velmi zajímavý – dráha byla neperiodická, docházelo pouze k protínání drah, nikoli k jejich splynutí. Výpočet Lorenzova atraktoru vychází ze soustavy tří diferenciálních rovnic:

dx/dt=-ax+ay
dy/dt=bx-y-zx
dz/dt=-cz+xy

Tyto rovnice lze pro účely programového zpracování upravit do diskrétní podoby:

xn+1=xn+(-a × xn × dt)+(a × yn × dt)

yn+1=yn+(b × xn × dt)-(yn × dt)-(zn × xn × dt)

zn+1=zn+(-c × zn × dt)+(xn × yn × dt)

Vhodné počáteční podmínky pro vykreslení Lorenzova atraktoru jsou:

  • dt=0.02
  • a=5.0
  • b=15.0
  • c=1.0

3. Hénonův atraktor

Hénonův atraktor patří mezi jeden z nejjednodušších 2D dynamických systémů s podivným atraktorem. Rovnice použité u tohoto atraktoru odvodil Michel Hénon při studiu pohybu astronomických objektů (vycházel přitom z diferenciálních rovnic pro pohyb těchto objektů). Výsledné vztahy jsou velmi jednoduché:

xn+1=1+yn-axn2
yn+1=bxn 

Výsledkem je však komplikovaný (i když poněkud nudný) tvar, jehož Hausdorffova dimenze má hodnotu přibližně 1,261. Procedura pro vytvoření obrazu orbitu tohoto dynamického systému vypadá následovně:

void
fractal_henon (     double startx,      /* počáteční podmínky */
                    double starty,      /* pro iteraci */
                    double a,           /* parametry fraktálu */
                    double b,
                    int maxiter,        /* maximální počet iterací */
                    double scale,       /* měřítko pro vykreslení */
                    double pan)         /* posun na obrazovce */
{
    double           x = startx;        /* počáteční podmínka */
    double           y = starty;
    double           x2;
    int              iter = maxiter;    /* čítač iterací */

    while (iter--) {                    /* iterační smyčka */
        x2 = x;
        x = 1.0 + y - a * x * x;
        y = b * x2;
        putpixel (x * scale + pan, y * scale + pan, iter);
    }
} 

Příklad volání procedury s vhodnými parametry: fractal_henon (0.0, 0.0, 1.4, 0.3, 30000, 50, 60);

Výše uvedená procedura je po mírné modifikaci použita i v prvním demonstračním příkladu (HTML verze se zvýrazněním syntaxe). Po spuštění tohoto příkladu se zobrazí základní pohled na Hénonův atraktor. Pomocí kurzorových kláves lze obrázkem v rámci okna aplikace posouvat, klávesy [PageUp] a [PageDown] slouží ke změně měřítka, klávesami [,] a [.] (popřípadě i se stlačeným Shiftem) se mění počet iterací a konečně pomocí kláves

[h] [j] [k] [l] a [1] [2] [3] [4] se mění počáteční podmínky a parametry systému. Aplikaci lze ukončit klávesou Esc nebo

Q, stiskem klávesy S se vytvoří soubor s uloženým rastrovým obrázkem (pixmapou).
Fraktály 06 - 1

Obrázek 1: Hénonův atraktor

4. Dynamický systém nazvaný Martin

Vzorec pro tento dynamický systém zveřejnil A. K. Dewdney v časopisu Computer Recreation. Dva velmi jednoduché vztahy vedou k vykreslení zajímavé mozaiky. Nejzajímavější obrazce je možné získat v případě, že parametr a je nastaven na hodnotu blízkou číslu π (předpokladem ovšem je, že goniometrické funkce mají hodnotu své nezávislé proměnné reprezentované v radiánech a ne ve stupních – to je však v C-čkovských knihovnách splněno). Zmiňované vztahy použité v iteračním výpočtu mají tvar:

xn+1=yn-sin xn
yn+1=a-xn

void
fractal_martin(   double startx,        /* počáteční podmínky */
                  double starty,        /* pro iteraci */
                  double a,             /* parametr fraktálu */
                  int    maxiter,       /* maximální počet iterací */
                  double scale,         /* měřítko pro vykreslení */
                  double panx,          /* posun na obrazovce */
                  double pany)
{
    double x=startx;                    /* nastavit počáteční podmínky */
    double y=starty;
    double x2;                          /* pomocná proměnná */
    int    iter=maxiter;                /* čítač iterací */

    while (iter--) {                    /* iterační smyčka */
        x2 = x;
        x = y - sin(x);
        y = a - x2;
        putpixel(x * scale + panx, y * scale + pany, iter);
    }
} 

Zdrojový kód demonstračního příkladu s tímto dynamickým systémem je uložen ke stažení, popř. je k dispozici i verze se zvýrazněním syntaxe.

Fraktály 06 - 2

Obrázek 2: Dynamický systém Martin

5. Dynamický systém nazvaný Gingerbreadman

Dalším dvourozměrným dynamickým systémem je systém nazvaný Gingerbreadman (pojmenování pochází ze známého programu Fractint). Rovnice pro iterační výpočet jsou zde velmi jednoduché:

xn+1=1-yn+|xn|
yn+1=xn

Jedinými parametry, které je možné u tohoto systému měnit, jsou počáteční podmínky x0 a y0. Procedura pro vykreslení má tvar:

void
fractal_ginger (    double startx,      /* počáteční podmínky */
                    double starty,      /* pro iteraci */
                    int maxiter,        /* maximální počet iterací */
                    double scale,       /* měřítko pro vykreslení */
                    double panx,
                    double pany)        /* posun na obrazovce */
{
    double          x = startx;         /* počáteční podmínky */
    double          y = starty;
    double          x2;                 /* pomocná proměnná */
    int             iter = maxiter;     /* čítač iterací */

    while (iter--) {                    /* iterační smyčka */
        x2 = x;
        x = 1.0 - y + fabs (x);
        y = x2;
        putpixel (x * scale + panx, y * scale + pany, iter);
    }
} 

Příklad volání této procedury s vhodnými parametry: fractal_ginger(-0.1, 0.0, 30000, 30, 60);

Zdrojový kód demonstračního příkladu ukazujícího práci s dynamickým systémem Gingerbreadman je k dispozici pro stažení, popř. si můžete prohlédnout verzi se zvýrazněním syntaxe.

Fraktály 06 - 3

Obrázek 3: Dynamický systém Gingerbreadman

6. Dynamický systém nazvaný Hopalong

Tento typ dynamického systému s podivným atraktorem, který poprvé prezentoval A. K. Dewdney v časopisu Computer Recreations, vytváří při vykreslování na obrazovce počítače velmi pěkné obrazce. Výpočet je v jednotlivých iteracích řízen aktuální hodnotou proměnné x. Pokud je tato hodnota větší než nula, provede se odlišný výpočet než v případě, že je aktuální hodnota x menší než nula nebo rovna nule. Ovlivnění výpočtu je možné provést jak změnou počátečních podmínek (startx, starty), tak i nastavením tří parametrů a,b a c. Procedura pro výpočet tohoto dynamického systému je velmi podobná předchozím fragmentům programového kódu:

void
fractal_hopalong (  double startx,      /* počáteční podmínky */
                    double starty,      /* pro iteraci */
                    double a,
                    double b,           /* parametry fraktálu */
                    double c,
                    int    maxiter,     /* maximální počet iterací */
                    double scale,       /* měřítko pro vykreslení */
                    double panx,
                    double pany)        /* posun na obrazovce */
{
    double           x = startx;        /* počáteční podmínky */
    double           y = starty;
    double           x2;                /* pomocná proměnná */
    int              iter = maxiter;    /* čítač iterací */

    while (iter--) {                    /* iterační smyčka */
        x2 = x;
        if (x > 0)                      /* větvení výpočtu */
            x = y - sqrt (fabs (b * x - c));
        else
            x = y + sqrt (fabs (b * x - c));
        y = a - x2;
        putpixel (x * scale + pan, y * scale + pan, iter);
    }
} 

Vhodné vstupní parametry procedury: fractal_hopalon­g(0.0, 0.0, 0.4, 1.0, 0.0, 50000.0, 50.0, 160.0);

Poznámka: na starších unixových systémech se vyskytoval program nazvaný xmartin, který mimo jiné vykresloval i tento dynamický systém.

Zdrojový kód demonstračního příkladu s tímto dynamickým systémem je uložen ke stažení, samozřejmě si můžete prohlédnout i verzi se zvýrazněním syntaxe.

Fraktály 06 - 4

Obrázek 4: Dynamický systém Hopalong

Fraktály 06 - 5

Obrázek 5: Dynamický systém Hopalong s odlišnými parametry

7. Dynamický systém nazvaný Chip

Dynamický systém nazvaný Chip vytvořil Michael Peters, který tento systém také použil ve svém programu HOP. Proceduru pro vykreslení orbitu tohoto systému je možné v C-čku zapsat následovně:

void
fractal_chip ( double startx,           /* počáteční podmínky */
               double starty,           /* pro iteraci */
               double a, double b, double c,
               int    maxiter,          /* maximální počet iterací */
               double scale,            /* měřítko obrazce */
               double panx,             /* posun obrazce */
               double pany)
{
    double x=startx;                    /* nastavit počáteční podmínky */
    double y=starty;
    double x2;                          /* pomocná proměnná */
    int    iter=maxiter;                /* čítač iterací */
    scale*=0.01;

    while (iter--) {                    /* iterační smyčka */
        x2=x;
        x=y-sgn(x)*cos(sqr(log(fabs(b*x-c))))*atan(sqr(log(fabs(c*x-b))));
        y=a-x2;
        putpixel(x*scale+panx, y*scale+pany, iter/50, iter/20, iter/30);
    }
} 

kde a, b, c jsou parametry, které ovlivňují vzhled fraktálu.

Zdrojový kód demonstračního příkladu s tímto dynamickým systémem je uložen ke stažení, popř. je k dispozici i verze se zvýrazněním syntaxe.

Fraktály 06 - 6

Obrázek 6: Dynamický systém Chip

8. Dynamický systém nazvaný Quadruptwo

Autorem tohoto systému je, podobně jako v předchozím případě, Michael Peters. Výpočet je velmi podobný, jako ve výše uvedeném příkladu, pouze se změní volání funkce cos() za sin(). Na první pohled malá změna však způsobí generování zcela jiných obrazců:

void
fractal_quad ( double startx,           /* počáteční podmínky */
               double starty,           /* pro iteraci */
               double a, double b, double c,
               int    maxiter,          /* maximální počet iterací */
               double scale,            /* měřítko obrazce */
               double panx,             /* posun obrazce */
               double pany)
{
    double x=startx;                    /* nastavit počáteční podmínky */
    double y=starty;
    double x2;                          /* pomocná proměnná */
    int    iter=maxiter;                /* čítač iterací */
    scale*=0.01;

    while (iter--) {                    /* iterační smyčka */
        x2=x;
        x=y-sgn(x)*sin(log(fabs(b*x-c)))*atan(sqr(log(fabs(c*x-b))));
        y=a-x2;
        putpixel(x*scale+panx, y*scale+pany, iter/50, iter/20, iter/30);
    }
} 

Zdrojový kód demonstračního příkladu s tímto dynamickým systémem je uložen ke stažení, popř. je k dispozici i verze se zvýrazněním syntaxe.

Fraktály 06 - 7

Obrázek 7: Dynamický systém Quadruptwo

Fraktály 06 - 8

Obrázek 8: Dynamický systém Quadruptwo s odlišnými parametry

CS24_early

9. Obsah dalšího pokračování tohoto seriálu

I v dalším pokračování tohoto seriálu budou popsány dynamické systémy, u nichž se zobrazují orbity. Tentokrát se však bude jednat o systémy vytvářející trojrozměrné obrazce.

ikonka

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.

Byl pro vás článek přínosný?

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.