Realistické zobrazení tryskající kapaliny

Vít Strádal,


Realistické zobrazení tryskající kapaliny za pomocí částicového systému. Popsány jsou způposby simulace kapaliny, slévání, vlnění hladiny, zobrazení částic.

1. Úvod

1.1 Motto

Odvahu. Odvahu do života. Nic víc.

-- František Křižík

1.2 Inspirace

Inspirací této práci bezesporu je Křižíkova fontána na pražském výstavišti. Tajným přáním bylo udělat si takovou malou vlastní virtuální fontánu.

Křižíkova fontána byla vybudována u příležitosti jubilejní výstavy v roce 1891 a její současná podoba vychází z rekonstrukce uskutečněné o sto let později. Je bez nadsázky evropským unikátem. Efekt produkce fontány zajišťuje množství vodních okruhů ovládaných padesáti čerpadly a zakončených téměř třemi tisíci trysek. Barevné efekty vytváří 1248 podvodních reflektorů různých barev, které mohou docílit široké škály barevných odstínů. Bazén má rozměry 25x45 metrů a pojme na 1650 kubických metrů vody. K dalším zajímavostem patří, že rozvod vody nerezovým potrubím měří přes dva kilometry. Ozvučení zabezpečuje 55 elektroakustických zářičů. Program fontány je řízen počítačem.

Přilehlé stěny okolních pavilonů byly architektonicky a stavebně pojaty jako amfiteátr pro více než 6 000 diváků, další mohou sledovat program z ochozů na střechách Křižíkových pavilónů.

1.3 Členění práce

Teoretická část

Tato kapitola je věnována teoretickému pozadí této diplomové práce. Jsou zde popsány způpsoby simulace kapaliny, slévání kapek, vlnění hladiny, zobrazení kapek. Také je zde stručně popsaná práce J. S. Millera zabívající se podobnou tematikou.

Jazyk pro popis scénáře fontány

Pro popis scénáře byl vyvinut jednoduchý jazyka JA (Jazyk animace). V této kapitole je tento jazyk podrobně popsán spolu s uvedením příkladů. Je zde i velmi stručný popis preprocesoru cpp, který se požívá k předpracování jazyka.

Uživatelská dokumentace programů

Výsledkem této diplomové práce je vlastně soustava programů, které z popisu scénáře vytvoří animaci. V této části jsou popsány programy z uživatelksého hlediska formou velmi podobnou unixovým manuálovým stránkám.

Programátorská dokumentace

V této části jsou popsány rozhraní jednotlivých modulů a stručný náhled do datových struktur.

Závěr

Zhodnocení dosažených výsledků.

Obsah přiloženého CD

Výsledné obrázky, animace a screenshoty jsou na přiloženém CD. Struktura adresářů je poměrně přehledná, ale přesto je tu tato drobná kapitolka, která ulehčí hledání těchto výsledků.

Několik málo ukázek, Poděkování, Literatura

Názvy těchto kapitol mluví samy za sebe.

2. Teoretická část

V této části je vysvětleno teoretické pozadí diplomové práce. Jsou zde popsány způpsoby simulace kapaliny, slévání kapek, vlnění hladiny, zobrazení kapek. V závěru je krátky výtah z práce J. S. Millera, který se zabýval podobnou tématikou.

2.1 Cíle

Celkově

Cílem bylo udělat systém, který by jednoduchým způsobem popisoval ``choreografii'' fontány. A tuto ``choreografii'' pak zpracovat až po výslednou animaci.

Zároveň zde byla možnost, že by program mohl být použit při návrhu nových fontán podobného typu. Nešlo by o nějaké testování parametrů fontány, ale spíše o prezentaci.

Hudba

Původní inspirace si přímo říká o to, aby do prostředků jazyka byly přidány prostředky pro práci s hudbou. Nicméně tomu tak není. Je sice možné synchronizovat scénář s nějakými konkrétními časovými okamžiky, ale již například nelze zahrnout zdroje hudby přímo do scény.

Zadání scénáře

Aby vůbec mohla proběhnout simulace tryskající vody, bylo třeba navrhnout a implementovat popis celé situace (scénář animace).

Pro tento účel byl navrhnut a vyvinut jazyk scénáře JA. Od jazyka scénáře se očekávalo, že bude schopen vyjádřit spojité chování určitých veličin v čase.

Popis scénáře musí zvládnout popis rozmístění trysek, světel a kamery. Nejen jejich rozmístění, ale i změnu jejich vlastností jako je například poloha. U trysky je to dále směr a síla vodního proudu. U světel barva. A tak dále.

Dalším prvkem popisu scénáře jsou tzv. pohlcovací plochy (vodní hladiny). Ty určují místo, kde kapky ``mizí''.

Díky poměrně unifornímu přístupu k těmto objektům je možné, aby se tyto plochy taktéž pohybovaly a měnily velikost a polohu. Nicméně tato vlastnost nevypadá příliš využitelně.

Od popisu scénáře se naopak neočekává, že by definoval objekty scény. Scéna je přidána až při závěrečném raytracingu.

Dá se očekávat, že v animaci se nemusí pohybovat pouze předměty zájmu simulace (tedy trysky, světla, vodní plochy, kamera), ale i jiné blíže nespecifikované. Proto jazykem popisu scénáře můžeme definovat proměnné (typu vektor) a jejich případný pohyb, bez nějakého konkrétního významu v simulaci. Tyto ``propašované'' proměnné budou parametry konkrétního popisu scény.

Původní budovatelský nápad vytvořit i ``intuitivně'' ovládaný grafický editor pro editaci scénáře se ukázal být nad rámec rozsahu diplomové práce.

Provedení simulace

Největší váha však spočívá na provedení simulace. Zobrazení tryskající kapaliny byl tak trochu krok do neznáma, neboť v době počátku této práce nebylo známo, že by se někdo přímo tryskající vodou zabýval. Blíže viz kapitola teo_jini .

Cílem tedy bylo vymyslet nějaké přístupy a tyto vyzkoušet a porovnat.

Pro simulování kapaliny byl zvolen částicový systém. Jde o to, že celá kapalina je reprezentována mnoha částicemi (v tomto případě jim říkejme ``kapky''). Tyto kapky se v diskrétních krocích pohybují dle ``nějakých'' pravidel.

Mezivýsledná forma

Pro uchování výsledku simulace byl vyvinut formát buran. Jde o velmi prostý binární formát, ve kterém se ukládají informace spočítané simulací. Poněvadž simulace probíhá v diskrétních krocích, je přirozené, že informace se uchovají po framech (jako by po políčkách filmu). V každém framu je možné uchovávat různé typy informací.

Ty nejzajímavější typy informací jsou: polohy kapek, logovací informace, čas, stav trysek, světel, kamery, pole výchylek poloh hladiny (vlnky) atd.

Preview

Je jasné, že spočítat výslednou animaci je časově náročné (o mnoho náročnější než provést samotnou simulaci). Proto se jevilo účelné vytvořit velmi jednoduchý 3d prohlížeč mezivýsledků -- xburan.

Tento prohlížeč pracuje nad mezivýslednou formou buran. Poskytuje pouze základní nadhled na vygenerovanou simulaci. Kupříkladu kapky jsou nahrazeny body, hladina pouhým obdélníkem a podobně.

Prohlížeč umožňuje procházet scénou v prostoru i v čase, zvětšovat detaily, sledovat scénu z pohledu kamery.

Zobrazení

Samotný výsledek simulace by nebyl nikterak zajímavý, pokud by nebyl nějakým vhodným způsobem realisticky zobrazen.

Celý systém simulace kapaliny je koncipován tzv. ``offline''. To znamená, že autor zadá scénář a nějakou dobu si počká, než se mu ukáže výsledek. Proto je možné použít rekurzivní sledování paprsku (raytracing), které umožňuje velmi věrné zobrazení, nicméně je časově náročné.

Jednou možností by bylo imlementovat vlastní raytracer. Aby scéna nebyla sestavena pouze z tryskající vody, světel a hladiny, bylo by jistě nutné do tohoto zobrazovače implementovat alespoň základní typy objektů, textur a popřípadě i nějaké urychlovací metody a spoustu dalších vlastností.

Ačkoliv imlementace jednoduchého raytraceru není složitá, byl zvolen jiný přístup. Pro závěrečné zobrazení byl vybrán již hotový raytracer povray.

To mělo několik důvodů. Jednak v povray je implementována velká spousta vlastností. Jejich výčet by byl dlouhý, ale stručně by se dalo říci, že to jsou všechny základní metody rekurzivního sledování paprsku. Implementace v takovém rozsahu by zřemě nebyla jednotlivcem zvládnutelná.

Dále povray je ``živý'' program a to zvláště díky tomu, že je vyvíjen podle Open Source Society modelu. To znamená, že zdrojové texty jsou volně šiřitelné a v podstatě každý, kdo má chuť něco přidat či vylepšit, může ``přispět svou troškou do mlýna''.

Jinak celý systém není však tak závislý na povray. Pro výstup do jiného zobrazovacího programu by se dal zařídit drobnou upravou programu job. Viz kapitola prog_job .

Modularita celého systému

Celý systém je rozložen do mnoha menších utilitek podle unixového hesla: každý program ať dělá pouze málo, ale ať to dělá dobře.

Cesta od scénáře scény k výsledné animaci vypadá zhruba takto: Nejprve je jazyk popisu scény (JA) převeden do ``nižšího jazyku'' A. Následuje zpracování simulace (jmv) jejímž výsledkem je soubor formátu buran. Ten je možné prohlížet xburan'em nebo job'em převést do popisu povraye. Pro paralelní spočítání výsledné animace poslouží soustava scriptů dish-*. Jednotlivé obrázky se pak dají dohromady nějakým standardním konverzním programem (zde se osvěčil mpeg_encode).

Blíže k popisu utilitek viz kapitola uziv .

2.2 Použité postupy při simulaci

Reprezentace kapaliny

Pro reprezentaci kapaliny byl použit částicový systém. Jde vlastně o to, že kapalina je nahrazena jakýmisi makromolekulami. V následujícím textu jim budeme říkat familiárně kapky.

