Vyhledávání

#9 - Processing

09.03.2014 21:00

Processing

Dnešní díl bude trochu netypický. Nebudeme se v něm totiž bavit o Arduinu, ale o vývojovém prostředí Processing. Postupně se podíváme na hlavní části tohoto prostředí a ukážeme si jak fungují.


Úvod

I když by se mohlo zdát, že spolu projekty Arduino a Processing moc nesouvisí, ve skutečnosti tomu tak není. Processing se sice nepoužívá na programování hardware, ale myšlenka obou prostředí je stejná. Má přiblížit programování i neprogramátorům jednoduchou cestou. Prostředí má vlastní stejnojmenný programovací jazyk, který vychází z jazyka Java a značně jej zjednodušuje. Dá se zde však použít i většina příkazů z tohoto jazyka. Vývojové prostředí stáhneme z oficiální stránky. Po kliknutí na download se zobrazí nabídka s různými operačními systémy (Windows, Linux a Mac OS X), ve které si vybereme a stáhneme vhodnou verzi. Silnou stránkou jazyka Processing jsou jeho grafické aplikace. Jednoduše se v něm dají kreslit plošné a po nějakém čase i prostorové geometrické útvary.

Velmi zajímavá instruktážní videa s ukázkami programů vytvořených v tomto prostředí naleznete na jeho oficiálních stránkách.


Seznámení

Po rozbalení staženého .zip archivu je prostředí plně funkční. Spustíme jej pomocí programu processing.exe. Otevře se nám okno velmi podobné Arduino IDE. Nejvíce nás bude zajímat dvojice kulatých a čtveřice hranatých tlačítek v horní části. Jejich funkce je (zleva): spuštění programu, zastavení programu, vytvoření nového programu, otevření existujícího programu, uložení programu a tlačítko pro export kódu v podobě spustitelné mimo Processing. I zde slouží velká bílá plocha uprostřed ke psaní kódu. Při programování se používají dvě základní funkce: setup() a draw().

void setup() {}

void draw() {}

 


Základ

Než se pustíme do grafických aplikací, ukažme si, jakým způsobem se v Processing řídí chod programu.


Datové typy

Zde nás nečeká téměř nic nového. Stejně jako u Wiring i zde existují datové typy boolean, byte, char, double, float, int a long. Navíc se setkáme ještě s datovým typem color sloužícím k uchování informace o barvě.


Pole

I když se zde s poli pracuje prakticky stejně tak jak známe, dají se nalézt malé odlišnosti, které však mohou způsobit problémy. Hned způsob vytváření polí je mírně jiný.

//místo 
int a[5];
int b[5] = {1,2,3,4,5};
//se zde používá syntaxe
int[] a = new int[5]; //pro vytvoření prázdného pole o pěti prvcích
int[] b = {1,2,3,8,20};

Práce s buňkami pole je stejná jako ve Wiring.

//nastavení hodnoty buňky s daným indexem
int[] a = new int[5];
a[3] = 10; //nastavení hodnoty buňky

Processing navíc nabízí zajímavou funkci pro zjištění délky pole.

int[] a = new int[5];
int l;

l = a.length; //l obsahuje délku pole a - tj. 5

 


Kontrolní struktury

Tato část je také velmi podobná Wiringu. Používají se zde základní porovnávací operátory, jimiž jsou !=, <, >, ==, <= a >=. Podmínky i cykly zde mají stejnou syntaxi, jakou již známe.

//podmínky
if (podmínka){
	//příkazy
}
else if(podmínka){
	//další příkazy
}
else {
	//a další příkazy
}

//cyklus
for(int i=0; i<10; i++){
  //příkazy
}

 


Výpis hodnot

Pro výpis textových hodnot slouží panel pod částí pro psaní kódu. Zde se v Arduino IDE zobrazují informace o průběhu uploadu a podobně. K výpisu slouží funkce print() a println(), které fungují stejně jako nám známé Serial.print() a Serial.println().


Kreslení

Vytvoření kreslícího plátna

