Hlavní navigace

Animace hyperkomplexních Juliových množin

6. 2. 2007
Doba čtení: 12 minut

Sdílet

V dnešním článku si ukážeme, jakým způsobem je možné vytvářet animace původně čtyřrozměrných Juliových množin za použití hyperkomplexní algebry. Uvidíme, že díky odlišné algebře použité pro výpočet budou mít výsledné animace zcela jiný charakter než animace využívající kvaternionovou algebru.

Obsah

1. Animace čtyřrozměrné Juliovy množiny počítané hyperkomplexní algebrou
2. Rozdíl ve tvarech Juliových množin vypočtených pomocí kvaternionové a hyperkomplexní algebry
3. První demonstrační animace – „rotace“ prvních dvou složek konstanty c
4. Druhá demonstrační animace – „rotace“ posledních dvou složek konstanty c
5. Třetí demonstrační animace – změna všech čtyř složek konstanty c
6. Čtvrtá demonstrační animace – pohyb složek konstanty c po spirále
7. Obsah dalšího pokračování tohoto seriálu

1. Animace čtyřrozměrné Juliovy množiny počítané hyperkomplexní algebrou

V předchozí části tohoto seriálu jsme si ukázali tvorbu animací původně čtyřrozměrných Juliových množin, které byly pro potřeby zobrazení ořezány třírozměrným prostorem zadaným svým normálovým vektorem a vzdáleností od počátku souřadného systému. Všechny výpočty (zejména iterační funkce) přitom byly prováděny za použití kvaternionové algebry, kterou v roce 1843 vymyslel známý matematik William Rowan Hamilton. Vytvářené prostorové fraktální objekty se vyznačovaly středovou symetričností a zakulaceným tvarem. Dnes si ukážeme animace čtyřrozměrných Juliových množin, při jejichž výpočtu je místo kvaternionů použita hyperkomplexní algebra. Jak uvidíme v následujících kapitolách, vede použití jiné algebry k odlišným tvarům i průběhu celé animace.

Připomeňme si, že každé hyperkomplexní číslo můžeme zapsat buď formou lineární kombinace čtyř vektorů h=x1+yi+zj+wk, kde 1, i, j a k jsou jednotkové a na sebe kolmé vektory, nebo jako čtyřsložkový vektor h=[x, y, z, w]. Při násobení dvou hyperkomplexních čísel platí zvláštní vztahy pro součin dvojic jednotkových vektorů, podobně jako tomu je u komplexních čísel i u kvaternionů. Tyto vztahy jsou sepsány v následující tabulce:

Multiplikativní operace Výsledek
1×1 1
1×i i
1×j j
1×k k
i×1 i
j×1 j
k×1 k
i×j k
j×i k
j×k -i
k×j -i
k×i -j
i×k -j
i×i=j×j=-k×k –1
i×j×k 1

Vztahy vypsané v předchozí tabulce použijeme zejména v případě, že máme vynásobit dvě hyperkomplexní hodnoty:

h1=x1+y1i+z1j­+w1k
a
h2=x2+y2i+z2j­+w2k

Vzájemný součin těchto hodnot můžeme vyjádřit vztahem:

h1h2=
    1(x1x2 – y1y2 – z1z2 + w1w2) +
    i(y1x2 + x1y2 – w1z2 – z1w2) +
    j(z1x2 – w1y2 + x1z2 – y1w2) +
    k(w1x2 + z1y2 + y1z2 + x1w2

Všechny dále uvedené animace jsou vytvořeny pomocí průběžné změny čtyřrozměrné konstanty c s využitím hyperkomplexní algebry při provádění iterační smyčky. Než si však jednotlivé animace popíšeme podrobněji, podívejme se na rozdíl ve tvarech řezů Juliovou množinou, které vznikají na základě použité algebry.

2. Rozdíl ve tvarech Juliových množin vypočtených pomocí kvaternionové a hyperkomplexní algebry

Ve výše uvedeném vztahu pro výpočet součinu dvou hyperkomplexních hodnot můžeme vidět v porovnání s kvaterniny určitou nesymetričnost, zejména při srovnání znamének výrazů vyskytujících se u jednotkových vektorů i a j s jednotkovým vektorem k. Tato nesymetričnost dále vynikne v případě výpočtu druhé mocniny hyperkomplexní konstanty h. Nejedná se přitom o výpočet uměle vymyšlený, protože v iterační funkci pro Mandelbrotovu množinu i množiny Juliovy se počítá právě druhá mocnina hyperkomplexní hodnoty z, konkrétně se jedná o vzorec: z→z2+c . Výpočet druhé mocniny hyperkomplexní hodnoty h můžeme vyjádřit následujícím způsobem:

h2=(x+yi+zj+wk)2=
    1(x2-y2-z2+w2)+
    i(2×y-2zw)+
    j(2×z-2yw)+
    k(2×w+2yz) 

Pro porovnání si uveďme, jakým způsobem byla vyjádřena druhá mocnina kvaternionu q:

q2=(x+yi+zj+wk)2=
    1(xx – yy – zz – ww) +
    i(yx + xy + wz – zw) +
    j(zx – wy + xz + yw) +
    k(wx + zy – yz + xw)
=
    1(x2 – y2 – z2 – w2) +
    2ixy +
    2jxz +
    2kxw
 

Další porovnání bude vizuální: na prvních dvou obrázcích je zobrazena dvojice původně čtyřrozměrných Juliových množin. První množina byla vypočtena kvaternionovou algebrou, druhá množina za pomoci algebry hyperkomplexní. Za konstantu c byla v obou případech zvolena hodnota [0, 0, 0, 0]. Vidíme, že tvar obou množin se liší – kvaternionová varianta Juliovy množiny má tvar přesné koule, hyperkomplexní varianta se spíše podobá superelipsoidu s vhodně nastavenými parametry. V praxi (pro rendering) se více používají Juliovy množiny vypočtené pomocí kvaternionů, protože ostré „pravoúhlé“ tvary hyperkomplexních Juliových množin nevypadají přirozeně a výpočet s pomocí kvaternionů probíhá rychleji.

fractals66_1

Obrázek 1: Porovnání 3D řezů Juliovými množinami vytvořenými s pomocí kvaternionové a hyperkomplexní algebry; zde je použita kvaternionová algebra, konstanta c má hodnotu [0, 0, 0, 0]

fractals66_2

Obrázek 2: Porovnání 3D řezů Juliovými množinami vytvořenými s pomocí kvaternionové a hyperkomplexní algebry; zde je použita hyperkomplexní algebra, konstanta c má hodnotu [0, 0, 0, 0]

Třetí a čtvrtý obrázek ukazuje rozdíl mezi Juliovými množinami, u nichž byla zvolena jiná hodnota konstanty c. V takovém případě je již rozdíl v tvarech obou množin velmi výrazný.

fractals66_3

Obrázek 3: Porovnání 3D řezů Juliovými množinami vytvořenými s pomocí kvaternionové a hyperkomplexní algebry; zde je použita kvaternionová algebra, konstanta c má hodnotu [0, 1, 0, 0]

fractals66_4

Obrázek 4: Porovnání 3D řezů Juliovými množinami vytvořenými s pomocí kvaternionové a hyperkomplexní algebry; zde je použita hyperkomplexní algebra, konstanta c má hodnotu [0, 1, 0, 0]

3. První demonstrační animace – „rotace“ prvních dvou složek konstanty c

Dnešní první demonstrační animace byla vytvořena tím způsobem, že se pomocí vhodně nastavených goniometrických funkcí sinus a kosinus měnily hodnoty prvních dvou složek cx a cy čtyřrozměrné konstanty c=cx+icy+jcz+kcw. Ostatní dvě složky cz a cw měly nastavenou nulovou hodnotu. Animace obsahuje celkem 300 snímků a je periodická, tj. na poslední snímek plynule navazuje snímek první.

Rozlišení animace 352×288 pixelů odpovídá specifikaci CIF (Common Intermediate Format) a je uložena – jak je ostatně v tomto seriálu zvykem – ve formátu MPEG-1. Doba trvání jejího přehrání je rovna přibližně 300/25=12 sekund. Rendering celé animace, která byla vytvářena v čtyřnásobném rozlišení 704×576 pixelů, trval na počítači s procesorem Intel Celeron 900 MHz cca 12 hodin. Textový soubor popisující celou trojrozměrnou scénu s Juliovou množinou má tvar:

// Fraktály v počítačové grafice
//
// První ukázka jednoduché animace trojrozměrného řezu
// původně čtyřrozměrnou Juliovou množinou počítanou
// pomocí hyperkomplexní algebry.
//
// Animace je prováděna průběžnou změnou prvních
// dvou složek hyperkomplexní konstanty C.
// Vektor představovaný touto konstantou opisuje kružnici.

// 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.6*cos(clock*6.28), 0.6*sin(clock*6.28), 0.0, 0.0>
        hypercomplex            // typ použité algebry
        sqr                     // iterační funkce: z->z^2+c
        max_iteration 6         // maximální počet iterací
        precision 50            // přesnost výpočtu průsečíku paprsku
        slice <0, 0, 0, 1>, 0
    }
    texture {                   // textura, kterou je fraktál pokryt
        pigment {               // konstantní tmavě červená barva
            color Red*0.6
        }
        finish {                // míra odlesků
            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, 0.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                 // zvětšení textury
    }
}