U každé kapky se uchovávají tyto informace: poloha, rychlost a hmotnost.

Makromolekuly se pak pohybují v diskrétních krocích. Pravidla, podle nichž se určí následující stav celého systému, jsou dána použitým matematickým modelem.

Částicový systém se jeví přirozený pro reprezentaci tryskající kapaliny, i když jsou možné i jiné přístupy.

Život kapky

Každá kapka v průběhu simulace projde jistým vývojem. Nejprve je vytvořena v místě ústí trysky.

Poté je s ní pohybováno na základě použitého matematického modelu. Při použití některých modelů se kapka může rozpadnout na více kapek, či více kapek se může slít v jednu větší.

Pokud kapka narazí na vodní hladinu, její ``život'' tímto končí.

Gravitační model

Gravitační model je prostým vyjádřením faktu, že celá simulace probíhá v gravitačním poli. K určení polohy a rychlosti je použita Eulerova metoda:

v = g t + v 0

s = (1/2) g t 2 + v 0 t + s 0

kde
s je nová poloha,
v je nová rychlost,
s0 je původní poloha,
v0 je původní rychlost,
g je tíhové zrychlení (0, -9.8, 0),
t časový krok.

V každém kroku simulace se tyto vztahy aplikují na každou kapku.

Model hrubého odstrkování

V předcházejícím modelu se nebralo do úvahy žádné vzájemné působení ani vzájemná poloha kapek. Kapalina je za normálních okolností těžko stlačitelná.

Tento model se to snaží řešit velice jednoduchým způsobem. Řekněme, že kapky vyžadují určitý odstup. Pokud jsou blíže než daný odstup, snaží se druhou kapku ``odstrčit'' do příslušné vzdálenosti. Získáme tedy ``odstrčenou'' polohu kapky. Pokud je konfliktních kapek více, výslednou polohu kapky dostaneme aritmetickým průměrem všech ``odstrčených'' poloh. sod = (1/n) Σk sk + norm( s0 - sk) Dk,od

kde
Dk,od je minimální distance(odstup) kapek k a od ,
sod je nová poloha kapky,
s0 je původní poloha kapky,
k jsou kapky které jsou blíže než Dk,od
n je jejich počet,
sk je původní poloha kapky,
norm() normalizace vektoru na jednotkový vektor.

Distance Di,j se určí dle vztahu: Di,j= K (ri + rj)

kde
ri, rj jsou poloměry kapek i a j.
K je konstanta určená experimentálně a dá se zadat jako parametr scénáře. Dobré výsledky jsou s hodnotami něco pod 1. Vyjadřuje vlastně, jak moc dovolíme kapkám se překrývat.

Model silového odstrkování

Předcházející přístup má několik modifikací a pokusných vylepšení. Jedním z nich je model silového odstrkování.

Myšlenka je taková, že nezměníme přímo polohu kapky, ale udělíme jí zrychlení, které ji ``odstrčí'' do příslušných mezí.

Jelikož simulace je dosti hrubá, nevyplatí se fyzikální molekulový přístup, neboť kapky se mohou celkem ``beztrestně'' dostat do velké blízkosti, kam by se ve spojitém případě nikdy nedostaly, protože odpudivá síla blízkých molekul je velmi velká. Pokud se kapky dostanou skokem takto blízko, jsou pak v souladu s fyzikálními zákony ``katapultovány'' velkou silou od sebe.

Proto bylo vhodné použít nějaký umírněnější model než fyzikální. Tento vychází z modelu hrubého odstrkování kapek. Místo odsunutí kapky na vzdálenější místo je kapce uděleno zrychlení, které by ji na toto místo dostalo z klidu za časovou délku kroku simulace.

Z uděleného zrychlení se v následujícím kroku spočítá nová poloha a nová rychlost.

Zrychlení udělené kapce je tedy:

aod= (2 sod/Δt2od)

kde
aod je udělené zrychlení,
sod je ``odstrčená'' poloha dle modelu hrubého odstrkování,
Δtod je časová délka kroku.

Dělení kapek

Dalším přístupem poněkud z jiné strany je dynamické zjemňování počtu částic.

Zde je použito velmi jednoduché pravidlo: pokud dosti daleko od kapky není žádná jiná kapka, rozděl ji na několik menších.

Toto jednoduché pravidlo má několik nejasných míst. Jedno z nich je ``dosti daleko''. Tedy jak určit vzálenost, kdy je kapka ``vhodná'' pro rozdělení. V našem případě bylo použito toto pravidlo: kapka se rozdělí, pokud žádná z ostatních kapek není blíže než volitelná konstanta. Tato konstanta je řádově centimetry.

Další problém je, jakým způsobem kapku rozdělit. Je zde opět mnoho možností.

Jednou z nich je kapku nahradit čtyřmi kapkami stejného poloměru, jejichž středy jsou ve vrcholech pravidelného čtyřstěnu. Základna je ve směru rychlosti kapky. Poloměry kapek jsou voleny tak, aby souhrnný objem kapek byl zhruba stejný jako objem původní kapky. Tj: r= &sqrt;(4)R, kde r je nový poloměr kapky, R je poloměr původní kapky.

Polohy středů jsou:

K0 = ((&sqrt;(6)/4), 0, 0 ) dist       K1 = (-(&sqrt;(6)/12), (&sqrt;(3)/3), 0 ) dist K2 = (-(&sqrt;(6)/12), -(&sqrt;(3)/6), (&sqrt;(3)/4) ) dist       K3 = (-(&sqrt;(6)/12), -(&sqrt;(3)/6), -(&sqrt;(3)/4) ) dist

kde
dist je vzdálenost středů nových kapek.


Uspořádání středů rozdělené kapky.


Rozdělení kapky, nárys.

Vztažná soustava je volena tak, aby osa x splývala s vektorem rychlosti původní kapky.

dist= vnor (r/2). Kde vnor je konstanta, vyjadřující jak moc chceme, aby se nové kapky překrývaly. Pro hodnotu vnor=1 se kapky budou dotýkat. Pro hodnoty nižší se budou kapky prolínat.

Další možnost dělení kapky je motivována tím, aby tvar kapek po dělení alespoň vzdáleně přípomínal letící kapku. Vzniknou čtyři větší kapky s poloměrem r=(1/2)(&sqrt;(3) - 1) 3 R) a dvě menší kapky s poloměry r4=(1/6)(&sqrt;(3) + 1)r a r6=(1/2). Středy budou mít následující souřadnice:

K1 = r (0, (2&sqrt;(3)/3), 0 ) K2 = r (0, - (&sqrt;(3)/3), (1/2) )       K3 = r (0, - (&sqrt;(3)/3), -(1/2) )       K5 = r (- (2&sqrt;(6)/3), 0, 0 )

Malé kapky pak:

K4 = r (- (2&sqrt;(3)/3)+(1/2), 0, 0 )       K6 = r (- (2&sqrt;(6)/3) -(3/2) , 0, 0 )

Proč byly polměry a polohy středů zvoleny takto, je snad celkem zřejmé když se podíváme na obrázek č. 3.


Uspořádání složitějšího dělení kapky

Také je vhodné zajistit, aby příliš malé kapky nebyly dále děleny. Přičemž ``příliš malé'' bylo zvoleno řádově desetiny milimetru. I když obavy z ``přemnožení'' kapek jsou celkem neopodstatněné, protože kapky vzniklé touto metodou se drží celkem pospolu.

Vznik kapek

Kapky vznikají v trysce. Generují se na počátku každého kroku simulace. Tryska v určitém časovém okamžiku je zadaná těmito parametry:
Poloha s,
směr p (normalizovaný),
rychlost vytékání kapaliny na počátku kroku v0,
rychlost vytékání kapaliny na konci kroku vT,
poloměr R,
rozptyl ro,
tření trysky.

Mimo parametry trysky záleží generování kapek na hustotě kapek ρ.

Navíc si označme průřez trysky P (= π r2). A pro přehlednost Δv=vT - v0.

Objem kapaliny, která proteče v časovém intervalu <0,t> tryskou: Rychlost kapaliny byla lineárně interpolovaná mezi krajními hodnotami tedy v(t)=v0 + Δv (t/T).

V(t) = ∫0t S v(t) dt = S [ v0 t + (1/2) t Δ v (t/T) ] 0t = S ( v0 t + (Δv t 2/2T) )

Pozn: správně bychom měli počítat s S(t), ale přepokládejme, že se průměr trysky nemění.

Speciálně pro t = T:

V = S T (vT - v0/2)

Počet vygenerovaných kapek, pak bude

n = V ρ

Poloha kapky je zvolena přirozeným způsobem: náhodný bod z průměru trysky.

Rychlost kapky

vk = vr + randk()rozptyl;

kde ro rozptyl trysky, randk() je náhodný vektor z jednotkové koule, vs je střední rychlost kapaliny ve vzdálenost r od osy trysky.

Závislost střední rychlosti na vzdálenosti od osy trysky je:

vr = ( 1 - (r2/R2) ) v

kde v je střední rychlost v ose trysky. R je poloměr průřezu trysky.