Abychom měli kam kreslit, musíme pro program vytvořit kreslící plochu. To se provádí pomocí příkazu size(x,y). Je jasné, že x a y jsou rozměry v jednotlivých osách. Následující kód tedy vytvoří kreslící plátno o rozměrech 500x500. Tím nám zároveň vznikne nová vztažná soustava pro kreslení objektů. Důležité je vědět, jakým způsobem jsou zde určené osy. Jejich průsečík (počátek) nalezneme v levém horním rohu plátna. Osa x je rovnoběžná s horním okrajem a její hodnota roste směrem doprava. Osa y je na ní kolmá. Je tedy rovnoběžná s levým okrajem a roste směrem dolů (což by mohlo zkušené matematiky mást :) )

void setup() {
  size(500,500);
}

void draw() {
}	

Funkce size

 

Zatím to není žádná sláva - šedý obdélník a nic víc. Pojďme si tedy ukázat, jak tento obdélník vyplnit. Mějme na paměti, že se objekty na plátně vrství ve stejném pořadí, v jakém je v programu vytváříme.

Barvy

K barvám lze přistupovat různými způsoby. Většinou se nastavují pomocí funkce color(), která může mít různý počet parametrů v závislosti na způsobu jejího použití.

//barva ve stupních šedé od černé (0) po bílou (255)
color(gray); 
//barva ve stupních šedé se sytostí od 0 do 255 (čím větší alpha, tím sytější barva)
color(gray, alpha);
//barva zadaná pomocí RGB - červená, zelená, modrá v rozsahu 0 až 255
color(r, g, b);
//barva RGB se sytostí (0-255)
color(r, g, b, alpha);

Těmito funkcemi se ale ještě nic neprovede. Pouze vracejí hodnotu zadané barvy jako int. Pro nastavování barev jednotlivých částí kreslící plochy slouží několik funkcí. První z nich je background(), která změní barvu celého pozadí. Jako její parametr můžeme použít právě představenou funkci color().

void setup(){
  size(500,500);
  background(color(0,255,0)); //nastaví pozadí plátna na zelenou
}

void draw(){}

Funkce background Kreslené útvary mají většinou okraj a výplň. Pro nastavení barvy okraje se používá funkce stroke() a pro výplň funkce fill(). Také můžeme programu říct, že si nepřejeme, aby okraj či výplň zobrazoval. Pomocí funkcí noStroke() a noFill() se tyto části objektu zprůhlední. Pokud použijeme libovolnou z těchto čtyř funkcí, ovlivní všechny útvary, které vytvoříme po jejich volání.

 


Bod

S bodem se konečně dostáváme ke geometrickým útvarům. Na plátno jej nakreslíme pomocí funkce point(x,y). Pomocí dvou cyklů a představených funkcí si můžeme jednoduše vytvořit barevnou škálu dvou barev.

int[] pocatek = {20,20}; //počáteční souřadnice x,y

void setup(){
  size(296,296);
}

void draw(){
  for(int i = 0; i<256; i++){
    for(int j = 0; j < 256; j++){
      stroke(color(i,j,0));
      point(i+pocatek[0], j+pocatek[1]);
    }
  }
}

Funkce point

 


Úsečka

K nakreslení úsečky se používá funkce line(x1, y1, x2, y2) se souřadnicemi jejího počátečního a koncového bodu. Vykresleme si barevnou škálu stupňů šedé pomocí úseček.

int delka = 100;
int[] pocatek = {20,20}; //počáteční souřadnice x,y

void setup(){
  size(296,140);
}

void draw(){
  for(int i = 0; i<256; i++){
    stroke(i);
    line(pocatek[0] + i, pocatek[1], pocatek[0] + i, pocatek[1] + delka);
  }
}

Funkce line

 


Čtyřůhelník

Čtyřúhelník je geometrický útvar daný pomocí čtyř bodů. V Processingu se nakreslí pomocí funkce quad(x1, y1, x2, y2, x3, y3, x4, y4), kde x1 - y4 jsou souřadnice krajních bodů. Funkci si předvedeme na deltoidu (tvar klasického draka).

