Obsah
1. Použití spline funkcí v POV-Rayi
2. První demonstrační příklad – použití různých typů spline funkcí
3. Druhý demonstrační příklad – spline funkce vracející třísložkový vektor
4. Spline funkce a animace
5. Třetí demonstrační příklad – posun objektu po cestě vytvořené spline křivkou
6. Čtvrtý demonstrační příklad – jedna spline funkce vyhodnocovaná při posunu většího množství objektů
7. Obsah dalšího pokračování seriálu
1. Použití spline funkcí v POV-Rayi
Raytracer POV-Ray je v současné verzi 3.x vybaven poměrně sofistikovaným a přitom snadno použitelným matematickým aparátem určeným pro práci se spline funkcemi. Tyto funkce představují základ pro tvorbu známých spline křivek popř. spline ploch, které jsme si již zevrubně popsali v osmé části tohoto seriálu. Spline funkce mj. tvoří základ pro modelování rotačních a vytahovaných těles – viz první a druhý obrázek s tělesem, jehož profil (kolmý řez) je tvořen kvadratickou resp. kubickou spline křivkou vypočtenou na základě spline funkce. Další možnosti použití spline funkcí jsou poměrně rozsáhlé, od tvorby animací s objekty pohybujícími se po zadané trajektorii, přes modelování těles s členitým povrchem až po definici procedurálních textur se vzorkem založeným na uživatelsky zadané spline funkci. POV-Ray podporuje čtyři typy spline funkcí – lineární, kvadratickou, kubickou a „přirozenou“ (natural – tento název je odvozen z faktu, že těleso, které se pohybuje po této křivce, nemění svoji rychlost, což je využitelné především při tvorbě animací).
Obrázek 1: Rotační těleso, jehož profil je určen kvadratickou spline křivkou.
Každá spline funkce, nezávisle na jejím typu, je specifikována seznamem libovolného množství řídicích bodů, mezi kterými POV-Ray automaticky vypočítá interpolační křivku. Každý řídicí bod je specifikován hodnotou parametru (reálné číslo určující pozici bodu v parametrickém prostoru) a vlastní souřadnicí řídicího bodu, přičemž vektor specifikující souřadnice bodu může mít dvě až pět složek – bod tedy může ležet v dvourozměrém až pětirozměrném prostoru, podle toho, k jakým účelům je spline funkce použita. Většinou si vystačíme buď s dvojicí nebo trojicí souřadnic (viz demonstrační příklady popsané v navazujících kapitolách). V případě, že dva řídicí body mají hodnotu svých parametrů shodnou (což znamená, že v parametrickém prostoru leží na stejném místě), berou se při výpočtu spline funkce v úvahu pouze souřadnice druhého řídicího bodu. Graf spline funkce obecně prochází svými řídicími body, jedná se tedy o interpolační křivku, ovšem u kvadratických a kubických spline mají krajní body odlišný význam – specifikuje se pomocí nich tečný vektor na začátku a konci křivky. Základní syntaxe zápisu definice spline funkce je následující:
#declare JMENO_SPLINE =
spline
{
typ_spline // linear_spline | quadratic_spline | cubic_spline | natural_spline
parametr_1, <bod_1>
parametr_2, <bod_2>
...
parametr_n, <bod_n>
}
Obrázek 2: Rotační těleso, jehož profil je určen kubickou spline křivkou. Vzhledem k charakteru kubických spline křivek neobsahuje profil žádné ostré hrany.
2. První demonstrační příklad – použití různých typů spline funkcí
V dnešním prvním demonstračním příkladu je ukázán způsob definice spline funkce a využití této funkce v programové smyčce, která postupně pro různé hodnoty parametru vyhodnocuje body ležící na spline křivce zvoleného typu. Spline nazvaná jednoduše SplineFunkce je zadána sedmi řídicími body, ovšem pouze pro pět těchto bodů (tvořících v ploše vrcholy čtverce, přičemž první vrchol musí být zdvojený) leží na výsledné křivce – krajní řídicí body jsou použity pro specifikaci tečných vektorů v případě volby kvadratických a kubických spline. V programové smyčce se spline vyhodnocuje pro parametr ležící mezi nulou a jedničkou, proto jsou oba krajní body (jejichž parametry mají hodnotu –0,25 a 1,25) z tohoto výpočtu vyloučeny, i když samozřejmě mohou ovlivňovat tvar vypočtené spline křivky.
Obrázek 3: Lineární spline je zkonstruována tak, že se mezi řídicími body provádí lineární interpolace (vznikají úsečkové segmenty).
Povšimněte si způsobu vyhodnocení spline funkce, tj. zápisu SplineFunkce(i).x a SplineFunkce(i).y – každé volání SplineFunkce(i) vrátí pro zadanou hodnotu parametru i (který by měl v tomto případě ležet mezi nulou a jedničkou) dvourozměrný vektor, protože i řídicí body leží v ploše (jak jsme se již dozvěděli v předchozí kapitole, je povoleno použít dvousložkové až pětisložkové vektory). Pomocí operátorů .x a .y je možné jednotlivé souřadnice vráceného vektoru extrahovat a použít v prakticky libovolném matematickém výrazu, zde pro určení středu jednoho prvku implicitní plochy.
Obrázek 4: Kvadratická spline, jejíž tvar na konci je ovlivněn tečným vektorem.
Obrázek 5: Kubická spline, při jejíž definici byly tečné vektory na okrajích zvoleny tak, aby vznikl symetrický tvar.
Následuje výpis zdrojového kódu prvního demonstračního příkladu:
// ------------------------------------------------------------
// První demonstrační příklad - vykreslení tvarů různých typů
// spline funkcí.
//
// rendering lze spustit příkazem:
// povray +W1024 +H768 +B100 +FN +D +Ispline1.pov +Ospline1.png
//
// (pro náhled postačí zadat příkaz povray spline1.pov)
// ------------------------------------------------------------
// globální nastavení parametrů scény
global_settings
{
assumed_gamma 2.2
max_trace_level 5
}
// načtení všech potřebných externích souborů
#include "colors.inc"
// nastavení kamery (pozorovatele)
camera
{
orthographic
location <0, 30, 0> // pozice kamery
look_at <0, 0, 0> // bod, na který kamera směřuje
}
// tři světelné zdroje
light_source
{
<-30, 50, 20> // pozice prvního světelného zdroje
color White // barva světla
}
light_source
{
< 31, 50, -20> // pozice druhého světelného zdroje
color White // barva světla
}
light_source
{
< 32, 50, 20> // pozice třetího světelného zdroje
color LightGray // barva světla
}
// podkladová rovina
plane
{
y, -5
texture
{ // textura - vlastnosti povrchu
pigment
{ // šachovnicová textura
checker // vyvedená ve stupních šedi
color rgb <0.3, 0.3, 0.3>
color rgb <0.5, 0.5, 0.5>
}
finish
{ // odlesky a odrazy na povrchu
diffuse 0.7
reflection 0.2
}
scale 3
}
}
#declare SplineFunkce = // deklarace spline funkce
spline
{
linear_spline
//quadratic_spline // typ použité spline funkce
//cubic_spline
//natural_spline
-.25, <-10, -10> // použije se pouze pro cubic_spline a natural_spline - první bod počátečního tečného vektoru
0.00, < 10, -10>
0.25, < 10, 10>
0.50, <-10, 10>
0.75, <-10, -10>
1.00, < 10, -10>
1.25, < 10, 10> // použije se pouze pro cubic_spline a natural_spline - druhý bod koncového tečného vektoru
}
blob
{
threshold 0.6
#declare i = 0;
#while (i < 1.0) // řídicí parametr spline funkce nabývá hodnot v rozsahu 0 až 1
sphere // pro každou hodnotu parametru je vypočtena souřadnice a barva kuličky
{
<SplineFunkce(i).x, 0, SplineFunkce(i).y>, 1.5,1 // souřadnice středu koule a její poloměr
texture
{
pigment // barva povrchu
{
rgb <0.5+0.5*sin(radians(i*360)), 0, 0.5+0.5*cos(radians(i*360))>
}
finish // odlesky na povrchu
{
phong 1.0
}
}
}
#declare i = i + 0.007; // zvýšit hodnotu řídicího parametru spline funkce
#end
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Obrázek 6: Přirozená (natural) spline taktéž prochází řídicími body a jedná se o kubiku, ovšem její tvar se od kubické spline odlišuje.
3. Druhý demonstrační příklad – spline funkce vracející třísložkový vektor
Ve druhém demonstračním příkladu je ukázáno použití spline funkce, která pro zadaný parametr i vrací třísložkový vektor. Ten je použit pro určení souřadnice středu barevné kuličky (v předchozím demonstračním příkladu se jednalo o středy prvků kostry implicitních ploch). Vzhledem k tomu, že POV-Ray správně rozezná, ve které chvíli je nutné použít vektor a kde jen jednu jeho složku, lze místo poměrně složitého a nepřehledného zápisu <SplineFunkce(i).x, SplineFunkce(i).y, SplineFunkce(i).z> (postupné vyhodnocení tří složek vektoru vráceného voláním SplineFunkce(i) a vytvoření vektoru nového) použít pouze SplineFunkce(i). V tomto případě se v zápisu nenachází ani úhlové závorky!
Obrázek 7: Tvar vytvořený z barevných kuliček ležících na lineární spline.
Zdrojový kód druhého demonstračního příkladu má tvar:
// ------------------------------------------------------------
// Druhý demonstrační příklad - použití spline funkce při
// vytváření "hada" složeného z barevných kuliček.
//
// rendering lze spustit příkazem:
// povray +W1024 +H768 +B100 +FN +D +Ispline2.pov +Ospline2.png
//
// (pro náhled postačí zadat příkaz povray spline2.pov)
// ------------------------------------------------------------
// globální nastavení parametrů scény
global_settings
{
assumed_gamma 2.2
max_trace_level 5
}
// načtení všech potřebných externích souborů
#include "colors.inc"
// nastavení kamery (pozorovatele)
camera
{
location <10, 30, -20> // pozice kamery
look_at <-5, -25, 15> // bod, na který kamera směřuje
}
// tři světelné zdroje
light_source
{
<-30, 50, 20> // pozice prvního světelného zdroje
color White // barva světla
}
light_source
{
< 31, 50, -20> // pozice druhého světelného zdroje
color White // barva světla
}
light_source
{
< 32, 50, 20> // pozice třetího světelného zdroje
color LightGray // barva světla
}
// podkladová rovina
plane
{
y, -15
texture
{ // textura - vlastnosti povrchu
pigment
{ // šachovnicová textura
checker // vyvedená ve stupních šedi
color rgb <0.3, 0.3, 0.3>
color rgb <0.5, 0.5, 0.5>
}
finish
{ // odlesky a odrazy na povrchu
diffuse 0.7
reflection 0.2
}
scale 5
}
}
#declare SplineFunkce = // deklarace spline funkce
spline
{
cubic_spline // typ použité spline funkce
//linear_spline
-.25, < 0, 0,-10> // použije se pouze pro cubic_spline - první bod počátečního tečného vektoru
0.00, <20, 0, 0>
0.25, < 0,-10, 10>
0.50, <-10,10, 0>
0.75, < 0, 10,-10>
1.00, <20, 0, 0>
1.25, < 0, 0, 10> // použije se pouze pro cubic_spline - druhý bod koncového tečného vektoru
}
#declare i = 0;
#while (i < 1.0) // řídicí parametr spline funkce nabývá hodnot v rozsahu 0 až 1
sphere // pro každou hodnotu parametru je vypočtena souřadnice a barva kuličky
{
SplineFunkce(i), 0.5 // souřadnice středu koule a její poloměr
texture
{
pigment // barva povrchu
{
rgb <0.5+0.5*sin(radians(i*360)), 0, 0.5+0.5*cos(radians(i*360))>
}
finish // odlesky na povrchu
{
phong 1.0
}
}
}
#declare i = i + 0.007; // zvýšit hodnotu řídicího parametru spline funkce
#end
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Obrázek 8: Tvar vytvořený z barevných kuliček ležících na kubické spline.
4. Spline funkce a animace
Spline funkce se velmi často používají při tvorbě animací, například při určování trajektorie, po které se mají pohybovat objekty ve scéně. Může se jednat jak o trojrozměrná tělesa, tak i o světelné zdroje nebo kameru (pozorovatele). Zatímco v předchozích dvou demonstračních příkladech se parametr předávaný do spline funkce počítal na základě programové smyčky, při specifikaci trajektorie se (většinou) místo počítaného parametru předává aktuální hodnota interní proměnné clock, jež se postupně v jednotlivých snímcích animace mění. V případě, že je křivka určená spline funkcí uzavřená (closed curve), bude výsledný pohyb objektu, tj. tělesa, světelného zdroje či kamery, cyklický. Aby byl pohyb objektu co nejpřirozenější, používají se většinou kubické spline funkce, tj. typy cubic_spline a natural_spline. Při použití lineární a kvadratické spline by při pohybu docházelo ke skokovým změnám směru (což na druhou stranu může být pro některý typ animací žádoucí vlastnost).
Obrázek 9: Základem této scény je rotační těleso, jehož profil je určen kubickou spline. Proutěný obal láhve byl získán pomocí makra „trace“.
5. Třetí demonstrační příklad – posun objektu po cestě vytvořené spline křivkou
V dnešním třetím demonstračním příkladu je ukázáno, jakým způsobem je možné použít spline křivku třetího řádu (tj. kubiku) pro určení trajektorie jednoduchého objektu – žluté kuličky. Trasa kuličky prochází osmi body, přičemž poslední bod je zdvojený, protože se jedná o uzavřenou křivku. Navíc je pro počáteční a koncový bod určen i tečný vektor, pomocí nějž se mění tvar spline křivky na jejím začátku a konci (jak jsme si již řekli v předchozích kapitolách, tečné vektory jsou použity u kvadratických a především kubických spline). Animaci vytvořenou renderingem třetího demonstračního příkladu lze získat pod tímto odkazem. Povšimněte si, že směr pohybu kuličky se sice mění bez nežádoucích skoků, ale rychlost pohybu není konstantní. Pokud by se navíc místo kuličky použil objekt jiného tvaru (model letadla, automobilu atd.), jeho orientace by se při pohybu neměnila. To, jakým způsobem je možné objektem při pohybu natáčet, si ukážeme v následující části tohoto seriálu.
Obrázek 10: Počáteční snímek třetího demonstračního příkladu.
Následuje výpis zdrojového kódu třetího demonstračního příkladu:
// ------------------------------------------------------------
// Třetí demonstrační příklad - použití spline funkce pro
// tvorbu cest použitých při animaci.
//
// rendering lze spustit příkazem:
// povray +W320 +H240 +B100 +FN +D +KFF100 +A -J +Ispline3.pov +Ospline3.png
// ------------------------------------------------------------
// globální nastavení parametrů scény
global_settings
{
assumed_gamma 2.2
max_trace_level 5
}
// načtení všech potřebných externích souborů
#include "colors.inc"
// nastavení kamery (pozorovatele)
camera
{
orthographic
location <0, 35, 0> // pozice kamery
look_at <0, 0, 0> // bod, na který kamera směřuje
}
// tři světelné zdroje
light_source
{
<-30, 50, 20> // pozice prvního světelného zdroje
color White // barva světla
}
light_source
{
< 31, 50, -20> // pozice druhého světelného zdroje
color White // barva světla
}
light_source
{
< 32, 50, 20> // pozice třetího světelného zdroje
color LightGray // barva světla
}
// podkladová rovina
plane
{
y, -8
texture
{ // textura - vlastnosti povrchu
pigment
{ // šachovnicová textura
checker // vyvedená ve stupních šedi
color rgb <0.3, 0.3, 0.3>
color rgb <0.5, 0.5, 0.5>
}
finish
{ // odlesky a odrazy na povrchu
diffuse 0.7
reflection 0.2
}
scale 3
}
}
#declare SplineFunkce = // deklarace spline funkce
spline
{
cubic_spline // typ použité spline funkce
-0.125, <-15, 0,-15> // první bod počátečního tečného vektoru
0.000, < 0, 0, 15>
0.125, < 15, 0,-15>
0.250, <-15, 0, 0>
0.375, < 15, 0, 15>
0.500, < 0, 0,-15>
0.625, <-15, 0, 15>
0.750, < 15, 0, 0>
0.875, <-15, 0,-15>
1.000, < 0, 0, 15>
1.125, < 15, 0,-15> // druhý bod koncového tečného vektoru
}
#declare alfa = clock;
sphere
{
SplineFunkce(alfa), 1.5 // souřadnice středu koule (vypočtené na základě spline funkce) a její poloměr
texture
{
pigment // barva povrchu
{
color Yellow
}
finish // odlesky na povrchu
{
phong 1.0
}
}
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Obrázek 11: Prostřední snímek třetího demonstračního příkladu.
6. Čtvrtý demonstrační příklad – jedna spline funkce vyhodnocovaná při posunu většího množství objektů
Výsledkem renderingu čtvrtého demonstračního příkladu je taktéž animace, ovšem počet objektů, které se pohybují po jedné spline křivce, se zvýšil na šest. Při výpočtu parametru předávaného spline funkci je použit výraz mod(clock + i/6, 1), kde proměnná i představuje index objektu 0 až 5 a funkce mod vrací zbytek po celočíselném dělení prvního parametru parametrem druhým. Na rozdíl od mnoha programovacích jazyků, kde je funkce (nebo spíše operátor) mod definovaný pouze pro celočíselné parametry, je v POV-Rayi možné použít i reálná čísla, neboť vztah pro výpočet této funkce vypadá následovně: mod=((A/B)-int(A/B))*B. Právě díky tomuto vztahu lze funkci mod použít pro zajištění periodicity parametrů předávaných do spline funkce, protože mod(x, 1) vrátí pro libovolné kladné x hodnotu ležící mezi nulou a jedničkou.
Obrázek 12: Počáteční snímek čtvrtého demonstračního příkladu.
Kód čtvrtého demonstračního příkladu má tvar:
// ------------------------------------------------------------
// Čtvrtý demonstrační příklad - pohyb šesti objektů po jedné
// spline křivce.
//
// rendering lze spustit příkazem:
// povray +W320 +H240 +B100 +FN +D +KFF100 +A -J +Ispline4.pov +Ospline4.png
// ------------------------------------------------------------
// globální nastavení parametrů scény
global_settings
{
assumed_gamma 2.2
max_trace_level 5
}
// načtení všech potřebných externích souborů
#include "colors.inc"
// nastavení kamery (pozorovatele)
camera
{
orthographic
location <0, 35, 0> // pozice kamery
look_at <0, 0, 0> // bod, na který kamera směřuje
}
// tři světelné zdroje
light_source
{
<-30, 50, 20> // pozice prvního světelného zdroje
color White // barva světla
}
light_source
{
< 31, 50, -20> // pozice druhého světelného zdroje
color White // barva světla
}
light_source
{
< 32, 50, 20> // pozice třetího světelného zdroje
color LightGray // barva světla
}
// podkladová rovina
plane
{
y, -5
texture
{ // textura - vlastnosti povrchu
pigment
{ // šachovnicová textura
checker // vyvedená ve stupních šedi
color rgb <0.3, 0.3, 0.3>
color rgb <0.5, 0.5, 0.5>
}
finish
{ // odlesky a odrazy na povrchu
diffuse 0.7
reflection 0.2
}
scale 3
}
}
#declare SplineFunkce = // deklarace spline funkce
spline
{
cubic_spline // typ použité spline funkce
-0.125, <-15, 0,-15> // první bod počátečního tečného vektoru
0.000, < 0, 0, 15>
0.125, < 15, 0,-15>
0.250, <-15, 0, 0>
0.375, < 15, 0, 15>
0.500, < 0, 0,-15>
0.625, <-15, 0, 15>
0.750, < 15, 0, 0>
0.875, <-15, 0,-15>
1.000, < 0, 0, 15>
1.125, < 15, 0,-15> // druhý bod koncového tečného vektoru
}
#declare i = 0; // proměnná, v níž je uložen index objektu (barevné kuličky)
#while ( i < 6 )
#declare alfa = mod(clock + i/6, 1); // výpočet hodnoty řídicího parametru pro každý objekt
sphere
{
SplineFunkce(alfa), 1.0 // souřadnice středu koule a její poloměr
texture
{
pigment // barva povrchu
{
#switch (i) // nastavení barvy
#case(0) color White #break;
#case(1) color Red #break;
#case(2) color Blue #break;
#case(3) color Yellow #break;
#case(4) color Magenta #break;
#case(5) color Green #break;
#end
}
finish // odlesky na povrchu
{
phong 1.0
}
}
}
#declare i = i + 1;
#end
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Obrázek 13: Snímek získaný v první třetině animace.
Obrázek 14: Snímek získaný ve druhé třetině animace.
7. Obsah dalšího pokračování seriálu
V následující části seriálu o raytraceru POV-Ray si ukážeme, jakým způsobem je možné použít spline funkce pro tvorbu pokročilejších animací, ve kterých se pohybující objekty také natáčí v trojrozměrném prostoru, podobně jako letadlo. Většina výpočtů bude založena na makru Spline_Trans, jehož definice je uložena v souboru transforms.inc dodávaném spolu s POV-Rayem. Na následujících dvou obrázcích je ukázka použití tohoto makra. Zjednodušené modely letadel se pohybují po cestě definované kubickou spline křivkou, přičemž dochází i k jejich natáčení, nikoli pouze k jednoduchému posunu.
Obrázek 15: Pohled na scénu, ve které se modely letadel pohybují po spline křivce.
První obrázek představuje pohled na celou scénu z pevného bodu (kamera nemění svoji pozici); při renderingu druhého obrázku se kamera nacházela přímo před kabinou jednoho z letadel a pohybovala se současně s tímto objektem. Spline křivka definující trasu letadel je vykreslena pomocí na sebe navazujících úzkých válců. V místě spojů těchto válců jsou navíc umístěny kuličky se stejným poloměrem, jaký mají i válce, aby při napojování nevznikaly mezi válci nežádoucí mezery.
Obrázek 16: Stejná scéna, ovšem sledovaná z kabiny jednoho letadla.