Hlavní navigace

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

8. 2. 2006
Doba čtení: 10 minut

Sdílet

V dnešním pokračování seriálu o fraktálech používaných (nejenom) v počítačové grafice se budeme zabývat způsobem animace "průletu" Mandelbrotovou množinou a také takzvanou mapou Mandelbrotovy množiny spolu s názvy nejtypičtějších tvarů (oblastí), které je možné v této nekonečně členité množině nalézt.

Obsah

1. Animace průletu Mandelbrotovou množinou
2. Poznámka k formátu vytvořených animací
3. Zajímavé oblasti, které lze nalézt v Mandelbrotově množině
4. Oblast nazývaná ‚Elephant valley‘
5. Oblast nazývaná ‚Seahorse valley‘
6. Oblast nazývaná ‚West seahorse valley‘
7. Oblast nazývaná ‚Triple spiral valley‘
8. Oblast nazývaná ‚Quad spiral valley‘
9. Obsah dalšího pokračování tohoto seriálu

1. Animace průletu Mandelbrotovou množinou

V předcházejících částech tohoto seriálu jsme si uvedli poměrně velké množství programů, které sloužily k vykreslování Mandelbrotovy množiny pomocí různých vykreslovacích technik. Tyto programy je možné jednoduchým způsobem upravit tak, aby se mohla hodnota měřítka (zvětšení) a popřípadě i střed vykreslovaného obrazce kontinuálně měnit v programové smyčce bez nutnosti interaktivního zásahu uživatele. Z matematického pohledu se změní mapování bodů ležících v rovině vykreslované pixmapy a bodů ležících v komplexní rovině.

Tímto způsobem je možné vytvořit působivou animaci „průletu“ Mandelbrotovou množinou. Výsledná animace se vytvoří tak, že se postupně spočítá větší množství obrázků Mandelbrotovy množiny, přičemž každý obrazec bude mít nastavené jiné parametry výpočtu. Je přitom jasné, že čím menší budou rozdíly mezi jednotlivými parametry, tím plynulejší bude výsledná animace. Vytvořené rastrové obrázky se následně seřadí do sekvence a vytvoří se z nich animace, tj. postupný přechod mezi obrázky. Animaci lze uložit například ve formátu FLI (postarší, ale stále ještě k tomuto účelu používaný formát pro uložení animací obsahujících v každém obrázku pouze 256 barev), Video for Windows (AVI), MPEG (Motion Picture Experts Group) apod.

Tento způsob vytváření animací je použit i v dnešním prvním (a jediném) demonstračním příkladu. K dispozici je jak zdrojový tvar programu, tak i HTML verze se zvýrazněnou syntaxí. Tento program ve skutečnosti vytvoří sadu rastrových obrázků, kterou je nutné pomocí dalších programových nástrojů spojit do výsledné animace. Ovládání programu je jednoduché, všechny parametry se zadávají z příkazové řádky. Program při svém zavolání očekává šestici argumentů s následujícím významem:

  1. První argument: maximální počet iterací použitý při výpočtu obrazu Mandelbrotovy množiny. Hodnotou tohoto argumentu by mělo být celé kladné číslo.
  2. Druhý argument: index barvové palety, který by měl ležet v rozsahu (intervalu) 0–9, protože v programu je vytvořeno pouze deset barvových palet.
  3. Třetí argument: hodnota reálné složky středu obrázku v komplexní rovině, tato hodnota by měla ležet v rozmezí –2,0..2,0.
  4. Čtvrtý argument: hodnota imaginární složky středu obrázku v komplexní rovině, i tato hodnota by měla ležet v intervalu –2,0..2,0.
  5. Pátý argument: faktor zvětšení udávající nepřímo (spolu s celkovým počtem obrázků zadaným v šestém argumentu) zvětšení posledního obrázku, tzv. „zoom“. Čím více se bude blížit hodnota tohoto faktoru k jedničce, tím menší budou změny mezi jednotlivými snímky v animaci.
  6. Šestý argument: celkový počet vygenerovaných obrázků, hodnotou musí být celé kladné číslo.

Parametry pro tvorbu jednotlivých obrázků jsou nastaveny tak, že mapování prvního obrazu do komplexní roviny vytvoří osově orientovaný obdélník o délce stran 4,0 a 3,0 se středem v bodě specifikovaném uživatelem. Ve druhém obrázku animace je obdélník proporcionálně zmenšen a zmenšování probíhá tak dlouho, aby se u posledního obrázku dosáhlo zadané hodnoty zoom. Prvních dvacet obrázků je však vytvořeno odlišným způsobem. Je proveden postupný posuv původního pohledu na Mandelbrotovu množinu tak, aby střed dvacátého snímku odpovídal středu specifikovanému třetím a čtvrtým argumentem programu. Posléze následuje pět stejných snímků, které vytvoří krátkou pauzu a teprve poté se započne se „zoomováním“.