void setup(){
  size(200, 300);
}

void draw(){
  quad(40,100,100,40,160,100,100,200); 
}

Funkce quad

 


Zvláštní případy čtyřúhelníků

Pro čtyřúhelníky, jejichž dvě protější strany jsou stejně dlouhé (čtverec, obdélník) existuje speciální funkce rect(). Ta vytvoří čtyřúhelník z jeho rozměrů a souřadnic určujícího bodu. Tento bod může být dvojího druhu: buďto střed útvaru, nebo jeho levý horní roh. Defaultně je jako určující bod nastaven právě roh útvaru, ale pomocí funkce rectMode() se dá změnit. Pokud ji voláme s parametrem CORNER nebo CORNERS, nastaví se určující bod na roh, pokud je parametr CENTER nebo RADIUS, bude jím střed útvaru.

void setup(){
  size(500,500);
}

void draw(){
  fill(0);
  rectMode(CORNER);  
  rect(250,250,100,200);
  
  fill(255);
  rectMode(CENTER);  
  rect(250,250,100,200);
}

Funkce rect a rectMode Funkce rect() může mít ještě další parametry, které určují zaoblení rohů. Přidáme-li funkci pátý parametr, všechny rohy se zaoblí tak, že jejich poloměr bude zadaný parametr.

void setup(){
  size(500,500);
}

void draw(){
  fill(255);
  rectMode(CENTER);  
  rect(250, 250, 100, 100, 20);
}

Funkce rect U čtyřúhelníka můžeme nastavit i poloměry jednotlivých zaoblených rohů zvlášť. Funkce tedy bude mít osm parametrů: rect(a, b, c, d, hl, hp, dp, dl), kde parametry a-d jsou stejné jako při volání základní funkce rect() a hl je poloměr horního levého rohu, hp horního pravého, dp dolního pravého a dl dolního levého rohu.

void setup(){
  size(500,500);
}

void draw(){
  fill(255);
  rectMode(CENTER);  
  rect(250, 250, 100, 100, 10,20,30,40);
}

Funkce rect

 


Trojúhelník

Dalším představeným objektem je trojúhelník. Používá se stejně jako quad(), jen má namísto osmi pouze šest parametrů (x a y tří bodů). K jeho nakreslení se používá funkce triangle(x1,y1,x2,y2,x3,y3).

void setup(){
  size(500,500);
}

void draw(){
  fill(255);
  triangle(100,100,400,400,200,400);
}

Funkce triangle

 


Elipsa a kružnice

Tímto jsme vyčerpali paletu základních n-úhelníků a dostáváme se k elipse, kružnici a kruhu a jejich částem. V Processing se využívá stejná funkce pro kružnici i elipsu a to ellipse(x,y,sirka,vyska). Liší se pouze použitými parametry (když sirka = vyska, výsledný tvar je kružnice). X a y jsou souřadnice středu elipsy.

void setup(){
  size(500,500);
}

void draw(){
  noStroke();
  
  fill(color(255));
  ellipse(250,250,400,400);
  
  fill(color(30,50,100));
  ellipse(250,250,400,200);
  
  fill(color(200));
  ellipse(250,250,100,200);
}

Funkce ellipse

 


Část kružnice a elipsy

Pro práci s částmi kružnice slouží funkce arc(x,y,sirka,vyska,p,k). První čtyři parametry jsou stejné, jako u ellipse(). Jsou to x a y středu, šířka, výška. Další dva parametry jsou počátek výřezu a konec výřezu v radiánech. Pro tento účel zde nalezneme konstanty PI, HALF_PI a QUARTER_PI odpovídající částem Ludolfova čísla.

int casti = 400;

void setup(){
  size(500,500);
}

void draw(){
  for(int i=1; i<=casti; i++){
    fill(color(i%30,i%50+200,i%40+100));
    arc(250,250,400/casti*i, 400/casti*i, PI*2*i/casti, PI*2*i/casti+PI*2/casti); 
  }
}