// finito 

fractals66_5

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

fractals66_6

Obrázek 6: První demonstrační animace, snímek číslo 50

fractals66_7

Obrázek 7: První demonstrační animace, snímek číslo 100

fractals66_8

Obrázek 8: První demonstrační animace, snímek číslo 280

4. Druhá demonstrační animace – „rotace“ posledních dvou složek konstanty c

Dnešní druhá demonstrační animace byla vytvořena postupnou změnou posledních dvou složek cz a cw konstanty c=cx+icy+jcz+kcw, první dvojice složek cx a cy byla nastavena na nulovou hodnotu. Můžeme vidět, že animace má zcela jiný charakter – jsou patrné dva směry metamorfózy celého objektu, které se shodují se dvěma souřadnými osami (objektem nebylo v případě této animace ve scéně rotováno). Pro odlišení animací byly také zvoleny jiné textury povrchu fraktálního objektu i textury podlahy. Díky jednodušším texturám bylo dosaženo menší velikosti souboru s animací.

Podobně jako první animace, i druhá animace je periodická (poslední snímek plynule navazuje na snímek první) a má i stejné rozlišení: 352×288 pixelů, shodný počet 300 snímků i stejný formát: MPEG-1. Doba přehrání je rovna 12 sekundám, zatímco doba renderování přesáhla na počítači s procesorem Intel Celeron 900 MHz 10 hodin. Textový soubor s popisem celé vykreslované scény má následující obsah:

// Fraktály v počítačové grafice
//
// Druhá ukázka jednoduché animace trojrozměrného řezu
// původně čtyřrozměrnou Juliovou množinou počítanou
// pomocí hyperkomplexní algebry.
//
// Animace je prováděna průběžnou změnou
// posledních dvou složek hyperkomplexní konstanty C.
// Vektor představovaný touto konstantou opisuje kružnici.

// 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 {
    <-200, 50, -180>
    color White
}

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

// čtyřrozměrná Juliova množina
object {
    julia_fractal {
        <0.0, 0.0, 0.7*cos(clock*6.28), 0.7*sin(clock*6.28)>
        hypercomplex            // typ použité algebry
        sqr                     // iterační funkce: z->z^2+c
        max_iteration 6         // maximální počet iterací
        precision 50            // přesnost výpočtu průsečíku paprsku
        slice <0, 0, 0, 1>, 0
    }
    texture {                   // textura, kterou je fraktál pokryt
        pigment {
            color Yellow*0.6    // tmavě žlutá barva
        }
        finish {                // nastavení odlesků
            ambient 0.3
            diffuse 0.7
            phong 1
        }
    }
    scale 12                    // zvětšení fraktálu ve scéně
}