Procedura, která celou animaci řídí, vypadá následovně:

    // vytvoření a prvotní smazání pixmapy
    pix=createPixmap(PIXMAP_WIDTH, PIXMAP_HEIGHT);
    clearPixmap(pix);

    // prvních dvacet snímků s posunem na zadaný střed obrazu (oblasti)
    for (i=0; i<20; i++) {
        double t1=(double)i/20.0;
        double t2=1.0-t1;
        sprintf(name, "%s%03d%s", FILE_NAME, i, ".tga");
        printf("%3d\t", i);
        recalcMandelbrot(pix, maxiter, 1.0, x0*t2+x1*t1, y0*t2+y1*t1, palette);
        savePixmap(pix, name);
    }

    // pět statických snímků - krátké pozastavení animace
    for (i=20; i<25; i++) {
        sprintf(name, "%s%03d%s", FILE_NAME, i, ".tga");
        printf("%3d\t", i);
        savePixmap(pix, name);
    }

    // zoomování k vybrané oblasti
    for (i=0; i<frames; i++) {
        sprintf(name, "%s%03d%s", FILE_NAME, i+25, ".tga");
        printf("%3d\t", i+25);
        recalcMandelbrot(pix, maxiter, scale, x1, y1, palette);
        scale*=factor;
        savePixmap(pix, name);
    } 

Funkce, která provádí překreslení Mandelbrotovy množiny, má následující programový kód:

//-----------------------------------------------------------------------------
// Překreslení Mandelbrotovy množiny a aplikace vybrané barvové palety
//-----------------------------------------------------------------------------
void recalcMandelbrot( pixmap *pix,             // pixmapa určená pro vykreslování
                       int    maxiter,          // maximální počet iterací
                       double scale,            // měřítko obrazce
                       double xpos,             // posun obrazce
                       double ypos,
                       int    palette)          // barvová paleta
{
    double zx, zy, zx2, zy2;                    // složky komplexní proměnné Z a Z^2
    double cx, cy;                              // složky komplexní konstanty C
    double cx0, cy0;
    double xmin, ymin, xmax, ymax;              // rohy vykreslovaného obrazce v komplexní
                                                // rovině
    int    x, y;                                // počitadla sloupců a řádků v pixmapě
    int    iter;                                // počitadlo iterací
    unsigned char r, g, b;

    calcCorner(xpos, ypos, scale, &xmin, &ymin, &xmax, &ymax);
    cy0=ymin;
    for (y=0; y<pix->height; y++) {             // pro všechny řádky v pixmapě
        cx0=xmin;
        for (x=0; x<pix->width; x++) {          // pro všechny pixely na řádku
            cx=cx0;                             // nastavit počáteční hodnotu Z(0)
            cy=cy0;
            zx=zy=0.0;                          // nastavení nulového orbitu
            for (iter=0; iter<maxiter; iter++) {// iterační smyčka
                zx2=zx*zx;                      // zkrácený výpočet druhé mocniny složek Z
                zy2=zy*zy;
                if (zx2+zy2>4.0) break;         // kontrola překročení meze divergence
                zy=2.0*zx*zy+cy;                // výpočet Z(n+1)
                zx=zx2-zy2+cx;
            }
            if (iter==maxiter)                  // pixely uvnitř Mandelbrotovy
                r=g=b=0;                        // množiny jsou černé
            else                                // výpočet barev podle počtu iterací
                mapPalette(palette, iter, &r, &g, &b);
            putpixel(pix, x, y, r, g, b);
            cx0+=(xmax-xmin)/pix->width;        // posun na další bod na obrazovém řádku
        }
        cy0+=(ymax-ymin)/pix->height;           // posun na další obrazový řádek
    }
} 

Z funkce recalcMandelbrot() se volá další pomocná funkce, jež provádí výpočet krajních bodů v komplexní rovině. Tento výpočet obstarává funkce calcCorner(), která má následující kód:

//-----------------------------------------------------------------------------
// Funkce určená pro výpočet pozice rohu vykreslovaného obrázku ze zadaného
// středu obrázku a měřítka (zvětšení)
//-----------------------------------------------------------------------------
void calcCorner(double xpos, double ypos, double scale,
                double *xmin,  double *ymin,  double *xmax, double *ymax)
{
    *xmin=xpos-WIDTH*scale;
    *ymin=ypos-HEIGHT*scale;
    *xmax=xpos+WIDTH*scale;
    *ymax=ypos+HEIGHT*scale;
} 