Poznámka: V dokumentaci jazyka Processing nalezneme i funkce pro práci s křivkami (Curves). Těmi se ale dnes nebudeme zabývat.

 


Interakce s myší

Processing umí reagovat na akce myši i klávesnice. Může například zjišťovat polohu kurzoru, stisk tlačítek, nebo rolování kolečka. K tomuto účelu slouží řada funkcí a proměnných. Některé z nich si nyní představíme. Ještě předtím si ale musíme říct, že se zde s funkcemi nepracuje úplně stejně jako u Arduina. Některé funkce musejí být volány stejným způsobem, jako bychom je znovu deklarovali. Mezi ně patří všechny funkce pro práci s myší.


Tlačítka myši

Základní funkce, která zjišťuje, jestli bylo vůbec nějaké tlačítko stisknuto je funkce mouseClicked(). Jak už jsem naznačil, musí být tato funkce ve vlastním bloku kódu na úrovni void draw() a dalších. Mějme na paměti, že se funkce provádí při zmáčknutí a uvolnění tlačítka (nestačí tedy pouze stisknutí).

void setup(){}
void draw(){ }

void mouseClicked(){
  //kód, který se provede když je stisknuté libovolné tlačítko myši
}

Informace, jestli je stisknuté nějaké tlačítko nám ale většinou nestačí. Ke zjištění, jaké tlačítko bylo zmáčknuto slouží proměnná mouseButton. Ta obsahuje informaci o stisknutém tlačítku. Její hodnoty mohou být LEFT, RIGHT a CENTER.

int casti = 400;
int vypln = 0; 
 
void setup(){
  size(500,500);
}
 
void draw(){  
  for(int i=1; i<=casti; i++){
    fill(vypln);
    noStroke();
    arc(250,250,400/casti*i, 400/casti*i, PI*2*i/casti, PI*2*i/casti+PI*2/casti); 
  }
}

void mouseClicked(){
  if(mouseButton == LEFT){
    vypln = 255;    
  }
  else{
    vypln = 0;
  }
}

Nalezneme zde také další funkce, které s tlačítky myši souvisejí. Jejich použití je stejné jako u mouseClicked(). První z nich je funkce mouseDragged(), která se vykoná v případě, že je stisknuté tlačítko myši a zároveň se myš pohybuje. Další funkcí je mouseMoved(), který se vykoná, pokud není zmáčknuto žádné tlačítko a myš se hýbe. funkce mousePressed() se provede, pokud je stisknuto libovolné tlačítko a mouseRelased() pokud je uvolněno. Poslední funkcí je mouseWheel(), která je volána, pokud rolujeme kolečkem myši.

 


Poloha kurzoru

Pro zjištění polohy kurzoru se zde nepoužívají funkce, ale proměnné, které obsahují jeho souřadnice v osách x a y. Jsou to mouseX a mouseY. Ukažme si program, který vykreslí úsečku danou jedním pevným bodem a kurzorem myši.

void setup(){
  size(500,500);
}

void draw(){ 
  background(200);
  line(250,250,mouseX,mouseY);  
} 

To by bylo pro dnešek vše. Možná si říkáte, proč se v seriálu o Arduinu bavíme o softwarovém prostředí, které s ním očividně moc nesouvisí. Vězte však, že Processing umí komunikovat se sériovou linkou a tím třeba i číst informace, které mu posílá Arduino. Celkem jednoduchým způsobem se tak dají vytvářet zajímavé grafy pomocí dat naměřených Arduinem v prostředí Processing.

 


Zdroje obrázků

Screenshoty z prostředí Processing.
V případě jakýchkoliv dotazů či nejasností se na mě neváhejte obrátit v komentářích.

 

Kam pokračovat?


<--#8 - Arduino jako klávesnice a myš||#10 - Arduino a Processing -->
Zpět

Diskusní téma: #9 - Processing

Datum
Vložil
Titulek

processing a android

Dobry den.
Chci se zeptat zda existuje i verze pro android.
Děkuji Honza.

© 2015 Všechna práva vyhrazena.

www.hwkitchen.com