Hlavní navigace

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

7. 12. 2005
Doba čtení: 8 minut

Sdílet

V sedmém pokračování seriálu o fraktálech používaných v počítačové grafice budou popsány další dynamické systémy, jejichž orbity tvoří zajímavé obrazce, a to jak v rovině, tak i v prostoru.

Obsah

1. Dynamický systém Kamtorus vytvořený v ploše
2. Dynamický systém Pickover vytvořený v ploše
3. Dynamický systém Latoocarfian vytvořený v ploše
4. Dynamický systém Kamtorus vytvořený v prostoru
5. Dynamický systém Pickover vytvořený v prostoru
6. Obsah dalšího pokračování tohoto seriálu

1. Dynamický systém Kamtorus vytvořený v ploše

předchozím pokračování tohoto seriálu jsme si ukázali princip vykreslování orbitů vybraných dynamických systémů. V dnešní části si popíšeme další zajímavé dynamické systémy, jejichž orbity je možné zobrazovat jak v ploše (rovině), tak i v třírozměrném prostoru. Začneme dynamickým systémem, který je v některých aplikacích určených pro práci s fraktálními objekty i v dokumentaci nazývaný Kamtorus. U tohoto systému se pro výpočet orbitů používá následující soustava vztahů:

xn+1 = xn cos(α) + (xn xn-yn) sin(α)
yn+1 = xn sin(α) – (xn xn-yn) cos(α) 

S počáteční podmínkou:

x0 = orbit/3
y0 = orbit/3
 

kde orbit značí konstantu platnou pro danou část obrazce (pro jeden orbit). U tohoto dynamického systému se nevykresluje pouze jeden orbit, ale celá sada na sobě nezávislých orbitů. Výpočet probíhá vždy podle stejných vztahů a se shodnými parametry, liší se pouze počáteční podmínky, tj. hodnoty, které jsou před prováděním iterační smyčky dosazovány do proměnných x a y. Prakticky to znamená, že celý výpočet obrázku probíhá ve dvou do sebe vložených programových smyčkách. Ve vnější smyčce se mění počáteční hodnoty proměnných x a y, vnitřní smyčka zajišťuje výpočet a následné vykreslení jednoho orbitu. Následuje ukázka C-čkovské procedury pro vykreslení orbitů tohoto dynamického systému v ploše:

//-----------------------------------------------------------------------------
// Překreslení dynamického systému Kamtorus (2D)
//-----------------------------------------------------------------------------
void recalcKamtorus(pixmap *pix,                // pixmapa pro vykreslování
                    double start,               // počáteční a koncová
                    double end,                 // hodnota orbitu
                    double step,                // změna orbitu
                    double alpha,               // úhel pro každou iteraci
                    int    maxiter,             // maximální počet iterací
                    double scale,               // měřítko obrazce
                    double panx,                // posun obrazce
                    double pany)
{
    double x, y, x2;                            // pozice bodu
    double orbit;                               // aktuální hodnota orbitu
    int iter;

    for (orbit=start; orbit<end; orbit+=step) { // smyčka pro orbity
        x = orbit / 3.0;                        // pozice počátečního bodu
        y = orbit / 3.0;
        iter = maxiter;
        while (iter--) {                        // iterační smyčka
            x2= x;
            x = x2*cos(alpha)+(x2*x2-y)*sin(alpha);
            y = x2*sin(alpha)-(x2*x2-y)*cos(alpha);
            putpixel(pix, x*scale+panx, y*scale+pany, iter/5, orbit*255.0/3.0, iter/3);// vykreslení pixelu
        }
    }
} 
Fraktály 07 - 1

Obrázek 1: Dynamický systém Kamtorus

Výše uvedená procedura je použita v prvním demonstračním příkladu (HTML verze se zvýrazněním syntaxe), pomocí nějž jsou také vytvořeny tři obrázky dynamického systému Kamtorus. Hodnoty parametrů jsou zobrazeny přímo na uvedených obrázcích. Po spuštění prvního demonstračního příkladu je možné měnit parametry vykreslovaného systému pomocí několika klávesových zkratek, které jsou vypsány v následující tabulce:

Klávesy použité v prvním demonstračním příkladu
Klávesa Význam
1 zmenšení hodnoty prvního počítaného orbitu (dolní mez vnější programové smyčky)
2 zvětšení hodnoty prvního počítaného orbitu
3 zmenšení hodnoty posledního počítaného orbitu (horní mez vnější programové smyčky)
4 zvětšení hodnoty posledního počítaného orbitu
5 zmenšení kroku vnější programové smyčky – ovlivňuje počet orbitů
6 zvětšení kroku vnější programové smyčky
< snížení počtu iterací pro každý orbit
> zvýšení počtu iterací pro každý orbit
Page Up změna měřítka
Page Down změna měřítka
šipky posun obrázku
S uložení obrázku do externího souboru
Q ukončení tohoto demonstračního příkladu
Esc má stejný význam jako klávesa Q
Fraktály 07 - 2

Obrázek 2: Dynamický systém Kamtorus s odlišnými parametry

Fraktály 07 - 3

Obrázek 3: Další verze dynamického systému Kamtorus

2. Dynamický systém Pickover vytvořený v ploše

Název tohoto dynamického systému je odvozen od příjmení jeho autora, jímž není nikdo jiný než známý fyzik a matematik Clifford Pickover, který mimo dalších publikačních činností vydal i několik knih zabývajících se fraktály a chaosem (například známou knihu „Computers, Pattern, Chaos and Beauty: Graphics from an Unseen World“, St. Martin's Press, New York, 1990). Dynamický systém Pickover je definovaný soustavou tří rovnic:

xn+1=sin ayn-zncos bxn
yn+1=znsin cxn-cos dyn
zn+1=sin xn 

Kde a, b, c a d jsou parametry vstupující do iterační smyčky a x0 a y0 jsou počáteční podmínky. Pro účely zobrazení dynamického systému Pickoverv rovině je možné při vykreslování ignorovat z-ovou souřadnici, tj. hodnotu proměnné zn. Při výpočet však nemůžeme tuto proměnnou ani jí příslušející rovnici zanedbat, protože na její hodnotě závisí i hodnoty dalších dvou proměnných. Procedura pro překreslení tohoto dynamického systému v rovině může vypadat následovně:

//-----------------------------------------------------------------------------
// Překreslení dynamického systému Pickover (2D)
//-----------------------------------------------------------------------------
void recalcPickover(pixmap *pix,                // pixmapa pro vykreslování
                    double a,                   // parametry fraktálu
                    double b,
                    double c,
                    double d,
                    int    maxiter,             // maximální počet iterací
                    double scale,               // měřítko obrazce
                    double panx,                // posun obrazce
                    double pany)
{
    double x=0.0, y=0.0, z=0.0;                 // pozice bodu
    double x2, y2, z2;
    int iter=maxiter;

    while (iter--) {                            // iterační smyčka
        x2=sin(a*y)-z*cos(b*x);
        y2=z*sin(c*x)-cos(d*y);
        z2=sin(x);
        x=x2;
        y=y2;
        z=z2;
        //putpixel(pix, x*scale+panx, y*scale+pany, iter/10, iter/50, iter/80);// vykreslení pixelu
        addluminance(pix, x*scale+panx, y*scale+pany);// vykreslení pixelu
    }
} 
Fraktály 07 - 4

Obrázek 4: Orbity dynamického systému Pickover vykresleného v ploše

Při vykreslování orbitu dynamického systému Pickover je možné na vypočtenou pozici v ploše [x, y] uložit buď barvu odpovídající provedené iteraci (podobně jako u všech předchozích demonstračních příkladů), nebo na této pozici zvýšit intenzitu (světlost) pixelu. Při použití druhé metody (která vlastně zajistí zobrazení hustoty vypočtených bodů) vypadají výsledné orbity lépe, ovšem pouze za předpokladu, že se provede mnohem větší počet opakování iterační smyčky – řádově se jedná o stovky tisíc iterací pro rastrový obrázek o velikosti 512×384 pixelů. S rostoucím rozlišením rastrového obrázku musí narůstat i počet provedených iterací. Na obrázcích 4–6 jsou zobrazeny orbity vykreslené právě touto metodou, přičemž se počet vypočtených bodů pohyboval od devíti set tisíc do jednoho milionu.

Fraktály 07 - 5

Obrázek 5: Další varianta dynamického systému Pickover

Procedura recalcPickover() je využita ve druhém demonstračním příkladu (HTML verze se zvýrazněním syntaxe). Následuje tabulka s výčtem klávesových zkratek, které je možné v tomto demonstračním příkladu použít:

Klávesy použité v prvním demonstračním příkladu
Klávesa Význam
1 zmenšení hodnoty parametru a
2 zvětšení hodnoty parametru a
3 zmenšení hodnoty parametru b
4 zvětšení hodnoty parametru b
5 zmenšení hodnoty parametru c
6 zvětšení hodnoty parametru c
7 zmenšení hodnoty parametru d
8 zvětšení hodnoty parametru d
< snížení počtu iterací
> zvýšení počtu iterací
Page Up změna měřítka
Page Down změna měřítka
šipky posun obrázku
S uložení obrázku do externího souboru
Q ukončení tohoto demonstračního příkladu
Esc má stejný význam jako klávesa Q
Fraktály 07 - 6

Obrázek 6: Třetí varianta dynamického systému Pickover

3. Dynamický systém Latoocarfian vytvořený v ploše

Dynamický systém nazvaný Latoocarfian vznikl zobecněním výše popsaného dynamického systému Pickover. Vztahy, pomocí nichž se vypočítávají body ležící v orbitu, používají obecné funkce f1f4:

xn+1=f1(byn)+­cf2(bxn)
yn+1=f3(axn)+df4(a­yn)

kde a, b, c a d jsou parametry systému a x0, y0 a z0 jsou počáteční podmínky. Za obecné funkce f1f4 je možné teoreticky dosadit jakoukoli matematickou funkci, jejímž definičním oborem jsou reálná čísla. V našem demonstračním příkladu se přidržíme, podobně jako v jiných aplikacích, funkce sin.

//-----------------------------------------------------------------------------
// Překreslení dynamického systému Latoocarfian
//-----------------------------------------------------------------------------
void recalcLatoocarfian(pixmap *pix,            // pixmapa pro vykreslování
                    double a,                   // parametry fraktálu
                    double b,
                    double c,
                    double d,
                    int    maxiter,             // maximální počet iterací
                    double scale,               // měřítko obrazce
                    double panx,                // posun obrazce
                    double pany)
{
    double x=0.1, y=0.1;                        // pozice bodu
    double x2, y2;
    int iter=maxiter;

    while (iter--) {                            // iterační smyčka
        x2=sin(b*y)+c*sin(x*b);
        y2=sin(a*x)+d*sin(y*a);
        x=x2;
        y=y2;
        //putpixel(pix, x*scale+panx, y*scale+pany, iter/10, iter/50, iter/80);// vykreslení pixelu
        addluminance(pix, x*scale+panx, y*scale+pany);// vykreslení pixelu
    }
} 
Fraktály 07 - 7

Obrázek 7: Orbity dynamického systému Latoocarfian

Při vykreslování orbitů tohoto dynamického systému můžeme s výhodou použít stejné metody, jako v případě dynamického systému Pickover – místo neustálého překreslování již jednou vybarvených pixelů se zvýší jejich intenzita. Zdrojový kód demonstračního příkladu ukazujícího práci s dynamickým systémem Latoocarfian je uložený ke stažení, samozřejmě i s verzí vhodnou pro zobrazení v prohlížeči. Ovládání demonstračního příkladu je shodné s příkladem předchozím, tabulku klávesových zkratek tedy není nutné uvádět.

Fraktály 07 - 8

Obrázek 8: Druhá varianta dynamického systému Latoocarfian

Fraktály 07 - 9

Obrázek 9: Třetí varianta dynamického systému Latoocarfian

4. Dynamický systém Kamtorus vytvořený v prostoru

Dynamický systém Kamtorus popsaný v první kapitole je možné jednoduše rozšířit do třírozměrného prostoru tak, že se hodnota orbitu považuje za třetí souřadnici. Procedura pro vykreslení takto upravené verze může vypadat následovně:

//-----------------------------------------------------------------------------
// Překreslení dynamického systému Kamtorus v prostoru
//-----------------------------------------------------------------------------
void recalcKamtorus3D(double start,             // počáteční a koncová
                      double end,               // hodnota orbitu
                      double step,              // změna orbitu
                      double alpha,             // úhel pro každou iteraci
                      int    maxiter,           // maximální počet iterací
                      double scale)             // měřítko obrazce
{
    double x, y, x2;                            // pozice bodu
    double orbit;                               // aktuální hodnota orbitu
    int iter;

    glColor3f(1.0f, 1.0f, 1.0f);
    glBegin(GL_POINTS);
    for (orbit=start; orbit<end; orbit+=step) { // smyčka pro orbity
        x = orbit / 3.0;                        // pozice počátečního bodu
        y = orbit / 3.0;
        iter = maxiter;
        while (iter--) {                        // iterační smyčka
            x2= x;
            x = x2*cos(alpha)+(x2*x2-y)*sin(alpha);
            y = x2*sin(alpha)-(x2*x2-y)*cos(alpha);
            glVertex3d(x*scale, y*scale, orbit*3.0-2.6);
        }
    }
    glEnd();
} 

Zdrojový kód pro vykreslení 3D verze dynamického systému Kamtorus je uložený ke stažení (popř. jeho verze pro zobrazení v prohlížeči).

Fraktály 07 - 10

Obrázek 10: Dynamický systém Kamtorus v prostoru

5. Dynamický systém Pickover vytvořený v prostoru

Také dynamický systému Pickover (viz druhá kapitola) je možné vykreslit v prostoru. Jediným rozdílem oproti 2D verzi je odlišný způsob vykreslování bodů. Zatímco v ploše bylo možné postupně zvyšovat intenzity jednotlivých pixelů (uložených v pixmapě), v 3D verzi je místo toho využit blending OpenGL:

//-----------------------------------------------------------------------------
// Překreslení dynamického systému Pickover v prostoru
//-----------------------------------------------------------------------------
void recalcPickover3D(double a,                 // parametry fraktálu
                      double b,
                      double c,
                      double d,
                      int    maxiter,           // maximální počet iterací
                      double scale)             // měřítko obrazce
{
    double x=0.0, y=0.0, z=0.0;                 // pozice bodu v prostoru
    double x2, y2, z2;
    int iter=maxiter;

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glColor4f(1.0f, 1.0f, 1.0f, 0.1f);
    glBegin(GL_POINTS);
    while (iter--) {                            // iterační smyčka
        glColor4f(x,y,z,0.1f);
        x2=sin(a*y)-z*cos(b*x);
        y2=z*sin(c*x)-cos(d*y);
        z2=sin(x);
        x=x2;
        y=y2;
        z=z2;
        glVertex3d(x*scale, y*scale, z*scale);
    }
    glEnd();
    glDisable(GL_BLEND);
} 

Zdrojový kód pro vykreslení 3D verze dynamického systému Pickover je uložený ke stažení (popř. je k dispozici i jeho verze pro zobrazení v prohlížeči).

Fraktály 07 - 11

Obrázek 11: Dynamický systém Pickover v prostoru

Fraktály 07 - 12

Obrázek 12: Další verze dynamického systému Pickover"

root_podpora

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

V dalším pokračování dokončíme část věnovanou zobrazování orbitů dynamických systémů – popíšeme si tvorbu zajímavých obrazců pomocí zobecněného dynamického systému nazývaného Dynamic, vykreslení známého Lorenzova atraktoru a také zobrazení orbitů Mandelbrotovy množiny (tzv. Mandelbrotovo mračno).

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.