Ahoj lidi!

     Dnes  jsem  se  rozhodl pro vás napsat návod na jeden zajímavý efekt,
     který  můžete  s  malou  námahou a velkým efektem použít například na
     pozadí  titulků  svého  programu, jako to udělala např. Iguana v demu
     Heartquake.  Jedná  se  o  kreslení  pohybujících  se  vlnek na vodní
     hladině.  Začnu  trochou  matematiky, což se, jak brzy zjistíte, u mě
     stane  tradicí.  Já  jsem  totiž  šílenec  a mám na to dokonce průkaz
     (s nápisem MFF UK :-).

     VLNOVÁ ROVNICE

     Protože najít nějaký jiný výpočet, který by dával podobné výsledky je
     velmi obtížné, tady je obecná vlnová rovnice, jak ji odvodili fyzici,
     ve své plné kráse ;-) (pro vlnu na povrchu - 2D):

                     2        +  2       2  +
                    d p     2 | d p     d p |      dp
                   ----- = V  |----- + -----| - D ----
                      2       |   2       2 |
                    dt        + dx      dy  +      dt

     Nebojte  se,  až  to  budete  programovat,  tak  tam nebude ani jeden
     součin, JENOM  DVĚ  ROTACE a budete to počítat v INTEGERECH! Nicméně,
     pokud  chcete pochopit, proč by to mělo vlastně fungovat, tak tady je
     vysvětlení:  Nejdříve  popis  symbolů:  Symbol d znamená diferenciál,
     p  je  okamžitá výchylka v určitém bodě a čase, x a y jsou prostorové
     souřadnice a t souřadnice časová. Konstanta V je rychlostní konstanta
     a  D  je  tlumící konstanta. A nyní trochu polopatické vysvětlení, co
     tahle  rovnice  znamená.  Druhá  derivace  na  levé staně představuje
     zrychlení  a rovnice o něm tvrdí, že je přímo úměrné zakřivení daného
     povrchu a v případě tlumení se snižuje při vyšší rychlosti.

     Pokud  pořád ještě netušíte, co tahle rovnice vyjadřuje, nebo nevíte,
     jak  něco  takového  numericky  počítat, uvádím  podrobné  vysvětlení
     eulerovy metody řešení této rovnice.

     Pro  výpočet druhé derivace eulerovou metodou musíme rovnici rozdělit
     na soustavu dvou rovnic s první časovou derivací. Asi takto:

                              +  2       2  +
                    dv        | d p     d p |
                   ---- = sqV |----- + -----| - D v
                              |   2       2 |
                    dt        + dx      dy  +


                    dp
                   ---- = v,

                    dt

     kde  v  je  rychlost  v daném bodě a V^2 bylo nahrazeno symbolem sqV,
     čímž chci říct, že tu konstantu přece nebudete pokaždé umocňovat.

     Tyto  dvě  rovnice  potom  převedeme do diferenčního tvaru a obdržíme
     následovný tvar:

                     +                                                 +
      v  - v         | p     + p     - 2p        p     + p     - 2p    |
       n    o        |  i+1,j   i-1,j    i,j      i,j+1   i,j-1    i,j |
     --------- = sqV |----------------------- + ---------------------- | -
                     |           2                         2           |
        ⌂t           |         ⌂x                        ⌂y            |
                     +                                                 +

           - D v
                o


      p  - p
       n    o
     --------- = v
                  n (<-- tady správně patří o, ale prakticky je to jedno)
        ⌂t

     Pokud  zvolíme  vhodné jednotky, snadno se zbavíme jmenovatelů (budou
     prostě 1), no a pak už stačí deklarovat příslušná pole a přepsat výše
     uvedené rovnice do C syntaxe:

     v[i][j] = sqV * (p[i+1][j] + p[i-1][j] + p[i][j+1] + p[i][j-1] -
         p[i][j]) + jednaminusD * v[i][j];
     p[i][j] += v[i];

     Doufám,  že  jste  pochopili,  že změna konstanty D na jednaminusD je
     způsobena   tím,   že  se  v  rovnici  objevuje  dvojčlen  v  -  D*v.
     Ekvivalentně  lze  použít  operátor += a původní konstantu. Konstanta
     sqV  musí  být  z důvodu přesnosti nejvýše 1/2, jinak to bude počítat
     pěkný blbosti a ne vlny.

     No  a  hurá  programovat!  Tak  to  zase prr! Ještě nám zbývá několik
     problémů.

     OKRAJOVÉ PODMÍNKY

     Protože  pole,  ve  kterém budete vlny počítat, někde končí, je nutné
     ošetřit, co  se  bude  dít  na  jeho  okrajích, kde zjevně neexistují
     všechna sousední políčka. Máte dvě základní možnosti:

     Pevný okraj

     Pevné  okraje  se  vyskytují například u blány na povrchu bubnu a pro
     simulaci  jsou  velmi  jednoduché.  Pevný  okraj  má tu vlastnost, že
     výchylka  p je zde vždy 0. Takže prostě na okraje pole uložíte nuly a
     nebudete pro tyto uzly provádět ŽÁDNÝ výpočet.

     Volný okraj

     Na  hladině  vody  se  však  vyskytují  okraje volné. Jejich simulace
     vypadá  efektněji,  ale staví nás před větší problémy. Volný konec je
     obecně  charakterizován  tím,  že zde je povrch v rovině. Tedy bod na
     okraji  má  stejnou  výchylku,  jako  bod  těsně  vedle  něj  (směrem
     dovnitř).  Takže pro okrajové uzly musíme provádět speciální operaci,
     která  jim  přiřadí  hodnoty  jejich sousedů. Pochopitelně můžete mít
     některé  okraje  volné  a  jiné  pevné,  nebo můžete na některý okraj
     připojit  generátor  vln  (budete  tam  postupně ukládat předem danou
     posloupnost hodnot výchylky)

     Průměrná výška a rychlost

     Použití pouze volných okrajů nás staví ještě před jeden problém. Díky
     nepřesnosti,  které  se přibližný numerický výpočet nevyhne, se velmi
     rychle  stane,  že celý vlnící se povrch odcestuje nahoru, nebo dolu.
     Proto   musíte   udržovat  celý  povrch  v  nulové  průměrné  výšce a
     rychlosti,  kterážto  podmínka  je  odvozena  z  toho,  že  pod vodní
     hladinou  bývá  konstantní  objem  nádoby  a tento je nutno zachovat.
     Proto musíme do výrazů pro výpočet v[i][j] a p[i][j] přidat člen vavg
     a pavg respektive. Takže:

     v[i][j] = ... - vavg;
     p[i][j] += ... - pavg;

     Hodnoty  vavg  a  pavg  potom  vypočítáme  tak, že sečteme hodnoty v,
     respektive  p  ve  všech  bodech  sítě  a  vydělíme  je  počtem  uzlů
     (idim*jdim).

     POČÁTEČNÍ PODMÍNKY

     Než  můžete  začít  počítat,  musíte pole naplnit nějakými hodnotami,
     kterým  se  říká počáteční podmínky. Pokud tam dáte samé nuly, tak se
     vám   nic  nerozvlní.  Takže  musíte  buď  na  počátku  naplnit  pole
     nestejnými   hodnotami,   nebo  později  vyvolat  rozruch  (dodatečně
     pozměníte některé hodnoty)

     No a teď se konečně můžete pustit do toho programování!

                                                                          -Bulb-

     PS: Na závěr jeden PŘÍKLAD. Přeji příjemnou zábavu!


            výheň