Každé kapce přiřadíme čas, po který se od počátku kroku ``jako'' pohybovala. Je třeba vygenerovat náhodný čas t (tk v intervalu <0,T> s distribuční funkcí V(t). (funkce randf() vrací náhodné číslo <0, 1> s normální distribucí).

Pro tento čas musí platit:

randf() V = V(t)

a dosazením a zkrácením S:

0 = - randf() T (v0 + vT/2) + v0 t + (Δ v /2T)t2

vyjádříme t:

t = (T/Δv) ( - v0 + &sqrt;( v02 + 4 (Δv/2T) randf() T (v0 + vT/2)) ) = (T/Δv) ( - v0 + &sqrt;( v02 + (vT2 - v02) randf()) )

Toto je čas, po který se právě vygenerovaná kapka bude pohybovat jaksi mimo simulaci (za použití pouze gravitačního modelu).

Zánik kapek

Kapky zanikají, pokud dopadnou na tzv. pohlcovací plochu. Přičemž kapka ``dopadne'' právě když spojnice polohy kapky s polohou v předcházejícím kroku simulace se s pohlcovací plochou protíná.


Zánik kapky.

Kapka pak bez jakéhokoli následku pro okolí zmizí.

Vlny na vodní hladině

Po dopadu vody na vodní hladinu se tvoří vlny. To lze reprezentovat tak, že každá kapka vytvoří zdroj vlnění, který pak přispívá k výchylce v každém bodě hladiny.


Ilustrativní obrázek k popisu vlnění

Výchylka v konkrétním bodě hladiny pak je:

y = Σz δ(dz,tz) yz sin ( 2 π (dz/λ) - 2 π (t - tz) ) adz bt - tz

kde z jsou všechny zdroje,
t je současný čas,
tz je čas vzniku zdroje z,
dz je vzdálenost od zdroje z,
yz je amplituda zdroje.
f frekvence vlnění.
λ vlnová délka,
u vzdálenostní útlumová konstanta (kolikanásobně se zmenší amplituda na 1m),
v časová útlumová konstanta (kolikanásobně se zmenší amplituda za 1s),
δ(dz,tz) je 0 pokud dz < (λ tz/p) 1 jinak.

Tato rovnice je pouhým optickým přiblížením skutečnosti a nedělá si právo na nějakou hlubší fyzikální opodstatněnost.

Konstanty byly určeny odhadem a pozorováním skutečné hladiny.

Jednoduchou úpravou tohoto výrazu můžeme separovat od sebe složku závislou na čase a složku závislou na zdroji. V jednom místě hladiny si stačí pamatovat dvě čísla (``sinovou'' a ``cosinovou'' složku). Přidání dalšího zdroje pouze tyto složky upraví. Nemusíme tedy v každém časovém okamžiku procházet všechny zdoje vlnění.

y = u t ( sin( αt) Σz cos( βz) - cos( αt) Σz sin( βz) )

kde
αz = 2 π t f je závislé pouze na čase t,
βz = 2 π ( (dz/λ) + tz f) je závislé pouze na zdroji z.

Pro pevně zvolený bod vodní plochy pak je suma konstantou, což výrazně urychlí počítání výchylky v tomto bodě.

Nové zdroje pouze přispějí každému bodu do jeho ``sinové'' a ``cosinové'' složky. Je třeba však mít na paměti, že vlnění se šíří od zdoje konečnou rychlostí, a proto není možné započítat tyto složky okamžitě při vzniku vlnění pro všechny body plochy, ale započítávat je tak, jak se vlnění postupně šíří.

Vlhkost vzduchu -- ``mlha''

Toto je další vlastnost (podobně jako vlnky na vodní hladině), která se samotným zobrazením tryskající kapaliny nemá mnoho společného a byla přidaná pouze pro ``přirozenější'' vzezření výsledku.

U skutečné fontány (pokud je vyšší vlhkost vzduchu) dochází k vytvoření vodní mlhy. V našem případě je mlha reprezentována následovně.

Celý prostor je rozdělen na malé ``buňky'' (krychličky o velikosti řádově mm3). Každá buňka má určitou vlhkost. Pokud buňkou proletí kapka, její vlhkost se zvýší na maximum. Pak tato vlhkost s postupem času klesá.

Díky jednoduchosti implementace byl přidán i vliv větru. Jde vlastně pouze o to, že vlhkost se distribuuje do okolních buněk v poměrech daných rychlostí a směrem větru.

2.3 Slepé uličky

Na pověstné prohledávání slepých uliček byla tato práce poměrně bohatá. Někdy však ono ``tudy cesta nevede, přátelé'' bylo vyřčeno příliš brzy a později se ukázalo, že navržený postup není zas až tak nepoužitelný.

Molekulový model

Nejprve se zdálo, že bude výhodné použít molekulový fyzikální model. Molekuly na sebe působí přitažlivou silou klesající se čtvrtou mocninou vzdálenosti a odpudivou silou klesající s šestou mocninou vzdálenosti.

Vynořily se však následující problémy. Simulace vykazovala vysokou míru numerické nestability. Zvláště v situacích, kdy mělo dojít ke kolizím kapek.

Ač byl časový krok simulace dosti malý, molekuly, které se ``chystaly'' do sebe narazit, se dostaly ``skokem'' do míst, kde byla odpudivá síla velmi velká. V následujícím kroku pak byly odmrštěny doslova první kosmickou rychlostí.

To se dalo řešit dostatečným zkrácením délky časového kroku. Čas simulace se pak pochopitelně prodloužil.

Tento model (bez gravitačního modelu) byl testován na vzorku zhruba 100 částic, původně rozmístěných v pravidelné čtvercové mřížce. Výsledkem byly částice zhruba uskupené do tvaru koule Částice vykonávaly chaoticky pohyb. Výsledek byl jako vystřižený z učebnice o Brownově pohybu (ovšem bez pylových zrnek).

Vypadalo to tedy, že oněch 100 částic je na reprezentaci kapky přiměřené množství, při řádově menším počtu by kapka působila poněkud neklidným dojmem.

Vzhledem k tomu, že pro simulaci tryskající vody fontány by bylo třeba řádově tisíce takovýchto ``kapek'', ukázal se tento přístup jako neúnosný. A to nejen paměťově, ale i časově (díky velkému počtu kroků způsobených numerickou nestabilitou).

Jazyk pro popis scény

Poměrně dlouhou dobu jsem se zabýval vývojem jazyka pro popis scénáře animace, který se nakonec ukázal jako velmi nevhodný.

Tento jazyk ovládal práci s objekty, garbage collector, mnohonásobnou dědičnost. Měl také upravenou syntaxi pro práci s časem.

Možná právě tyto vlastnosti způsobily, že jazyk se stával čím dál více složitý a čím dál méně přehledný a pochopitelný. Případného nového uživatele by zřejmě stálo dosti úsilí tento jazyk si osvojit.

Proto byl jazyk popisu scénáře nahrazen prostším, vcelku jasným jazykem JA.

Zvolený operační systém

Motto: Přechod je možný pouze jedním směrem -- programátorský žargon.

Na začátku byly utilitky diplomové práce vyvíjeny na MSDOSu. Jelikož utilitky nevyužívaly žádnou knihovnu specifickou pro tento systém, pokusil jsem se o přenos na platformu Linux. Když jsem zjistil, jak pohodlné pro programátora je na první pohled nehostinné prostředí Unixů, už jsem u tohoto platfomy zůstal a na MSDOS jsem zcela zanevřel.

2.4 Přístupy použité jinými autory

Nedostatek materiálu

Zdá se, že toto téma je v počítačové grafice poměrně opomíjené. Teprve na konferenci WSCG99 v Plzni byl referován příspěvek Jamese Millera ``Modelling Liquids using Particle Systems and Implicit Surfaces'' (Modelování kapalin s použitím částicového systému a implicitních ploch).

James S. Miller

Pro modelování kapaliny byl použit částicový systém. Jako matematický model byl použit jednoduchý gravitační model v kombinaci s molekulovým silovým modelem. Jelikož tento model dával očekávané výsledky, nebyl již nijak dále vylepšován.

Hlavní důraz je v práci kladen na zobrazení kapaliny. Pro výsledný tvar kapaliny jsou použity implicitní plochy.

Implicitní funkce ma tvar:

f(s)= Σi δ(R,di) ( (2 di3 /R3) - (3 di2 /R2) + 1 )

kde
δ(R,di) je 1 pokud di menší než R a 0 jinak.
di je vzdálenost od částice i ``vážená'' jeho hmotností.

Implicitní plocha daná touto funkcí, je pak množina bodů splňující f(s)=c.

Je vidět, že například jedna izolovaná částice vytvoří kouli.

Vyrovnání objemu

Blízké částice (tedy ty, které přispívají do jedné plochy) jsou spojeny do tzv. shluků. Je snahou udržet objem těchto shluků alespoň přibližně stejný, jaký by byl, kdybychom sečetli objemy všech izolovaných částic.

Tento požadavek je splňován modifikací konstanty c. Prostor okolo shluku se adaptivně rozdělí na malé krychličky, které se rozdělí na tři skupiny:uvnitř kapaliny, vně a na hranici. Pokud je objem příliš malý (či příliš nepřesný), modifikuje se konstanta c a pokračuje se v dělení krychliček. Takovýmto způsobem lze dosáhnout předem stanovené přesnosti zachování objemu.

Různé druhy kapalin

Systém taktéž umožňuje modelování více druhu kapalin. Kolize povrchů kapalin různých druhů je vyřešena ``vyvážením'' obou ploch kapalin.

Upravená implicitní funkce pak má tvar (fA, fB jsou původní implicitní funkce shluku A a B, FA je upravená implicitní funkce shluku A):

FA(z)=fA(z) v případě, že fB(z) <c

FA(z)= fA(z) + c - fB(z) jinak.

Kontakt s podložkou

Dalším problémem, kterým se J. Miller zabýval, je kontakt kapky s pevnou podložkou. Tedy jak upravit plochu částice, který by se měl dotýkat podložky.


Modifikace tvaru částice na podložce

Částice, jejíž plocha má průnik s podložkou(a), je nejprve zvětšena tak, aby byl zachován objem(b). Poté je plocha částice dvakrát zkosena. Nejprve ve směru kolmém k ploše(c) a podruhé ve směru tečném(d). Velikosti deformace jsou dány příslušnými složkami gravitace (tedy složkou kolmou a tečnou k podložce).

Shrnutí

Práce J. S. Millera předkládá tyto nové přístupy k modelování kapaliny: slévání a štěpení částic, interakce různých druhů kapalin, jednoduchá pravidla pro zachování objemu kapaliny a reakci s podložkou. Výsledný tvar kapaliny je dán implicitními plochami.

Počítání tvarů implicitních ploch (s vyvažováním objemu) je časově náročné a proto tento přístup lze použít pouze pro relativně malé soubory částic.

3. Jazyk pro popis scénáře fontány

Pro popis scénáře byl vyvinut jednoduchý jazyka JA (Jazyk animace). V této kapitole je tento jazyk podrobně popsán spolu s uvedením příkladů. Je zde i velmi stručný popis preprocesoru cpp, který se používá k předpracování jazyka.

3.1 Obecné vlastnosti

Popis scénáře je realizován jazykem A. Jazyk A umožňuje popis objektů scény v závislosti na čase. Objekty scény jsou trysky (poloha, směr, rychlost proudu, poloměr průřezu, rozptyl), světla (poloha, směr, barva, úhel kužele), pohlcovací plocha (poloha, rozměry), kamera (poloha, look_at, up), externí proměnné scény (vektor).

Chování např. trysky je zadáno (volně řečeno) po časových blocích. U každého bloku je určen počátek, délka trvání a co se v průběhu bloku děje. Tento děj může být popsán v podstatě libovolnou (rozumnou) funkcí. Tato funkce bude mít jako proměnnou čas. Při následné simulaci pak bude pro každý okamžik tato funkce vyhodnocena.

Omezením jazyka je, že počátky bloků musí být ve scénáři vzestupně uspořádány. Toto je velmi výhodné pro simulační program, neboť si nemusí udržovat v paměti celý scénář, ale pouze aktuální část. Nicméně pro autora tohoto scénáře je to naopak velmi nevýhodné, zvláště při ladění pohybů několika nezávislých objektů. Například pokud máme celý scénář fontány již hotový, jen bychom rádi upravili pohyb kamery.

Proto zde vznikl velmi prostý jednoduchý ``přeuspořádávač'', jazyk JA. Ten umožňuje nesekvenční popis scény a jeho úkolem je pouze tyto bloky uspořádat. Výstupem je pak korektní kód jazyka A.

Pro větší pohodlí autora scénáře přibyla ještě preprocesová fáze. Díky preprocesoru cpp je možné rozdělit nezávislé části scénaře do více souborů. S tím se ``svezly'' i všechny ostatní vymoženosti cpp jako jsou definování maker, podmíněný překlad atd.

3.2 Popis jazyka A

Jde o zásobníkový jazyk a může velmi vzdáleně připomínat Postscript. Všechny příkazy jsou jako by v obrácené polské notaci (postfixové formě). To znamená, že nejprve je výčet argumentů a až po nich následuje funkce (operátor).

Syntaxe

fce
  : argumenty fce_id
  ;

argumenty
  : seznam
  | fce
  | proměnná
  | číslo
  | vektor
  | řetězec
  ;


seznam
  : '[' příkaz ']'
  ;

číslo

double

vektor

ve tvaru (x y z) např.: (1.2 0 -15).

proměnná

$p, $q, $t, $e, $1, $2, ... $9 vestavěné proměnné, bližší popis viz níže.

řetězec

něco v uvozovkách např: "fce2".

Jak je vidět, syntaxe je opravdu jednoduchá.

Sémantika

Číslo, vektor, řetězec anebo proměnná uloží svou hodnotu na zásobník, fceN vezme posledních N položek zásobníku a výsledek opět uloží na zásobník. Mnemotechnika názvu funkcí je taková, že poslední znak názvu vyjadřuje árnost funkce.

Vestavěné aritmetické funkce

add2, sub2

sčítání, odčítání. Příklad: 1 3 add2.

smul2, div2

násobení, dělení vektoru skalárem. Příklad (1 2 3) 4 div2.

norm1, abs1

normalizace, velikost vektoru.

Příklad

(1 0 1) (0 1 0) add1 2 div2 norm1 abs1

sečte (1 0 1)+(0 1 0), výsledek vydělí dvěma, to celé znormalizuje a velikost tohoto vektoru bude výsledek.

Poznámka

číslo je chápáno jako vektor s ostatními složkami nulovými nebo nedefinovanými. Takže 1 (0 1 1) add1 má stejný význam jako (1 0 0) (0 1 1) add2.

a b t umer3

vážený průměr bodu a a b tj. t * b + (1 - t ) * a

a pa d pd t spline5

bod určený řídícími body a a b vektory pa a pd v čase t.

a pa d pd t vspline5

tečna v tomto bodě.

Definování vlastních funkcí

[ tělo_fce ] "mojefceN" def2

definuje N-ární funkci mojefceN. K argumentům funkce lze přistupovat pomocí proměnných $0, $1, $2, ... $9. Proměnné se číslují podle hloubky v zásobníku.

Příklady

[ $0 1 add2 ] "divny_inc1" def2

definuje funkci my_inc1, která přičte k argumentu 1.

5 my_inc1

vrátí tedy 6.

[ $2 $1 add2 $0 sub3 ] "divny_prumer3" def2

definuje funkci my_prumer3, který sečte dva vektory a podělí číslem. Tedy:

(6 3 3) (6 0 0) 3 divny_prumer3

vrátí (4 1 1).

Funkce pro sázení objektů scény

"id" p0 p1 r v ro vl try7

id název trysky, p0 pozice trysky, p1 směr, r poloměr, v rychlost vytékání, vl vlastnost trysky (pro budoucí využití)

"id" p0 p1 rgb rad sve5

id název, p0 pozice, p1 směr, rgb barva světla, rad kužel.

"id" eye lookat up kam3

id název, eye pozice kamery, lookat kam kouká, up kde je ``nahoře''.

"id" vec "dfn2"

umožňuje měnit nějaký parametr scény.

Poznámka

výhodné je přidefinovat si stručnější funkci:

[ "hlavnitryska" (0 0 0) (0 1 0) .01 $0 0.1 0 try7 ] "hlavnitryska1" def2

Časové funkce

TT čas1

posune čas na TT, čas se musí posouvat pouze vpřed.

[ tělo intervalu ] LEN int2

tělo intervalu se provede vždy, když se bude chtít zjistit vzhled scény v časovém intervalu <TT, TT + LEN). S výhodou lze použít vestavěné proměnné $t, $p, $q.

