Hlavní navigace

Animace čtyřrozměrných kvaternionových fraktálů v POV-Rayi

30. 1. 2007
Doba čtení: 10 minut

Sdílet

V dnešním článku si ukážeme, jakým způsobem je možné tvořit zajímavě vypadající animace čtyřrozměrných fraktálů ve známém raytraceru POV-Ray. Zaměříme se zejména na tvorbu animací vznikajících změnou iterační konstanty c, posunem ořezávacího trojrozměrného podprostoru a průběžnou změnou tohoto podprostoru.

Obsah

1. Animace pomocí změny kvaternionové konstanty c
2. První demonstrační animace – „rotace“ konstanty c
3. Druhá demonstrační animace – odlišná „rotace“ konstanty c
4. Třetí demonstrační animace – pohyb konstanty c po spirále
5. Průběžná rotace ořezávacího trojrozměrného podprostoru
6. Obsah dalšího pokračování tohoto seriálu

1. Animace pomocí změny kvaternionové konstanty c

Celá dnešní část seriálu o fraktálech používaných pro vykreslování 2D obrazů i modelování trojrozměrných objektů je zaměřena na vysvětlení možností animací trojrozměrných řezů původně čtyřrozměrných Juliových množin vykreslovaných známým raytracerem POV-Ray (http://www.po­vray.org). V předchozí části tohoto seriálu jsme si ukázali velmi jednoduchou animaci čtyřrozměrné Juliovy množiny, která spočívala v průběžné změně jedné souřadnice kvaternionové konstanty c, která je použita v iterační funkci z=z2+c (v tomto vztahu jsou z i c kvaterniony, klasická Juliova množina je definována v oboru komplexních čísel). Výsledná animace však byla poměrně nezajímavá, a to z toho důvodu, že změna pouze jedné souřadnice konstanty c se projevila změnou tvaru fraktálního objektu především v jednom směru bez většího vlivu na jeho celkový tvar.

Z tohoto důvodu si dnes ukážeme animace vytvářené poněkud složitějším způsobem, které jsou však působivější. První tři demonstrační animace vznikly změnou všech čtyř souřadnic kvaternionové konstanty c. Vzhledem k tomu, že možnosti POV-Raye jsou při tvorbě animací poněkud omezené – existuje pouze jedna proměnná clock, kterou je možné vhodným nastavením konfiguračních souborů průběžně měnit – musíme všechny čtyři souřadnice konstanty c odvodit z aktuální hodnoty této konstanty. Můžeme přitom využít toho, že POV-Ray kromě přímočarého nahrazení jednotlivých souřadnic konstanty c hodnotou proměnné clock podporuje i zápis složitějších výrazů, včetně základních matematických operandů a goniometrických funkcí. Právě tuto funkcionalitu POV-Raye použijeme při tvorbě následující trojice animací, které jsou popsány ve druhé, třetí a čtvrté kapitole.

2. První demonstrační animace – „rotace“ konstanty c

V prvních dvou ukázkových animacích se provádí „rotace“ kvaternionové konstanty c okolo bodu [0, 0, 0, 0], tj. počátku souřadné soustavy čtyřrozměrného prostoru. Výpočet rotace je zajištěn pomocí goniometrických funkcí sin() a cos(), které jsou do interpreteru POV-Raye zabudovány. Kvaterniony jsou sice většinou zapisovány ve formátu q=x+yi+zj+wk, ale můžeme si je také představit jako čtyřrozměrné vektory q=[x, y, z, w]. Pokud tedy mluvím o rotaci konstanty c, mám tím na mysli rotaci vektoru [x, y, z, w], kde jednotlivé složky tohoto vektoru odpovídají hodnotám složek konstanty c. Při zápisu parametrů čtyřrozměrné Juliovy množiny v souboru popisujícím vykreslovanou scénu je při specifikaci konstanty c použita následující konstrukce:

    < amp*sin(s1*clock*6.28),
      amp*sin(s2*clock*6.28),
      amp*sin(s3*clock*6.28),
      amp*sin(s4*clock*6.28)> 

Místo symbolů amp a s1, s2, s3 a s4 jsou v obou demonstračních animacích použity číselné hodnoty; například se místo amp zapíše hodnota 0.9.

V první demonstrační animaci se kvaternionová konstanta c při výpočtu jednotlivých snímků pohybuje po povrchu čtyřrozměrné koule o poloměru rovném 0,8 jednotek, přičemž střed koule odpovídá počátku souřadné soustavy. Pro změnu jednotlivých souřadnic konstanty c jsou použity obě výše zmíněné goniometrické funkce, dvě souřadnice se v průběhu animace mění s jednotkovou periodou, další souřadnice se dvěma periodami a poslední (čtvrtá) souřadnice dokonce se třemi periodami. Použitá konstanta 6,28 zhruba odpovídá hodnotě 2×π, zápis na více desetinných míst není nezbytný. Vedlejším efektem použití goniometrických funkcí je, že se animace periodicky opakuje, tj. po posledním snímku navazuje snímek první. Zdrojový soubor s popisem scény použité pro první demonstrační animaci má následující obsah:

// Ukázka jednoduché animace trojrozměrného řezu
// původně čtyřrozměrnou Juliovou množinou.
//
// Animace je prováděna změnou kvaternionové
// konstanty C.

// specifikace verze POV-Raye
#version 3.0

// globální nastavení scény
global_settings {
    assumed_gamma 2.2
}

#include "colors.inc"

// nastavení pozice kamery a směru pohledu
camera {
    location <20, 20, -10>
    look_at  <0, -5, 0>
}

// nastavení světelného zdroje
light_source {
    <200, 50, -80>
    color White
}

// čtyřrozměrná Juliova množina
object {
    julia_fractal {
        <0.8*sin(clock*6.28),   // amplituda=0,8, jedna perioda
         0.8*cos(clock*6.28),   // amplituda=0,8, jedna perioda
         0.8*sin(2*clock*6.28), // amplituda=0,8, dvě periody
         0.8*cos(3*clock*6.28)> // amplituda=0,8, tři periody
        quaternion              // typ použité algebry
        sqr                     // iterační funkce: z->z^2+c
        max_iteration 8         // maximální počet iterací
        precision 80            // přesnost výpočtu průsečíku paprsku
        slice <0, 0, 0, 1>, 0   // trojrozměrný ořezávací podprostor
    }
    texture {                   // textura, kterou je fraktál pokryt
        pigment {
            color Sienna
        }
        finish {
            ambient 0.3
            diffuse 0.7
            phong 1
        }
    }
    scale 10                    // zvětšení fraktálního objektu
}

// podlaha s texturou šachovnice
plane {y, -10
    texture {
        pigment {
            checker
            color White color Black
        }
        scale 6
    }
}

// finito 

Výslednou animaci o rozlišení 352×288 pixelů (v tomto případě se jedná o rozlišení odpovídající specifikaci CIF – Common Intermediate Format), která je uložena do formátu MPEG-1, si můžete prohlédnout zde za pomoci prakticky libovolného multimediálního přehrávače. Animace obsahuje celkem 300 snímků a doba trvání jejího přehrání je přibližně 300/25=12 sekund. Jak již bylo řečeno výše, animace je periodická – může se přehrávat stále dokola bez viditelného přeskoku mezi posledním a prvním snímkem.

fractals65_1

Obrázek 1: První demonstrační animace – snímek číslo 1

fractals65_2

Obrázek 2: První demonstrační animace – snímek číslo 50

fractals65_3

Obrázek 3: První demonstrační animace – snímek číslo 100

fractals65_4

Obrázek 4: První demonstrační animace – snímek číslo 150

fractals65_5

Obrázek 5: První demonstrační animace – snímek číslo 300

3. Druhá demonstrační animace – odlišná „rotace“ konstanty c

I ve druhé demonstrační animaci se provádí rotace kvaternionové konstanty c. Změna oproti předchozí animaci spočívá v tom, že se zmenšil poloměr čtyřrozměrné koule, po které se pohybuje bod představující konstantu c, na hodnotu 0,7 jednotek. Také vlastní rotace probíhá odlišným způsobem, protože pro každou souřadnici je použita jiná perioda, což je ostatně patrné i z výpisu souboru popisujícího scénu (použité hodnoty v goniometrických funkcích jsou nesoudělné, aby nedocházelo k několikanásobnému opakování animace). Další změny ve scéně jsou spíše kosmetické – jsou použity dva světelné zdroje a změnily se textury, kterými je pokryt jak fraktální objekt, tak i podlaha tvořená nyní šachovnicí složenou ze dvou různých textur dřeva. Druhou demonstrační animaci si můžete prohlédnout po aktivaci tohoto odkazu. Popis celé scény má následující tvar:

// Druhá ukázka jednoduché animace trojrozměrného řezu
// původně čtyřrozměrnou Juliovou množinou.
//
// Animace je prováděna změnou kvaternionové
// konstanty C.

// specifikace verze POV-Raye
#version 3.0

// globální nastavení scény
global_settings {
    assumed_gamma 2.2
}

#include "colors.inc"

// nastavení pozice kamery a směru pohledu
camera {
    location <20, 30, -10>
    look_at  <0, 0, 0>
}

// nastavení dvojice světelných zdrojů

// první světelný zdroj
light_source {
    <-1000, 50, -180>
    color White
}

// druhý světelný zdroj
light_source {
    <1000, 1000, -5>
    color White
}

// čtyřrozměrná Juliova množina
object {
    julia_fractal {
        <0.7*sin(2*clock*6.28), // amplituda=0,7, dvě periody
         0.7*sin(3*clock*6.28), // amplituda=0,7, tři periody
         0.7*sin(5*clock*6.28), // amplituda=0,7, pět period
         0.7*sin(7*clock*6.28)> // amplituda=0,7, sedm period
        quaternion              // typ použité algebry
        sqr                     // iterační funkce: z->z^2+c
        max_iteration 6         // maximální počet iterací
        precision 30            // přesnost výpočtu průsečíku paprsku
        slice <1, 0, 0, 1>, 0   // trojrozměrný ořezávací podprostor
    }
    texture {                   // textura, kterou je fraktál pokryt
        pigment {
            color Green*0.7
        }
        finish {
            ambient 0.3
            diffuse 0.7
            phong 1
        }
    }
    scale 12                    // zvětšení fraktálu ve scéně
}

// podlaha s texturou šachovnice, obsahující
// různé druhy dřeva
plane {y, -10
    texture {
        pigment {
            checker
            pigment {           // textura prvního druhu políček
                wood            // na šachovnici
                turbulence 0.6
                scale <0.05, .05, 1>
                color_map {
                    [0.0, 0.1 color rgb <0.888, 0.600, 0.3>
                              color rgb <0.888, 0.600, 0.3>]
                    [0.1, 0.9 color rgb <0.888, 0.600, 0.3>
                              color rgb <0.600, 0.400, 0.2>]
                    [0.9, 1.0 color rgb <0.600, 0.400, 0.2>
                              color rgb <0.600, 0.400, 0.2>]
                }
                rotate 90
                scale 5
            }
            pigment {           // textura druhého druhu políček
                wood            // na šachovnici
                turbulence 0.4
                colour_map {
                    [0.00 0.34  color rgb <0.58, 0.45, 0.23>
                                color rgb <0.65, 0.45, 0.25>]
                    [0.34 0.40  color rgb <0.65, 0.45, 0.25>
                                color rgb <0.33, 0.23, 0.13>]
                    [0.40 0.47  color rgb <0.33, 0.23, 0.13>
                                color rgb <0.60, 0.40, 0.20>]
                    [0.47 1.00  color rgb <0.60, 0.40, 0.20>
                                color rgb <0.25, 0.15, 0.05>]
                }
                scale 0.6
            }
        }
        scale 7
    }
}

// finito 

fractals65_6

Obrázek 6: Druhá demonstrační animace – snímek číslo 1

fractals65_7

Obrázek 7: Druhá demonstrační animace – snímek číslo 50

fractals65_8

Obrázek 8: Druhá demonstrační animace – snímek číslo 100

fractals65_9

Obrázek 9: Druhá demonstrační animace – snímek číslo 200

fractals65_a

Obrázek 10: Druhá demonstrační animace – snímek číslo 242

4. Třetí demonstrační animace – pohyb konstanty c po spirále

Ve třetí demonstrační animaci je použit složitější vztah pro změnu kvaternionové konstanty c. Koncový bod vektoru představovaného touto konstantou se již nepohybuje pouze po čtyřrozměrné kouli, ale po spirále. Vzhledem k tomu, že animace začíná s hodnotou konstanty c nastavenou na c=0+0i+0j+0k, tj. c=[0, 0, 0, 0], je první zobrazený tvar podobný kouli (v případě klasické Juliovy množiny se jedná o kružnici, takže zde můžeme spatřit podobnost), která se spolu s rostoucí délkou vektoru „rozkmitává“ a postupně dostává tvar podobný tvarům zobrazeným v předchozích animacích.

Povrch fraktálního objektu se podobá zlatému plechu (i s částečným zrcadlením), proto jsou jasně patrné i první zákmity v úvodních snímcích. Další rozdíl oproti předchozím animacím spočívá v tom, že se již nejedná o animaci periodickou – mezi posledním a prvním snímkem je jasně patrný přeskok. Popis trojrozměrné scény použité pro tvorbu animace vypadá následovně:

// Třetí ukázka jednoduché animace trojrozměrného řezu
// původně čtyřrozměrnou Juliovou množinou. Tato animace
// využívá pohybu kvaternionové konstanty C po spirále.

// specifikace verze POV-Raye
#version 3.0

// globální nastavení scény
global_settings {
    assumed_gamma 2.2
}

#include "colors.inc"
#include "textures.inc"

// nastavení pozice kamery a směru pohledu
camera {
    location <20, 20, -10>
    look_at  <0, 0, 0>
}

// nastavení prvního světelného zdroje
light_source {
    <200, 50, -80>
    color White
}

// nastavení druhého světelného zdroje
light_source {
    <0, 100, 0>
    color White*0.5
}

// čtyřrozměrná Juliova množina
object {
    julia_fractal {
        <(clock*0.9)*sin(8*clock*6.28), // pohyb po spirále
         (clock*0.9)*cos(8*clock*6.28),
         (clock*0.9)*sin(8*2*clock*6.28),
         (clock*0.9)*cos(8*3*clock*6.28)>
        quaternion              // typ použité algebry
        sqr                     // iterační funkce: z->z^2+c
        max_iteration 6         // maximální počet iterací
        precision 80            // přesnost výpočtu průsečíku paprsku
        slice <0, 0, 0, 1>, 0   // trojrozměrný ořezávací podprostor
    }
    texture {
        Gold_Texture            // textura, kterou je fraktál pokryt
    }
    scale 10                    // zvětšení fraktálního objektu
}

// podlaha s texturou šachovnice
plane {y, -10
    texture {
        pigment {
            checker
            color White color Black
        }
        scale 6
    }
}

// finito 

fractals65_b

Obrázek 11: Třetí demonstrační animace – snímek číslo 1

fractals65_c

Obrázek 12: Třetí demonstrační animace – snímek číslo 50

fractals65_d

Obrázek 13: Třetí demonstrační animace – snímek číslo 100

fractals65_e

Obrázek 14: Třetí demonstrační animace – snímek číslo 150

fractals65_f

Obrázek 15: Třetí demonstrační animace – snímek číslo 200

5. Průběžná rotace ořezávacího trojrozměrného podprostoru

Čtvrtá demonstrační animace se od předchozí trojice animací v jedné podstatné věci odlišuje. Nemění se totiž hodnota kvaternionové konstanty c (ta je stále nastavena na [0, 1, 0, 0]), ale normálový vektor ořezávacího trojrozměrného podprostoru, který byl naopak v předchozích animacích nastaven na konstantní hodnotu. Normálový vektor má čtyři složky, přičemž poslední složka by měla být stále nastavena na hodnotu 1 (jedná se o omezení POV-Raye). Z tohoto důvodu jsou měněny pouze tři první složky tohoto vektoru. Výsledkem je video s poněkud odlišným charakterem než tomu bylo u předchozí trojice animací. Díky použití goniometrických funkcí je animace periodická. Popis celé scény pro program POV-Ray vypadá následovně:

// Čtvrtá ukázka jednoduché animace trojrozměrného řezu
// původně čtyřrozměrnou Juliovou množinou.
//
// Animace je prováděna změnou ořezávacího 3D podprostoru.

// specifikace verze POV-Raye
#version 3.0

// globální nastavení scény
global_settings {
    assumed_gamma 2.2
}

#include "colors.inc"

// nastavení pozice kamery a směru pohledu
camera {
    location <20, 30, -10>
    look_at  <0, 0, 0>
}

// nastavení dvojice světelných zdrojů

// první světelný zdroj
light_source {
    <-1000, 50, -180>
    color White
}

// druhý světelný zdroj
light_source {
    <1000, 1000, -5>
    color White
}

// čtyřrozměrná Juliova množina
object {
    julia_fractal {
        <0, 1.0, 0.0, 0.0>
        quaternion              // typ použité algebry
        sqr                     // iterační funkce: z->z^2+c
        max_iteration 8         // maximální počet iterací
        precision 80            // přesnost výpočtu průsečíku paprsku
        slice <0.8*sin(2*clock*6.28), // amplituda=0,8, dvě periody
               0.8*sin(3*clock*6.28), // amplituda=0,8, tři periody
               0.8*sin(5*clock*6.28), // amplituda=0,8, pět period
               1> // poslední hodnota by měla být rovna jedné
         , 0   // posun trojrozměrného ořezávacího podprostoru
    }
    texture {                   // textura, kterou je fraktál pokryt
        pigment {
            color Green*0.7
        }
        finish {
            ambient 0.3
            diffuse 0.7
            phong 1
        }
    }
    scale 12                    // zvětšení fraktálu ve scéně
}

// podlaha s texturou šachovnice, obsahující
// různé druhy dřeva
plane {y, -10
    texture {
        pigment {
            checker
            pigment {           // textura prvního druhu políček
                wood            // na šachovnici
                turbulence 0.6
                scale <0.05, .05, 1>
                color_map {
                    [0.0, 0.1 color rgb <0.888, 0.600, 0.3>
                    color rgb <0.888, 0.600, 0.3>]
                    [0.1, 0.9 color rgb <0.888, 0.600, 0.3>
                    color rgb <0.600, 0.400, 0.2>]
                    [0.9, 1.0 color rgb <0.600, 0.400, 0.2>
                    color rgb <0.600, 0.400, 0.2>]
                }
                rotate 90
                scale 5
            }
            pigment {           // textura druhého druhu políček
                wood            // na šachovnici
                turbulence 0.4
                colour_map {
                    [0.00 0.34  color rgb <0.58, 0.45, 0.23>
                    color rgb <0.65, 0.45, 0.25>]
                    [0.34 0.40  color rgb <0.65, 0.45, 0.25>
                    color rgb <0.33, 0.23, 0.13>]
                    [0.40 0.47  color rgb <0.33, 0.23, 0.13>
                    color rgb <0.60, 0.40, 0.20>]
                    [0.47 1.00  color rgb <0.60, 0.40, 0.20>
                    color rgb <0.25, 0.15, 0.05>]
                }
                scale 0.6
            }
        }
        scale 7
    }
}

// finito 

fractals65_g

Obrázek 16: Čtvrtá demonstrační animace – snímek číslo 1

fractals65_h

Obrázek 17: Čtvrtá demonstrační animace – snímek číslo 50

fractals65_i

Obrázek 18: Čtvrtá demonstrační animace – snímek číslo 100

fractals65_j

Obrázek 19: Čtvrtá demonstrační animace – snímek číslo 164

root_podpora

fractals65_k

Obrázek 20: Čtvrtá demonstrační animace – snímek číslo 258

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

V následujícím pokračování tohoto seriálu si ukážeme, jakým způsobem je možné vytvářet animace Juliových množin za použití hyperkomplexní algebry. Uvidíme, že výsledné animace budou mít zcela jiný charakter než animace uvedené v této části seriálu.

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.