Ve výše uvedené funkci jsou použity dvě symbolické konstanty WIDTH a HEIGHT, ve kterých je uložena šířka a výška výsledného rastrového obrázku (obě hodnoty jsou samozřejmě reprezentovány v pixelech).

2. Poznámka k formátu vytvořených animací

Dnešní demonstrační příklad popsaný v první kapitole slouží k vytváření rastrových obrázků uložených ve formátu TGA (Targa). Sekvence obrázků tvořících průlet Mandelbrotovou množinou je převedena na animaci (video) fyzicky uloženou v jednom souboru. Soubory s vytvořenou animací jsou zakódovány ve formátu odpovídajícímu standardu MPEG-1. Pro co největší kompatibilitu s různými softwarovými i hardwarovými přehrávači bylo zvoleno rozlišení 352×288 pixelů, přičemž je zobrazováno 25 snímků za sekundu. To odpovídá jak televiznímu standardu PAL (ve skutečnosti jde o poloviční rozlišení televizního snímku bez prokládání), tak i minimálním parametrům, které podle standardu musí splňovat každý přehrávač odpovídající MPEG-1 – jedná se o takzvaný Constrained Parameters Bitstreams (CPB), který je mnohdy (mylně) zaměňován s parametry samotného standardu MPEG-1. To však není pravda, protože animace či videa uložená ve formátu MPEG-1 mohou mít mnohem větší rozlišení než zmíněných 352×288 pixelů a i snímková frekvence může být odlišná.

3. Zajímavé oblasti, jež lze nalézt v Mandelbrotově množině

V Mandelbrotově množině se nachází velké množství zajímavých oblastí, přičemž zobrazované tvary jsou sobě podobné, tj. při různém zvětšení se opakují. Některé typické tvary byly podle svého vzhledu dokonce pojmenovány. Popis zajímavých oblastí začneme částí Mandelbrotovy množiny, která se nachází v okolí takzvaného Feigenbaumova bodu. S prací Feigenbauma jsme se setkali již při popisování dynamických systémů a bifurkačních diagramů. Feigenbaumův bod je místo v Mandelbrotově množině, v jehož okolí nastává stejný jev jako v bifurkačním diagramu – prudké zdvojování period vedoucích až k chaosu. Tento bod má v komplexní rovině souřadnice -1,401155+0,0i, leží tedy v záporné části reálné osy. Na prvním obrázku je zobrazena Mandelbrotova množina zvětšená do oblasti se středem ve Feigenbaumově bodu. Animace, která zobrazuje průlet Mandelbrotovou množinou k tomuto bodu, je uložena zde.

Zdrojové obrázky k vytvořené animaci byly získány s těmito parametry (předpokladem je, že spustitelný soubor dnešního demonstračního příkladu má název buď fractals16_1 na Unixových systémech nebo fractals16_1.exe na systémech Microsoft Windows či DOS):

fractals16_1 1024 0 -1.401144 0.0 0.95 200

fractals16_1

Obrázek 1: Mandelbrotova množina v oblasti Feigenbaumova bodu

4. Oblast nazývaná ‚Elephant valley‘

Tato zajímavá oblast Mandelbrotovy množiny byla nazvána Elephant valley proto, že některé tvary zde obsažené připomínaly autorům názvu hlavu slona i se zatočeným chobotem. Oblast se nachází v okolí bodu 0,25+0,0i, tj. na kladné části reálné osy, která při celkovém pohledu na Mandelbrotovu množinu obsahuje vrchol největší (srdcovité) části množiny. Při velkém zvětšení můžeme v Elephant valley nalézt například množství zborcených „kopií“ základního tvaru Mandelbrotovy množiny. Animace zobrazující průlet do okolí Elephant valley je uložena zde, pohled na některé její části zprostředkuje druhý a třetí obrázek.

Zdrojové obrázky k vytvořené animaci byly získány s těmito parametry:

fractals16_1 1024 1 0.257 0.001 0.95 200

fractals16_4

Obrázek 2: Mandelbrotova množina v okolí oblasti nazvané ‚Elephant valley‘

fractals16_5

Obrázek 3: Mandelbrotova množina v okolí oblasti nazvané ‚Elephant valley‘

5. Oblast nazývaná ‚Seahorse valley‘