// koule představující oblohu
sphere {
    <0,0,0>, 500                // je umístěná až za kamerou a světelnými zdroji
    pigment {
        gradient y
        color_map {
            [0.00 0.10 color Yellow color Orange] // na horizontu je oranžová
            [0.10 0.15 color Orange color Red   ] // přechod z oranžové do červené
            [0.15 0.27 color Red    color Blue  ] // přechod z červené do modré
            [0.27 1.01 color Blue   color Black ] // přechod z modré do černé (zenit)
        }
        scale 1500              // zvětšení textury
    }
    finish  {                   // zákaz odlesků
        ambient 1.0
        diffuse 0.0
    }
}

// vrchní část plochy
plane { y, -10
    pigment {
        Blue                    // barva textury
    }
    normal {                    // modulace normály
        waves 0.05              // (bump mapping)
        frequency 5000
        scale 3500
    }
    finish {                    // nastavení odrazivosti plochy
        reflection 0.8
    }
}

// spodní část plochy
plane { y, -20                  // umístěná 10 jednotek pod předešlou plochou
    pigment {
        Blue                    // barva textury
    }
    finish  {                   // zákaz odlesků
        ambient 1.0             // (pouze všesměrová složka světla)
        diffuse 0.0
    }
}

// finito 

fractals66_9

Obrázek 9: Druhá demonstrační animace, snímek číslo 0

fractals66_10

Obrázek 10: Druhá demonstrační animace, snímek číslo 75

fractals66_11

Obrázek 11: Druhá demonstrační animace, snímek číslo 150

fractals66_12

Obrázek 12: Druhá demonstrační animace, snímek číslo 225

5. Třetí demonstrační animace – změna všech čtyř složek konstanty c

Ve třetí demonstrační animaci jsou průběžně měněny všechny čtyři složky hyperkomplexní proměnné c=cx+icy+jcz+kcw, tj. cx, cy, cz i cw. Periody opakování u goniometrických funkcí sinus a kosinus (viz zdrojový kód) jsou však nastaveny různě, to znamená, že každá složka se mění poněkud odlišným způsobem, což činí animaci zajímavější a přitom je stále zajištěna její periodičnost, protože hodnota každé periody (argument goniometrické funkce) je vynásobena konstantou 2π. Všimněte si, že na některých snímcích došlo k chybnému výpočtu průsečíku paprsku s fraktálním objektem, což je patrné zejména na roztřepaných okrajích.

Tato chyba je patrná zejména u Juliových množin vypočtených pomocí hyperkomplexní algebry a ani vyšší hodnota parametru precision v tomto případě nepomáhá, pouze neúměrně prodlužuje renderovací čas, který opět pro celou animaci, tj. 300 snímků o rozlišení 352×288 pixelů (původně před resamplingem 704×572 pixelů), přesáhl hodnotu dvanácti hodin – z tohoto důvodu je vhodné provádět renderování čtyřrozměrných Juliových množin v zimě, kdy počítač slouží i jako topení :-). Zdrojový kód popisující celou renderovanou scénu má tento obsah:

// Fraktály v počítačové grafice
//
// Třetí ukázka jednoduché animace trojrozměrného řezu
// původně čtyřrozměrnou Juliovou množinou počítanou
// pomocí hyperkomplexní algebry.
//
// Animace je prováděna průběžnou změnou všech
// čtyř složek hyperkomplexní konstanty C. Vektor
// představovaný touto konstantou se pohybuje
// po povrchu čtyřrozměrné koule.

// specifikace verze POV-Raye
#version 3.0

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

#include "colors.inc"
#include "textures.inc"
#include "woods.inc"
#include "stones.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, 350, -180>
    color White
}

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

// čtyřrozměrná Juliova množina
object {
    julia_fractal {
        <0.5*cos(7*clock*6.28), // amplituda=0,5, sedm period
         0.5*sin(3*clock*6.28), // amplituda=0,5, tři periody
         0.5*cos(5*clock*6.28), // amplituda=0,5, pět period
         0.5*sin(2*clock*6.28)> // amplituda=0,5, dvě periody
        hypercomplex            // typ použité algebry
        sqr                     // iterační funkce
        max_iteration 6         // maximální počet iterací
        precision 60            // přesnost výpočtu průsečíku paprsku
        slice <0, 0, 0, 1>, 0
    }
    texture {                   // textura, kterou je fraktál pokryt
        T_Wood6                 // viz soubor woods.inc
        finish {                // nastavení odlesků
            ambient 0.3
            diffuse 0.7
            phong 1
        }
    }
    scale 16                    // zvětšení fraktálu ve scéně
}