TT end1

čas konce.

Vestavěné proměnné

$t

čas od začátku intervalu;

$e

délka intervalu

$p

normalizovaný čas ( $t / $e )

$q

( 1 - $p )

Funkce pro vnitřní nastavení

kncm1

počet kapek na centimetr krychlový.

3.3 Ilustrativní příklad v A

Zde je jednoduchý příklad jazyka A. Definuje scénu s jednou kamerou a jednou tryskou.

Tryska začíná tryskat. V čase 0.5 chvíli tryská stejně, v čase 1.5 proud začne zesilovat a v čase 4.5 dosáhne vrcholu. Pak tryska přestane tryskat.

Kamera nejprve trysku sleduje z jednoho místa a v čase 1.0 ji začne objíždět.

; tryska "T" 
;
; id  p0      p1      r    v  ro   vl
[ "T" (0 0 0) (0 1 0) 0.01 $0 0.01 0  try7 ] "T1" def2
; camera "ocko"
;  id     eye look up
[ "ocko"  $1  $0   (0 1 0) kam4 ] "ocko2" def2
;začneme časem 0.0
0.0  cas1
  ; tryska T začíná tryskat 
  ; na začátku tryská rychlostí 0 na konci rychlostí 1
  ; interval končí v čase .3
  [ $p  T1 ] .5 int2
  ;kamera "ocko" to z povzdálí sleduje
  [ (-1 0 0) (0 0 0) ocko2 ] 1 int2
;posuň čas
0.5 cas1
  ;tryska chvilku tryská stejně  a to rychlostí 1
  [ 1 T1 ] 1 int2
  ;kamera objíždí trysku, ale stále sleduje T
  ; přesune se z místa (-1 0 0) na (0 0 1) za 3s 
1.0 cas2
  [
    ; nejprve spočítáme polohu kamery
    (-1 0 0) (0 0 1) (0 0 1) (1 0 0) $p spline5 
    ;kouká se stále na T
    (0 0 0)  ocko2 
  ] 4 int2
  ;další bod scénáře: tryska zesílí z 1 na 5 za 3 sec
1.5 cas1
  [ 1 5 $p umera3 T ] 3 int2
4.5 cas1
  ;a pak rychle přestane tryskat úplně
  [ $q 5 mul2 T1 ] 0.1 int2
;v čase 5s již skončíme
5.0 end2

3.4 Popis jazyka JA

Jak bylo řečeno výše, omezením jazyka A je, že počátky bloků musí být v souboru uspořádany vzestupně.

Proto byl navrhnut jazyk JA, který je jakýmsi přerovnávačem bloků jazyka A.

Syntaxe

Základní stavební jednotkou je časový blok (dále jen blok). Bloky je možné vnořovat. Blok má počátek a délku trvání.

t + dt TĚLO_BLOKU/

Blok má počátek v čase t od počátku nadbloku a délka jeho trvání je dt. Pokud není uvedené t, blok začíná v čase, kdy skončil předcházející blok, pokud není uvedeno dt, má blok délku 0 .

TĚLO_BLOKU může mít jeden z těchto dvou tvarů:

 { seznam_podbloků }

 [ fce_jazyka_a ] 

Přerovnávač spočítá počátky všech atomických bloků, setřídí je.

Hrubé kopírování

Mimo bloky lze v přerovnáváči mít úseky, které se beze změn vloží do výsledného .a souboru. To je výhodné pro definice a deklarace objektů scény. Zkrátka pro ``věci'' globální, nezávislé na čase.