Další zajímavá oblast Mandelbrotovy množiny je nazvaná Seahorse valley. Pojmenování vzniklo tak, že při větším přiblížení (zoomu) mohou tvary viditelné v této oblasti připomínat tělo mořského koníka. Oblast se nachází v okolí bodu -0,75+0,0i, tj. v místě, ve kterém se spojuje největší (srdcovitá) oblast Mandelbrotovy množiny s kruhovou oblastí umístěnou vlevo. Při velkém přiblížení zde můžeme nalézt zejména na sebe navazující dvouramenné spirály. Animaci zobrazující průlet do okolí Seahorse valley si můžete rovnou prohlédnout, detailnější pohled na některé zajímavé tvary nalezené uvnitř této oblasti je zobrazen na čtvrtém a pátém obrázku.

Zdrojové obrázky k vytvořené animaci byly získány s těmito parametry:

fractals16_1 256 2 -0.748 0.1 0.95 200

fractals16_2

Obrázek 4: Mandelbrotova množina v okolí oblasti nazvané ‚Seahorse valley‘

fractals16_3

Obrázek 5: Mandelbrotova množina v okolí oblasti nazvané ‚Seahorse valley‘

6. Oblast nazývaná ‚West seahorse valley‘

Na „západ“ od Seahorse valley, tj. ve směru záporné části reálné osy, se nachází takzvaná West seahorse valley. Jedná se o oblast nacházející se v okolí bodu -1,26+0,0i. Při celkovém pohledu na Mandelbrotovu množinu zjistíme, že se zde spojují dvě kruhové části Mandelbrotovy množiny. Tvary, které se při větším přiblížení nachází ve West seahorse valley jsou podobné tvarům z předchozí oblasti, ovšem s tím rozdílem, že zde také můžeme nalézt části Mandelbrotovy množiny, které jsou zdánlivě odtržené. Ve skutečnosti to však není pravda, protože je matematicky dokázáno, že Mandelbrotova množina je spojitá. A skutečně, při větším zvětšení zjistíme, že zdánlivě odtržené části jsou se zbytkem množiny propojeny tenkými vlákny. Animace zobrazující průlet do okolí West seahorse valley je opět uložena a můžete si ji rovnou pustit.

Zdrojové obrázky k vytvořené animaci byly získány s těmito parametry:

fractals16_1 512 4 -1.26 0.04 0.95 200

fractals16_6

Obrázek 6: Mandelbrotova množina v okolí oblasti nazvané ‚West seahorse valley‘

fractals16_7

Obrázek 7: Mandelbrotova množina v okolí oblasti nazvané ‚West seahorse valley‘

7. Oblast nazývaná ‚Triple spiral valley‘

Oblast nazvaná výstižně Triple spiral valley se nachází v okolí bodu -0,088+0,655i, tj. v „severní“ části Mandelbrotovy množiny. Zrcadlově symetrická oblast se samozřejmě nachází i v okolí bodu -0,088–0,654i. Jak je již z názvu této oblasti patrné, je zde možné nalézt množství trojramenných spirál, což je zobrazeno v další animacii na osmém a devátém obrázku.

Zdrojové obrázky k vytvořené animaci byly získány s těmito parametry:

fractals16_1 512 5 -0.088 0.6555 0.95 200

fractals16_8

Obrázek 8: Mandelbrotova množina v okolí oblasti nazvané ‚Triple spiral valley‘

fractals16_9

Obrázek 9: Mandelbrotova množina v okolí oblasti nazvané ‚Triple spiral valley‘

8. Oblast nazývaná ‚Quad spiral valley‘

Tato oblast, jež se nachází v blízkém okolí bodu 0,274+0,482i (resp. u zrca­dlového bodu 0,274–0,482i), se při větším přiblížení vyznačuje (nekonečným) množstvím tvarů podobných spirále se čtyřmi rameny. Animaci zobrazující průlet do okolí této oblasti si nenechte ujít, zajímavé obrázky Mandelbrotovy množiny nalezené v okolí bodu 0,274+0,482i jsou zobrazeny na desátém a jedenáctém obrázku.

Zdrojové obrázky k vytvořené animaci byly získány s těmito parametry:

fractals16_1 256 7 0.274 0.486 0.95 200

fractals16_10

Obrázek 10: Mandelbrotova množina v okolí oblasti nazvané ‚Quad spiral valley‘

fractals16_11

Obrázek 11: Mandelbrotova množina v okolí oblasti nazvané ‚Quad spiral valley‘

V Mandelbrotově množině se nachází i další – zde blíže nepopsané – zajímavé oblasti, například Dendrid s bodem 0.0+1.0i apod.

ict ve školství 24

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

V následujícím pokračování tohoto seriálu dokončíme část věnovanou Mandelbrotově množině. Uvedeme si další způsoby modifikace Mandelbrotovy množiny, které mají vliv na její vizuální obraz. Také si řekneme, jakým způsobem souvisí Mandelbrotova množina se známou konstantou π a Fibonnaciho posloupností.

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.

Autor článku

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