// podlaha s texturou šachovnice, která se podobá mramoru
plane {y, -10
    texture {
        T_Stone1                // viz soubor stones.inc
        scale 10                // zvětšení textury
    }
}

// finito 

fractals66_13

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

fractals66_14

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

fractals66_15

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

fractals66_16

Obrázek 16: Třetí demonstrační animace, snímek číslo 134

6. Čtvrtá demonstrační animace – pohyb složek konstanty c po spirále

Ve čtvrté a současně i poslední demonstrační animaci jsou jednotlivé složky hyperkomplexní konstanty c měněny tak, aby se koncový bod vektoru představovaný touto konstantou pohyboval po spirále, která má počátek v bodu [0, 0, 0, 0]. Povrch fraktálního objektu je potažen texturou vyleštěného dřeva, proto jsou jasně patrné i první zákmity objektu. Na některých snímcích jsou opět vidět chyby vzniklé nesprávným vyhodnocením průsečíku paprsku s povrchem fraktálního objektu. Vzhledem k tomu, že se koncový bod spirály představované vektorem c nespojí s bodem počátečním, není ani výsledná animace periodická. Naopak, původně spojitý a pravidelný objekt se postupně rozpadá na trojrozměrnou variantu známého Cantorova prachu (Cantor Dust).

// Fraktály v počítačové grafice
//
// Čtvrtá ukázka jednoduché animace trojrozměrného řezu
// původně čtyřrozměrnou Juliovou množinou počítanou
// pomocí hyperkomplexní algebry.
//
// Animace je prováděna průběžnou změnou všech
// čtyř složek hyperkomplexní konstanty C. Vektor
// představovaný touto konstantou opisuje spirálu.

// specifikace verze POV-Raye
#version 3.0

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

#include "colors.inc"
#include "woods.inc"

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

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

// čtyřrozměrná Juliova množina
object {
    julia_fractal {
        <(clock*0.7)*sin(6*clock*6.28), // pohyb po spirále
         (clock*0.7)*cos(6*clock*6.28),
         (clock*0.7)*sin(6*2*clock*6.28),
         (clock*0.7)*cos(6*3*clock*6.28)>
        hypercomplex            // typ použité algebry
        sqr                     // iterační funkce: z->z^2+c
        max_iteration 6         // maximální počet iterací
        precision 50            // přesnost výpočtu průsečíku paprsku
        slice <0, 0, 0, 1>, 0   // řez 3D podprostorem
    }
    texture {                   // textura, kterou je fraktál pokryt,
        T_Wood1                 // je definována v souboru woods.inc
        finish {                // nastavení odlesků
            ambient 0.3
            diffuse 0.7
            phong 1
        }
    }
    scale 12                    // zvětšení fraktálu ve scéně
    rotate <0, 0, 90>
}

// deklarace textury, kterou je pokryta podlaha
#declare TextPodlaha=
    texture{
        pigment {
            White               // barva textury
        }
        normal {                // modulace normály
            wrinkles 0.6        // (bump mapping)
            scale 0.24
        }
        finish {                // nastavení odlesků
            phong 0.8
            phong_size 200
        }
    }

// podlaha s nanesenou texturou
plane {y, -10
    texture {
        TextPodlaha
        scale 15
    }
}

// finito 

fractals66_17

Obrázek 17: Čtvrtá demonstrační animace, snímek číslo 0

fractals66_18

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

fractals66_19

Obrázek 19: Čtvrtá demonstrační animace, snímek číslo 210

ict ve školství 24

fractals66_20

Obrázek 20: Čtvrtá demonstrační animace, snímek číslo 300

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

Příště si ukážeme, jakým způsobem je možné vytvářet trojrozměrné obrazce Juliových množin v programu Quat, který je šířen pod licencí GNU.

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.