Plazma

Vizuálny efekt plazmy je jeden zo základných cvičení, ktoré pochádza ešte z dávnych ér demoscény (Wikipedia: Plasma effect).

Základný program

Budeme vychádzať z podobného základu ako pri tutoriáli Psychedelické vlny. Ak ste tento tutoriál nerobili, tak si urobte najprv ten.

Podobne ako v tom tutoriáli, budeme aj tu používať dvojitý cyklus, ktorý prechádza mriežku na obrazovke políčko po políčku. Akurát v každom políčku vykreslíme štvorček a nie krúžok. A ešte si nastavíme HSB farebný mód hneď na začiatku, lebo to už poznáme a nebudeme sa tomu ďalej venovať.

float d = 20;
int riadkov,stlpcov;

void setup()
{
  size(800,400);
  riadkov = int(height/d);
  stlpcov = int(width/d);
  colorMode(HSB);
}

void draw()
{
  for (int r = 0; r < riadkov; r++)
  {
    for (int s = 0; s < stlpcov; s++)
    {
      square(s*d, r*d, d);
    }
  }   
}

Príkaz map()

Prvým základným bodom plazma efektu je nastavenie farby políčka podľa jeho polohy. Napríklad takto by vyzeralo, keby sme nastavili farbu podľa stĺpca s:

void draw()
{
  for (int r = 0; r < riadkov; r++)
  {
    for (int s = 0; s < stlpcov; s++)
    {
      fill(s, 255, 255);
      square(s*d, r*d, d);
    }
  }   
}

U vás tento farebný prechod môže vyzerať rôzne, podľa toho, koľko máte stĺpcov. Vždy bude síce začínať na červenej farbe (s = 0) ale skonči to pri inej farbe, ak máte iný počet stĺpcov.

Ak by sme chceli, aby to vždy obsiahlo celú farebnú škálu od 0 po 255, použijeme príkaz map.

Tento príkaz zoberie hodnotu z nejakého intervalu, v našom prípade hodnotu s z intervalu 0stlpcov. A prepočíta ju na hodnotu z iného intervalu, v našom prípade 0255. Takto:

      fill( map(s, 0, stlpcov, 0, 255) , 255, 255);

Namiesto samotného s sme toto s premapovali na interval 0255 a tým máme zabezpečené, že nech je stĺpcov hocikoľko, vždy bude farba začínať na 0 a prejde celé spektrum až po 255:

Skúste teraz zmeniť d, zmení sa tým veľkosť mriežky a s tým aj počet stĺpcov. Ale farba bude stále roztiahnutá cez celé spektrum od 0 po 255.

Vzdialenosť a príkaz dist()

Druhým základným bodom plazma efektu je nastavenie farby podľa vzdialenosti od nejakého bodu (alebo bodov). Teraz máme farbu nastavenú len podľa horizontálnej súradnice s. Doplníme si nejaký stred a budeme farbu nastavovať podľa vzdialenosti od neho.

Vytvorte súradnice cx, cy a nastavte ich na stred obrazovky:

float d = 20;
int riadkov,stlpcov;
float cx, cy;

void setup()
{
  size(800,400);
  riadkov = int(height/d);
  stlpcov = int(width/d);
  colorMode(HSB);
  cx = width/2;
  cy = height/2;
}

Vo vnútornom cykle si vypočítame x,y súradnice práve vykresľovaného štvorčeka, lebo z tých potom budeme vypočítavať, ako ďaleko na obrazovke je od cx, cy:

  for (int r = 0; r < riadkov; r++)
  {
    for (int s = 0; s < stlpcov; s++)
    {
      float x = s*d;
      float y = r*d;
      fill( map(s, 0, stlpcov, 0, 255) , 255, 255);
      square(x, y, d);
    }
  }   

Vzdialenosť medzi bodom x,y a bodom cx,cy nám vypočíta funkcia dist(), uložíme si vypočítanú vzdialenosť do premennej v:

      float x = s*d;
      float y = r*d;
      float v = dist(x, y, cx, cy);
      fill( map(s, 0, stlpcov, 0, 255) , 255, 255);
      square(x, y, d);