Zkopírovano bude to co bude uzavřeno mezi %{ a `%}. (podobně jako ve flexu či bisonu).

Příklad:

%{
; kód v A, který bude beze změn zkopírován do .a
%}

3.5 Ilustrativní příklad v JA

příklad z popisu jazyka A bychom mohli přepsat takto:

%{
; toto bude beze změn zkopírováno do .a
; pro pohodlnější použití si přidefinuji funkci T1, které bude
; stačit jak rychle má tryska tryskat
; id  p0      p1      r    v  ro   vl
[ "T" (0 0 0) (0 1 0) 0.01 $0 0.01 0  try7 ] "T1" def2
; camera "ocko"
;  id     eye look up
[ "ocko"  $1  $0   (0 1 0) kam4 ] "K2" def2
%}
;nejprve  trysku
{
  ; tryska T začíná tryskat
  ; na začátku tryská rychlostí 0 na končí rychlostí 1
  ; interval konci v čase .3
  + 0.5 [ $p  T1 ]
  ;tryska chvilku tryská stejně a to rychlostí 1
  + 1.0  [ 1 T1 ]
  ;další bod scénáře: tryska zesílí z 1 na 5 za 3 sec
  + 3.0  [ 1 5 $p umera3 T ]
  ;a pak rychle přestane tryskat úplně
  + 0.1 [ $q 5 mul2 T1 ]
} ; konec trysky T1
; a nyní kamera
{
  ;kamera K to z povzdálí sleduje
  + 1 [ (-1 0 0) (0 0 0) K2 ] 
  ;kamera objíždí trysku, ale stále sleduje T
  ; přesune se z místa (-1 0 0) na (0 0 1) za 3s
  + 4 [
        ; nejprve spočítáme polohu kamery
        (-1 0 0) (0 0 1) (0 0 1) (1 0 0) $p spline5
        ;kouká se stále na T
        (0 0 0)  K2
      ]
}
; konec se vygeneruje automaticky
; 5.0 end2

Oč přehlednější, že?

3.6 Preprocesor cpp

Motivace

Preprocesor cpp byl použit z několika důvodů.

Hlavním důvodem je možnost vkládat soubory. Tím je umožněno rozdělit scénář na nezávislé části. Díky této modularitě jde lehce psát více různých scénářů pro stejnou fontánu, různé ``střihy'' téhož scénáře, nebo např. různá osvětlení téže ``choreografie''.

Dalším důvodem je možnost vytváření maker. To by se dalo využít například při spojení s hudbou tak, že bychom si ve zvláštním souboru definovali počátky zajímavých míst. Pro různé scénáře na stejnou hudbu bychom si pak nemuseli pamatovat čísla.

V neposlední řadě je to podmíněný překlad. To je vhodné například při ladění pouze částí scénáře. Zbytek scénáře může být dočasně vynechán.

Mimo jiné to byla i ``konstruktivní lenost'', neboli: ``Proč něco implementovat po tisícáté prvé, když je to již tisíckrát napsáno a lépe.''

Stučný popis

Jazyk makroprocesoru zajisté ovládá každý programátor v jazyce C či C++. Nicméně zajisté neuškodí stručný přehled.

Makroprocesor projíždí vstup a v podstatě jej kopíruje (trochu upravený) na výstup. Úprava spočívá v expadnování maker.

Chod makroprocesoru se dá řídit pomocí tzv. direktiv. Direktiva začíná vždy na novém řádku znakem `#'.

Popis jednotlivých direktiv

#define MAKRO HODNOTA_MAKRA

po tomto každý výskyt slova MAKRO bude nahrazen řetězcem HODNOTA_MAKRA. Například pokud definujeme

#define pes nejlepší přítel člověka

pak text

pes štěkal na pestrý koberec.

bude vyexpandováno následovně:

nejlepší přítel člověka štěkal na pestrý koberec.

Všiměte si, že pes ve slově pestrý nebylo expandováno.

#define pes(x) nejlepší přítel x

definování makra s parametrem. Text

pes(člověka) není pes(kočky).

bude vyexpandováno na

nejlepší přítel člověka není nejlepší přítel kočky.

#include "soubor"

na tomto místě bude vložen soubor soubor. Tento soubor taktéž projde makroprocesorem.

#ifdef PROMĚNNÁ

#endif

Pokud je deklarované makro PROMĚNNÁ, provede se makroproces i na blok končící endif. V opačném případě bude tento blok vynechán. Tyto direktivy lze vnořovat.

Makro procesor cpp má daleko více vlastností. Pro náš účel tento popis však stačí. Zájemci nechť se obrátí na info cpp, kde je velmi podrobný popis.

4. Uživatelská dokumentace programů

V této kapitole jsou popsány utility potřebné k vytvoření animace ze scénáře scény.

4.1 Stručný přehled

Než se ze scénaře v jazyku JA stane výsledná animace, musí projít poměrně dlouhou cestou. Následuje velmi stručný přehled této cesty.

Jazyk JA

Popis scénáře animace. Jeho výhodou je, že události ve scénáři nemusí být popsány v tom pořadí, jak jdou ve skutečnosti za sebou. Další výhodou je možnost použití preprocesoru jazyka C, který umožní rozložit scénář na několik nezávislých částí (např. popis poloh trysek, popis choreografie fontány, pohyb kamer). Utilitou ja se program převede do jazyka A.

Jazyk A

Toto je rovněž jazyk pro popis scénáře, jenže na nižší úrovni. Počátky událostí musí být ve scénáři tak, jak jdou časově za sebou. To je výhodné pro následující simulační část, která nemusí uchovávat v paměti celý scénář, ale stačí jí aktuální kousek.

Utilitka jmv

Hlavní hybný program. Podle nastavených parametrů provede simulaci. Výstup je ve formátu buran.

Formát buran

Jde o binární formát pro ukládání informací o animaci, která je již rozdělena na jednotlivé framy. V každém framu jsou pak informace o poloze kapek, vlnění hladiny či stavu světel nebo poloze některých pohyblivých předmětů. Tedy informace o věcech, které se ve scéně mění.

Utilitka jj

Všechny tyto výše zmíněné utilitky zastřešuje jj. Nedělá nic jiného, než že je ve správném pořadí spustí. Takže přímo z .ja souboru vznikne .bur.

Prohlížeč formátu buran xburan

Jednoduchý prohlížeč formátu buran. Jak název napovídá program je pro Xwindows.

Utilitka job

Pokud máme spočítanou animaci, je třeba ji nějak zobrazit. Tento program z formátu buran vezme konkrétní frame a vytvoří popis scény ve formátu povray'e. Tedy pouze jejích proměnlivých částí, statická část scény musí být připravena zvlášť.

Soustava scriptů dish

Pro urychlení počítání výsledné animace byla vytvořena soustava scriptů dish-*. Umožňuje současné počítání jedné animace na více počítačích. Nejde o žádný hlubokomyslný distribuovaný systém. Každý počítač vždy spočítá jeden obrázek a poté požádá o další.


Cesta scénáře až po výslednou animaci.

Popis obrázku č. 7

Obrázek č. 7 znázorňuje cestu cestu, kterou projde scenář a.ja než se zně jstane výsledná animace. a.jap -- scénář prošel preprocesorem cpp. a.a -- bloky jsou přerovnány tak, aby jejich začátky šly vzestupně za sebou. a.bur -- simulace je provedena, jsou známy polohy všech kapek, kamer, trysek atd. v každém framu, a-vl.bur z informací o kapkách dopadnuvších na hladinu jsou spočítany výchylky hladiny, a001.d.pov -- defince proměnných scény ve formátu povray, scéna.pov -- popis statické části scény, a001.t.pov -- popis kapek, kamer a světel ve formátu povray. a001.v.pov -- popis vodní hladiny. a001.t.tga -- bump textura vodní hladiny. a001.o.tga -- výsledný obrazek, a.mpg -- celá animace.

Čárkovaným obdélníkem je naznačeno pokrytí zastřešující utilitkou jj resp. soustavou scriptu dish-*.

4.2 jj -- zastřešující program j-utilit.

Stručný popis

Tento program řetězí za sebe vyvolání programů cpp, jja a jmv. Usnadní tedy průchod od popisu scény až ke spočítání každého jeho framu (ne raytracing).

Použití

jj [-h] [-pa] -oOutput.a input.ja  [ -- jmv-options ]

Popis

Programem jj se nejprve se input.ja provede přezpracování preprocesorem jazyka C -- cpp (ve skutečnosti se volá gcc -E -xc). Díky tomu může být scénář rozložen na několik nezávislých částí. Vytvořený soubor se jmenuje Input.ja.p. Poté se spustí jja, který vytvoří uspořádanou podobu scénáře. Název bude Output.a. Nakonec přijde na řadu jmv, které zadaný scénář odsimuluje. Mezivýsledky se nemažou.

Volby

Input.ja

Vstup. Implicitně a.ja.

-oOutput.a

Název uspořádaného scénáře. Implicitně a.a.

-p

Vytvoří soubor a.ja.p a skončí. Tedy provede pouze makro preproces.

-a

Vytvoří soubor a.a a skončí.

-h

Krátký přehled voleb.

4.3 jja -- přerovnávač jazyka A

Stručný popis

Jednoduchý přerovnávač jazyka A

Použití

jja [-i input.ja ] [-o output.a ]

Volby

-i input.ja

Soubor vstupu . Implicitně a.ja.

-o output.a

Výstup v jazyce A. Implicitně a.a.

Popis

Jazyk A má tu vlastnost, že události se musí popisovat tak, jak jdou za sebou (přesněji: jak jdou za sebou jejich počátky), a to i když jsou na sobě třeba nezávislé. To je sice výhodné pro pohybový program jmv, který nemusí udržovat v paměti celý scénář, ale nevýhodné pro autora scénáře.

Tuto nevýhodu odstraňuje právě tento přerovnávač. Zvlášť si můžeme definovat tryskání jednotlivých trysek, zvlášť pohyb kamery, osvětlení atd. Viz též kapitola jaz_ja .

4.4 jmv -- hlavní hybatelský program

Stručný popis

Hlavní hybatelský program. Simuluje pohyb vody dle nastaveného modelu. Výsledky ukládá ve formátu .bur.

Použití

jmv [-h] [-ofmvsn]  [ -i infile.a ] [-o outfile.bur]

Volby

-i intput

vstup ve formátu jazyka a. Implicitně a.a.

-o output

výstup ve formátu bur. Implicitně a.bur.

Volby pro řízení simulace

-m

Mlha. Použij model, který počítá i s tzv. mlhou.

-p

Kapky budou udržovat minimální vzájemnou vzdálenost.

-f

Silou. Minimální vzdálenost se bude udržovat dle modelu silového odstrkování.

-r

Vítr. mlha se posunuje v závislosti na vítru.

-v

Vlnky. Použij vlnění hladiny.

-s

Štěpení. Použij model, který použivá štěpení osamělých kapek na menší.

-d

Použij definice. Do výstupu zapisuj i informace typu define.

-n

Následující volba ne.

-h

Krátký přehled voleb včetně jejich implicitních hodnot.

Pro více informací o významu voleb viz. kap teo .

4.5 bured -- prohlížeč formátu buran

Stručný popis

prohlížeč formátu buran, formátu pro uchování informací o animaci na úrovni framů. Vhodné pro ladění programů, které formát buran mají produkovat (jchrl, jmv).

Použití

bured -fN  -bBEG -eEND file.bur

Volby

file.bur

soubor formátu buran, který má být znázorněn

-fN

Frame N. zobrazí se N'tý frame.

-bBEG

První zobrazovaný frame bude BEG.

-eEND

Poslední zobrazovaný frame bude END.

Formát buran

Formát buran slouží k uchování informací o animaci rozložené na framy. U každého framu animace je třeba si uchovat různé informace o scéně, např. polohy kapek, polohu a směr trysek, barvy světel. Proto jsou v každém framu bloky těchto informací, ve kterých se uchovává více informací stejného typu.

Typy bloku

POINTS

3d body.

POLYGON

Vrcholy polygonu.

LOG

Logovací informace.

CASTICE

Zrod kapky, poloha, rychlost. Pro rychlejší preview je výhodnější nepočítat polohy všech kapek, ale zapamatovat si pouze jejich zrod.

KOULE

3d bod a poloměr. Používá se pro pozici kapky.

CAMERA

Pozice ``look_at'' a ``up'' kamery.

VLNKY

Pole výchylek vodní hladiny.

DEFINE

Propašování hodnoty vektoru a identifikátoru do scény povray'e. V popisu scény se pak objeví něco jako ``#declare ID = <1, 2, 0>''.

Popis formátu výstupu

Pro každý blok ve framu se vytiskne nejprve hlavička s těmito informacemi: název typu bloku, číselně typ bloku, délka jedné datové položky, offset ve framu, počet datových položek, velikost v bytech.

Následuje výpis každé datové položky, na jeden řádek jedna. Výjimku tvoří bloky typu LOG a DEFINE, kde se vlastně celý blok vypíše na jeden řádek.

[tryska (8,  32)  242 2(64)]
`(0.00 0.10 0.00) (0.00 1.00 0.00)0.01
`(0.10 0.10 0.10) (0.00 1.00 0.00)0.01

4.6 xburan -- preview animace

Stručný popis

Program pro rychlé zhlédnutí spočítané animace. Umožňuje procházení scény, zobrazení jen některých komponent.

Použití

xburan [ input.bur ] 

Popis

Zobrazí animaci input.bur. Implicitně look.bur. Jak název napovídá, pro zobrazení jsou potřebné Xwindows. Z formátu .bur jsou podporovány tyto typy: KAPKA -- bílá tečka, druhé bloky (užívané pro mlhu), červená tečka. POLY -- modrý polygon, TRYSKA -- parabola od místa vzniku, až po průnik s rovinou xz, DEFINE -- žlutý ``motýl'' pro parametry scény.

Ovládání

Pohyb

h -- otáčení

j -- chod vzad

k -- chod vpřed

l -- otáčení vpravo.

H -- úkrok vlevo

J -- nahoru

K -- dolů

L -- úkrok vpravo.

u -- nahnutí dolů

i -- nahnutí nahoru

Posun animace

n -- následující

p -- předcházející

b -- počáteční

Zvětšování

+, = -- zvětšit

- -- zmenšit

Kamera

0 - 7 -- výběr kamery

8 -- nehýbat s kamerou dle popisu animace, zůstat na místě.

9 -- vytisknout pozici kamery na stdout. Ta se pak muže vložit do scénáře.

Ostatní

h -- help. Protože program je používán k ladění, dosti často je potřeba nová klávesa, help zobrazí aktuální funkce kláves.

q -- konec

4.7 jvl -- počítání povrchu hladiny

Stručný popis

Na základě informací o vyřazených kapkách spočítá pro každý časový okamžik pole výchylek vodní plochy. Vstup i výstup je ve formátu buran.

Použití

jvl [-fN ] [-bBEG] [-eEND] [ -i input.bur ] [ -o  outfile.pov ] 

Volby

-i input.bur

Soubor vygenerovaný jmv'em. Implicitně a.bur

output.pov

Výstupní soubor ve formátu povray.

-bBEG

Nastaví počáteční frame, od kterého se bude počítat. Předchozí zaniklé kapky však nebudou mít na výsledek vliv a proto dojde k chybě. Někdy je však třeba spočítat pouze část animace a pak stačí vzít do úvahy pouze několik předchozích framů, viz volbu -p. Imlicitní hodnota volby -b je 1.

-pPRE

Bere do úvahy PRE framů před BEG. Tyto framy budou odsimulovány, avšak výstup začíná až framem BEG.

-eEND

Nastaví, po který frame se mají vlnky počítat.

Mouchy

Je implementována pouze statická velikost vodní hladiny, ač měnit rozměry hladiny je v jazyce JA v zásadě možné. Hladina se sice může pohybovat, avšak velikost vodní plochy bude braná z prvního zpracovaného framu.

4.8 job -- transformace formátu bur do formátu povray

Stručný popis

Vytváří z popisu animace .bur popis scény jednoho framu

Použití

job [-fN ] [-kcn] [-vName] [ input.bur [ outfile.pov ] ]

Volby

Job vezme jeden obrázek formátu popisu animace a vygeneruje zdojový text pro povray.

input.bur

Soubor vygenerovaný jmv'em

output.pov

Výstupní soubor ve formátu povray.

-fN

Zobrazovaný frame číslo N.

-k

Kapky budou reprezentovány jako obyčejné koule.

-r

Blízké koule budou spojené válcem.

-n

Nezobrazovat kapky.

-c

Obalit barevně koule, spojující válce i trojúhelníky. Pro účely ladění obalovacích algoritmů.

-vNAME.tga

Bumb textura vlnek do NAME.tga.

-bXXX

Bump scale, výchylka vlnek v metrech se musí převést do 256'ti stupňové škály <-128, 127>. Někdy jsou vlny tak vysoké, že přesáhnou tento rozsah. Proto je vhodné vlnky touto volbou zmírnit. Implicitní hodnota 6000.

-h

Krátký seznam voleb. Právě zakompilované implicitní hodnoty.

4.9 dish -- distribuované počítání výsledné animace

Stručný popis

dish-client, dish-vi, dish-get, dish-put, dish-num soustava shelových scriptů, pro spočítání animace ze spočítaného .bur s pomocí více počítačů.

Popis

Na serveru musí být přítomné scripty dish-vi, dish-get, dish-put, dish-num program job, pro vytváření .pov z .bur. Také je zde spočítaná animace .bur.

Na clientu musí být dish-client a povray. Script dish-client si vytvoří adresář tmp a do něj si bude ze serveru stahovat popisy scén, spočítané obrázky vrací serveru.

Čísla framů, která se mají spočítat, jsou v souboru dish.todo (na serveru). Všechna čísla jsou na jednom řádku oddělená mezerou.

Scripty dish-num a dish-vi vytváří soubor(lockfile) dish.lock, čímž je zajištěno, že při práci s dish.todo nedochází ke kolizím.

dish-client

Script dish-client využívá program ssh a proto je dobré umožnit clientům přístup k serveru bez autorizace (viz. man ssh).

Ve scriptu je také třeba upravit nastavení těchto proměnných,

SERVER

Uživatel a server na který se bude dish-client logovat a získavat z něj popisy scén jednotlivých framů. Např: vitas@vitas.kolej.mff.cuni.cz.

RDISH

Kde je adresář s dish-* na serveru

LDISH

Kde je adresář s dish-* na clientu

Taktéž je třeba upravit proměnnou prostředí PATH tak, aby vedla i k povray'ovi.

dish-get

tento script je volaný z dish-clienta, ale je spouštěn za pomocí ssh na straně serveru. Požádá dish-num o další číslo framu, vytvoří potřebné soubory, zataruje je. Vytiskne tři řádky: první příkaz, který se má spustit (obyčejně něco jako povray -ifile.pov -ofile.tga). Druhý řádek je seznam souborů, které se mají poslat zpět. Třetí řádek jsou soubory, které se po skončení tohoto výpočtu mohou smazat. Poté následují zatarované vstupní soubory.

dish-num

Vždy při žádosti clienta o práci script dish-num přečte první číslo ze souboru dish.todo a smaže ho.

dish-vi

Editovat soubor dish.todo je možné i za běhu výpočtu pomocí tohoto scriptu. Klávesa ``m'' je namapovaná na ``zapsaní čísla o jedna většího, než jaké je na místě kurzoru'', čehož lze s úspěchem využít při psaní dlouhého seznamu framu. Tj. stačí napsat ``1'' a pak jen přidržet ``m''.

dish-put

pouze příjme zatarovaný výsledek od dish-client'ta. A roztaruje jej.

5. Programátorská dokumentace

V následující části se budeme zabívat programátorskou dokumentací. Je zde popsáno členění na moduly jejich rozhraní jednotlivých modulů a hlavní datové struktury.

5.1 Knihovna pro buran

Stručný popis

Knihovna pro uchování informací o animaci, která je rozdělena na navzájem nesouvisející framy. Každý frame může obsahovat několik bloků.

Knihovní funkce

Knihovní funkce pro práci s formátem buran využívají strukturu TBuran. O datech struktury TBuran uživatel této knihovny nemusí nic vědět.

Další pomocnou strukturou je TBuran_dir, která slouží (mimo jiné) k předávání informací o právě načteném bloku dat:

typedef struct TBuran_dir
{
  int typ, off, siz;
}TBuran_dir;

V typ je typ dat bloku a v siz je velikost bloku v bytech. Velikost typu dat v bloku není pro knihovnu nikterak zajímavá. Knihovna vlastně nic neví (ani nepotřebuje vědět) o typu dat v bloku. Přesto je použita následující konvence: spodních 16 bitů typu má význam délky typu, horních 16 je pak již rozlišovacích.

Obecné funkce

TBuran* buran_open(char *path, char *mode)

vytvoří strukturu TBuran. Argumenty path a mode jsou obdobně jako ve fopen(3). Tedy path je jméno otevíraného souboru, mode je jedno z "rb" pro čtení, nebo "wb" pro zápis.

TBuran* buran_open_by_file(FILE *f)

obdoba s tím rozdílem, že soubor f je již otevřen v příslušném módu.

Funkce pro čtení burana

int buran_seek(TBuran *bur, int offset, int mode)

posun po buranu bur, offset je v závislosti na mode buď od začátku (SEEK_SET), nebo relativně k současné pozici (SEEK_CUR).

TBuran_dir *buran_read(TBuran *bur, int typ, int nty)

načtení nty'ého bloku typu typ. Pokud bude typ==0, jde o nty blok bez ohledu na typ. V případě neúspěchu je vrácená hodnota NULL. Při úspěchu ukazuje na TBuran_dir, ve které jsou obsaženy informace o načteném bloku.

tt

unsigned char *buran_buff(bur);

vrátí ukazatel na buffer s místem, kde jsou data bloku. Je nutné si jej přetypovat.

Příklad

TBuran_dir *dir;
float *points;

/* chci všechny  bloky s body (POINT)*/

for(i=0; NULL != (dir = buran_read(bur, BUR_TYP_POINT, i); i++)
{
  points =  (float*)buran_buff(bur);
  ... dělej něco s polem `points'
}

Funkce pro zápis do burana

int buran_write(TBuran *bur, int bur_typ, int siz, void * buff)

Zapíše blok typu bur_typ, na který ukazuje buff velikosti (v bytech ) siz.

int buran_write_init(TBuran *bur, int bur_typ)

Připraví burana pro postupný zápis bloku typu typ. Ekvivalentní buran_write(bur, bur_typ, 0, 0);

int buran_write_add(TBuran *b, int siz, void *buff)

Přidání dat k posledně zapsanému bloku dat. Velikost dat je siz a nacházejí se na buff.

int buran_flush(TBuran *b)

Konec zadávání tohoto framu. Je potřeba zavolat po ukončení sypání dat do jednoho framu.

int buran_printf(TBuran *bur, char *format, ...)

Zapiš logovací hlášku (typ BUR_TYP_LOG). Argumenty format a ... jsou stejné jako u printf(3).

Příklad

Příklad ukazuje, jak je možné uložit 10 framů, v každém jsou dva bloky(logovací hláška a blok pět bodů):

TBuran *bur = buran_open("look.bur", "wb");
float point[3] = { 1, 0 , 0}; 

/* deset obrázků */
for(int frame = 0; frame < 10; frame++)
{
  /* v každém pět bodů */
  buran_init(bur, BUR_TYP_POINT);
  for(i = 5; i--;)
  {
    /* přidej jeden bod */
    buran_add(bur, sizeof(float)* 3, point);
    point[2] += 0.5; /*  ``výpočet'' bodu */
  }
  /* zapiš poznámku k tomu framu */
  buran_printf(bur, "Poznámka k framu %i\n", frame); 
  /* ukonči zadávání tohoto framu */
  buran_flush(bur);
}

Podrobný popis formátu buran

Celý soubor je rozdělen na framy. Fram má následující struktru: nejprve je hlavička framu. Ta je dlouhá 3 inty. V prvním je tzv magické číslo (hodnota pro kontrolu, zda nejde o porušenou strukturu souboru). Následuje offset následujícího a předcházejícího framu.

Následuje adresář bloků ve framu. Každá položka se skládá opět ze tří intů. První je typ bloku. Druhý je offset začátku dat odpovídajícího bloku. Offset se počítá od konce adresáře. A konečně třetí položka je délka bloku dat.

Pokud jsou všechny položky nulové, jde o poslední položku adresáře.

Následují data framu.

Mouchy

Knihovna nepomýšlí na korekci různých typu endianit (byte-orderů). Proto soubor není přenositelný mezi platformami různých endianů. Jinými slovy: číst data můžeme jen na endiánech na kterých tato data vznikala. Taktéž zřejmě budou problémy s přenosem souboru mezi platformami s různými hodnotami sizeof(int).

5.2 Jazyk JA

Parsování

Pro parsování je použita sehraná dvojice flex-bison. Pro více informací viz flex(1), bison(1).

Raw copy

Text mezi znaky tokeny %{ a %} je bezezměn zkopírován do výstupního souboru již při parsování.

Derivační strom

Během parsování se postaví derivační strom. Jeho průchodem získáme jeho všechny atomické bloky i s přesnými počátky. Po setřízení dle počátku bloku je vše připraveno k výstupu do korektního kódu jazyka A.

5.3 Jazyk A a modul Zenon

Motivace

V každém kroku simulace je třeba vědět o poloze a směru a síle trysky.

I když popis jazyka A umožňuje (v čase) spojité definování těchto hodnot, pro simulaci je nutné toto spojité chování zdiskrétnit. Právě k tomu slouží modul Zenon. Zjednodušeně řečeno, chceme se ptát Zenona, jak vypadá scéna v určitém okamžiku. Za odměnu mu slíbíme, že se budeme ptát pouze na čím dál tím větší čas.

Lexikální analýza jazyka A

Pro lexikální analýzu je použit nástroj flex(1). Tomu stačí pouze popsat jednotlivé lexémy regulárnímy výrazy a co se má dělat poku je najde. Z toho popisu flex vytvoří zdrojový text v jazyce C. Tak můžeme přehledným a snadno upravitelným způsobem získat velmi efektvivní lexikální analyzátor. Více informací o flexu viz např. info flex.

Popis chodu parseru

Parser bere od lexikálního analyzátoru jeden token za druhým a podle typu s nimi nakládá takto:

Některé funkce speciálně:

[] "idfce" def2

Definice nové funkce. Na zásobníku musí být dva argumenty: tělo definice (spoják tokenů), a id názvu této nové funkce.

TT cas1

Posunutí času na TT. Pokud je tento čas větší než požaduje modul Zenon (viz níže), parsování je dočasně přerušeno.

[] dT int2

Definice intervalu. Na zásobníku je tělo intervalu (spoják tokenů) a délka intervalu dT. Tělo bude provedeno pokaždé, když bude modul Zenon požádán o zjištění stavu trysek v čase, který bude mezi TT a TT + dT.

Modul Zenon

Pracuje vlastně ve dvou fázích. Nejprve načte všechny další intervaly, které by mohly potenciálně obsahovat čas TT. Zároveň se vyřadí ty intervaly, které již do děje nezasáhnou.

Druhá fáze spočívá v tom, že se provedou těla všech intervalů obsahujících čas TT.

Zenon podrobněji

V polích zn_trysky, zn_svetla, zn_kamery, zn_define, jsou informace o tryskách, o světlech, o kamerách, o proměnných scény. Informace o tryskách jsou využity modulem Chrlič, ostatní jsou jednoduše přeneseny do výstupu.

Modul Zenon má následující interface:

zn_init()

inicializace.

zn_set_time_zone(double tz)

nastavení kroku.

zn_shift_time()

posuň čas krok vpřed.

zn_set_time_lo(double tm)

nejmenší možný čas bude tm.

zn_at_time(double tm)

spočítej pozici trysek, světel ... v čas tm.

5.4 Obalování

Stručný úvod

Z programu jmv vypadnou (zjednodušeně řečeno) souřadnice a poloměry kapek. Úkolem job je tyto informace převést do popisu scény povray'e.

Obalování koulemi

Tato metoda je velmi jednoduchá: kapky budou nahrazeny skleněnými koulemi o daném poloměru.

Obalování válci

O něco málo složitější metoda. Blízké kapky jsou navíc spojeny komolými jehlany. Název zůstal historicky z doby, kdy měly všechny kapky stejný poloměr. Pojem ``blízké kapky'' je definován tak, že středy kapky nejsou dále než DISTANCE (konstanta definovaná v job.c).

Obalování trojúhelníky

Pokud jsou tři koule dostatečně blízko, vytvoří se mezi nimi navíc ještě trojúhelník, který zacelí díru použítím předchozí metody.

Protože by vznikla velká spousta trojúhelníků, což by jistě zdržovalo následný raytracing, je použita ještě drobná optimalizace. Vytvoří se pouze ty trojúhelníky, které jsou viditelné. Přičemž viditelnost chápeme následovně: Pokud 4 kapky tvoří (v relaci ``býti blízko'') čtyřstěn, potom o vnitřních stranách stěn tohoto čtyřstěnu řekneme, že nejsou viditelné. A nakonec -- trojúhelník je viditelný, pokud je viditelný alespoň z jedné strany.

Obalování jiných předmětů, než jsou kapky

Následujícím prostředkům se již nedá říkat obalování, ale myšlenka je podobná: převést spočítané prvky scény do popisu scény povray'e.

Vlnky

Bude vytvořen obrázek ve formátu TGA s bumb texturou výchylek vodní hladiny, zároveň se vytvoří objekt scény (obdélník), která se na tuto texturu odkazuje.

Define

Do popisu scény se přidá definice hodnoty. Tedy například:

 #declare poloha_autobusu = <1,0,1>

v hlavním popisu scény se potom může autobus posunout do místa poloha_autobusu.

5.5 Modul Star

Stručný popis

Modul Star uchovává kapky ve vnitřní datové struktuře. Požadavky na tuto strukturu jsou: rychlé vyhledávání blízkých kapek, možnost projít všechny kapky. Dále potřebujeme do struktury přidávat nové a ubírat staré kapky. Na druhou stranu můžeme slíbit, že přidávání a ubírání bude probíhat najednou (v kvantech). Jinými slovy budou se střídat dvě fáze. První: časté vyhledávání. A druhá: mazání a přidávání. To odpovídá tomu, že simulace probíhá diskrétně.

Prostor je rozdělen na 2 48 pomyslných buněk. Buňka je vlastně malá krychlička, která případně obsahuje kapky. Každá buňka má své vlastní číslo, které koresponduje s jejím umístěním v prostoru. Číslo je rozděleno na významnější (hi) a méně významnou část (lo). Významná část má 32 bitů, méně významná 16.

Popis datových struktur

Základem je pole st_hvezdy, ve kterém jsou informace o kapkách (trochu zavádějící název zůstal ze starších verzí). Tj. poloha, rychlost a různé další, které využívá převážně modul Move.

Nad tímto polem je ona vnitřní struktura, tvořena polemi st_bunky_ht hašovací tabulka buněk, st_bunky pole obsazených buněk, st_hvezdy_idx prvky buněk.

Dejme tomu, že máme najít kapku, která patří do buňky s číslem B. Méně významnou část čísla B nazveme lo, více významnou pak hi.

st_bunky_ht hashtable buněk, na místě st_bunky_ht[lo] se nalézá index do pole st_bunky, jde o první buňku s tímto lo. Zatímco st_bunky_ht[lo+1] je index na první buňku, která má již jiné lo. Mezi těmito dvěma čísly se nacházejí všechny buňky s hledaným lo.

st_bunky bloky buněk se stejným lo. Jak jsou tyto bloky určeny je patrné z předcházejícího odstavce. V bloku jsou buňky uspořádány dle hodnoty hi. Hledaná buňka se najde poměrně snadno půlením intervalu. V buňce jsou kromě informace o hodnotě hi tyto informace: fst první hvězda této buňky (odkaz do pole st_hvezdy_idx), len jejich počet.

st_hvezdy_idx bloky indexu do pole st_hvezdy, v každém bloku jsou hvězdy ze stejné buňky. Jak jsou určeny počátky a délky těchto bloků, je opět jasné z předchozího odstavce.

Z výše uvedeného je zároveň i vidět, jak se v takové struktuře vyhledávají blízké kapky: prostě prohledáme blízké buňky. Čísla hledaných buněk jsou snadno spočítatelná z jejich souřadnic.

Konstrukce datové struktury

První průchodem pole st_hvezdy zjistíme počty kapek se stejnými lo. Tyto hodnoty jsou dočasně uchovány v poli st_bunky_ht.

Poté průchodem pole st_bunky_ht připravíme bloky v st_bunky. Pro každou, kapku zde bude zatím připravena jedna buňka.

Druhým průchodem st_hvezdy zaplníme pole st_bunky.

Následuje komprese a setřídění v každém z bloků buněk. Bloky buněk budou setřízeny dle hodnoty hi. Komprese spočívá v tom, že buňky se stejnou hodnotou hi budou spojeny v jednu.

Posledním průchodem st_hvezdy konečně zařadíme hvězdy do buněk. A to tak, že vyplníme bloky pole st_hvezdy_idx indexy příslušných kapek.

Časová složitost

Označíme h_siz počet kapek, rozsah hodnot lo označíme lo_max. ro maximální počet kapek na buňku ro. Z výše uvedeného je vidět, že časová složitost vybudování struktury je O(h_siz + lo_max).

Časová složitost vyhledávání buňky je pak O(ln(kol)), kde kol je maximální počet kolizí v st_hvezdy_ht.

Tyto úvahy však vedou k zamyšlení, zda má smysl počítat asymptotickou složitost datové struktůry, jejíž velikost je omezena konstantou (viz následující odstavec).

Paměťová náročnost

Velikost této struktury záleží poněkud netriviálním způsobem na maximálním počtu kapek (h_siz).

V ``malé'' variantě je počet kapek omezen číslem 65535(= 2^16 - 1).

Ve ``velké'' variantě je počet kapek v podstatě neomezen (přesněji: omezen číslem 2^32). V hranatých závorkách je uváděna hodnota pro velkou variantu.

Počet položek pole st_bunky_ht je vždy 64k. Každá položka (index do pole st_bunky) má velikost 2B [4B].

Počet položek pole st_bunky_ht je h_siz. Velikost položek hi 4B [4B], fst index do st_hvezdy_idx 2B [4B], len délka bloku 2B [4B], celkem tedy 8B [12B].

Počet položek pole st_index je také h_siz. Položky mají velikost 2B [4B].

Celkově je tedy v malé variantě potřeba (horní odhad) 12 * 64kB = 768kB.

Kódování čísla buňky

Kódování polohy prostoru do čísla buňky je voleno tak, aby blízké buňky měly rozdílné číslo.

lo

 y5 y4 y3 y2 y1 y0 z4 z3 z2 z1 z0 x4 x3 x2 x1 x0
`--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--'
 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0

hi

 y15 ...  y6 z15 ...  z5 x15 ...  x5
`---+---+---+---+---+---+---+---+---'
 31  ...  22  21 ...  11  10 ...   0

Interface modulu

st_init()

Inicializace polí st_hvezdy, st_hvezdy_idx, st_bunky_ht,

t_star *st_hvezda_alloc()

Alokace nové hvězdy v poli st_hvezdy.

hvezda->flag &= ~ST_FLAG_IN

Zneplatnění hvězdy. Po zavolaní st_pack() bude hvězda uvolněna.

void st_pack()

modul Star vymaže všechny označené hvězdy a přejde do ``přidávacího'' stavu. Tj. mohou se přidávat nové kapky.

void st_build()

Vystavěné struktury. Od této chvíle se bude pouze vyhledávat.

t_long_bid vec2bid(t_vec v)

t_long_bid bid2vec(t_bid b)

t_long_bid bid2lbid(t_bid b)

Funkce na převod mezi identifikací, bodem prostoru a číslem buliňky, do které patří.

6. Závěr

Hlavním cílem této diplmové práce bylo vymyslet, vyzkoušet a porovnat možné přístupy k dané problematice. Nyní jsou implementovány základní modely chování vody, štěpení kapek, vlnění hladiny.

Zda bylo dosaženo onoho ``realistického zobrazení'', samořejmě dosti závisí na subjektivním pohledu. Nicnéně je nutné konstatovat, že nebylo dosaženo takové věrnosti, aby si výsledek ``necvičený laik'' spletl se skutečností, jak by se od realistického zobrazení mohlo očekávat.

Práce přinesla také nějaké vedlejší produkty, které mohou být aplikovány i mimo téma práce.

Jazyk JA vyvinutý v rámci této práce umožňuje spojité popsání chování oběktů ve scéně. Proto je možné jej s úspěchem použít i na zobrazení ``netryskajících'' animací.

Počítání animace je, díky prostému distribuovanému systému dish-*, možné v rozumném čase, pokud je k dispozici dostatečná výpočetní síla. Například spočítání průměrné desetisekundové animace (100 framů za sec) trvalo za použití 18 počítačů PC, 4 počítače silicon graphic, a 5 počítačů sun zhruba dvacet minut.

Vzhledem k umírněnému používání systémově závislých knihoven, je celý systém dobře přenositelný. Přenos byl bez větších zásahů a problémů proveden na tyto platformy: PC (Linux, FreeBSD, DOS), Sparc (Solaris, Linux), Silicon Graphics (Irix).

Dalším pozitivním rysem je poměrně dobře navržená struktura celého projektu, která umožňuje snadné zásahy a tím je dobře připravena pro případný další vývoj.

Tento vyvoj by se mohl zaměřit na sofistikovanější přístup při závěrečném zobrazení, či více propracovat použité matematické modely.

7. Obsah přiloženého CD

Na přiloženém cd jsou vytvořené programy, jejich zdrojové texty a ukázky animací. Struktura adresářů je následujicí:

/doc

Text diplomové práce v mnoha textových fomátech (tex, dvi, ps, html, txt, doc, sgml).

/src/di

Zdrojové texty diplomové práce.

/src/cvsroot/

Archív zdrojáků cvs.

/bin/i386

Zkompilované programy pro platformu Linux/x86

/bin/sparc

Zkompilované programy pro platformu sparc (sun).

/sup

Podpůrné programy (pro platformu Linux/x86), které se ne vždy dodávají s distribucí.

Jsou to povray, ssh, knihovna Mesa, Togl, mpeg_encode.

/obr

Ukázky výsledků. V souboru /obr/index.html je přehled a komentáře k obrázům.

8. Několik málo ukázek

Obrázek č.1

Jeden snímek z animace. Pro simulaci byl použit základní gravitační model spolu s modelem hrubého odstrkování. Kapky jsou nahrazeny koulemi.

Obrázek č.2

Ten samý snímek, jen k obalování je zvolena válcová metoda, tj blízké kapky jsou návíc spojeny válcem.

Obrázek č.3

Tento snímek se od prvního liší pouze změnou použitého materiálu pro vodu. Zatímco v předcházejících případech šlo o zrcadlo, v tomto případě je použito čisté čiré sklo.

Obrázek č.4

Prohlížeč xburan. Tímto programem, lze snadno a rychle prohlížet právě spočítanou simulaci, aniž by se musela počítat výsledná animace. V prohlížeči je zhruba stejný záběr jako v předchozích ukázkách.

Obrázek č.5

Ukázka detailu obalování kapek. V místě kapky je koule a blízké kapky jsou spojeny válci. Barvy válců a koulí byly záměrně obarveny odlišnými barvami, aby vynikla struktura obalování.

Obrázek č.6

Jiný přístup k obalování. Blízké kapky jsou oproti předchozímu příkladu navíc pokryty trojúhelníčky. Jednotlivé útvary jsou opět obarveny nerealistickými barvami.

9. Poděkování

Josefu Pelikánovi

vedoucímu této diplomové práce, za dobré vedení, spoustu inspirativních připomínek.

Františkovi Křižíkovi

za opravdu velkou inspiraci.

Bramu Moolenaarovi

autoru editoru vim, ve kterém tato diplomová práce byla napsána.

L. Beethovenovi, A. Mozartovi a jiným skladatelům

za hudbu při které tato práce vznikala.

Spolužákům, rodičům, známým

za morální podporu při tvorbě diplomové práce. Zvláště pak za cenné konzultace v oblasti pravopisu.

10. Literatura

[1] Orfeus: Křižíkova fontána http://www.radio.cz/orfeus/

[2] Gerlová, J.: Životopis Františka Křižíka http://www.trafika.cz/pr/1997/9707/pr182701.HTML

[3] Miller, J. S.: Modelling Liquids using particle Systems and Impicit Surfaces.
            Ph.D. Thesis University of Manchester Department of Computer Science, 1998

[4] Murta A., Miller, J. S.: Modelling and Rendering Liquits in Motion. WSCG99

[5] Svěrák Z., Smoljak L., Cimrman J.: Posel z Liptákova.

[6] Horák, Z. a kol: Technická fysika. SNTL, 1961

[7] Rapaport, D. C.: The art of molecular dynamics simulation. Cambridge University Press, 1995

[8] GNU info cpp

[9] Povray, Povray documentation. http://www.povray.org/