A namiesto súradnice s použijeme do výpočtu farby túto novú hodnotu - vzdialenosť v:

      float x = s*d;
      float y = r*d;
      float v = dist(x, y, cx, cy);
      fill( map(v, 0, stlpcov, 0, 255) , 255, 255);
      square(x, y, d);

Akurát, že obrázok je dosť zdecimovaný:

To je preto, že v príkaze map, kde sme pôvodne mapovali s na farbu, tak teraz mapujeme vzdialenosť v. Ale toto v už nie je z intervalu 0stlpcov. Musíme teda upraviť aj interval z ktorého mapujeme. Najmenšia vzdialenosť je 0, to zostáva, ale maximálnu vzdialenosť nepoznáme. Použime napríklad width/2, lebo to je vzdialenosť od stredu obrazovky po jej kraj.

      fill( map(v, 0, width/2, 0, 255) , 255, 255);

Animácia a príkaz sin()

Treťou časťou je animácia. Pridajme do programu počítadlo času:

float d = 20;
int riadkov,stlpcov;
float cx, cy;
float t = 0;

A začleňme ho do výpočtu farby:

void draw()
{
  for (int r = 0; r < riadkov; r++)
  {
    for (int s = 0; s < stlpcov; s++)
    {
      float x = s*d;
      float y = r*d;
      float v = dist(x, y, cx, cy);
      fill( map(v + t, 0, width/2, 0, 255) , 255, 255);
      square(x, y, d);
    }
  }
  t = t + 1;
}

Animácia už beží, ale po chvíľke farby zdegenerujú do čisto červenej:

To preto, že keď rastie t, tak časom vyrastie príliš vysoko a farby s hodnotou nad 255 sú už konštantne červené.

Ak chceme, aby sa niečo v čase periodicky opakovalo, tak použijeme funkciu sínus. Ako bude čas rásť, tak funkcii sínus je to jedno, tá bude stále produkovať hodnoty od -1 po 1 a tak dokola. Nikdy nevylezie do nekontrolovateľných výšok.

Akurát budeme musieť pozmeniť aj interval z ktorého mapujeme farby. Teraz je to 0 až width/2. Po použití sínusu to bude -1 až 1:

      fill( map( sin(v + t), -1, 1, 0, 255) , 255, 255);

Teraz sa už farby periodicky menia, ale zase strašne divoko:

Potrebujeme to, čo je vnútri sínusu spomaliť, tak vydelíme aj v aj t nejakými číslami:

      fill( map( sin(v/100 + t/50), -1, 1, 0, 255) , 255, 255);

Plazma s viacerými stredmi

Plazma len s jedným stredom je nudná. Pridáme do vzdialenosti aj druhý stred a bude to pozícia myši:

      float v = dist(x, y, cx, cy) + dist(x,y,mouseX,mouseY);

Prípadne aj tretí stred, na náhodnú pozíciu:

float d = 20;
int riadkov,stlpcov;
float cx, cy;
float dx, dy;
float t = 0;

void setup()
{
  size(800,400);
  riadkov = int(height/d);
  stlpcov = int(width/d);
  colorMode(HSB);
  cx = width/2;
  cy = height/2;
  dx = random(width);
  dy = random(height);
}

A ešte upravíme výpočet vzdialenosti:

      float v = dist(x, y, cx, cy) + dist(x, y, mouseX, mouseY) + dist(x, y, dx, dy);

Vyladenie farieb

Obvykle sa plazma nerobí v dúhových farbách, ale v nejakej kombinácii červenej, žltej, oranžovej. Toto vieme upraviť keď zúžime cieľový interval mapovania z 0255 na 040:

      fill( map( sin(v/100 + t/50), -1, 1, 0, 40), 255, 255);

Tu je finálny skeč:

Modifikácie

  • Zmeňte farebnú škálu tak, aby namiesto červenej, oranžovej až žltej bola zelená, tyrkysová až modrá.

  • Rozhýbte body cx,cy a dx,dy nejakým pohybom. Môžu sa odrážať od stien, alebo sa môžu loopovať cez okraje obrazovky

Last updated