Close

Processing

Processing funkce ellipse()

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 500×500. 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() {
}	
Hlavní okno Processing

Hlavní okno Processing

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(){}
Processing a funkce background()

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]);
    }
  }
}
Processing funkce stroke() a point()

Funkce stroke() a 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);
  }
}
Processing funkce stroke() a fill()

Funkce stroke() a fill()

 

Č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); 
}
Processing funkce quad()

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);
}
Processing funkce fill() a rect()

Funkce fill() a rect()

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);
}
Processing funkce rect()

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);
}
Processing funkce rect()

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);
}
Processing funkce triangle()

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);
}
Processing funkce ellipse()

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); 
  }
}

 

Processing funkce arc()

Funkce arc()



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.

 

Zbyšek Voda

4 Comments on “Processing

Zbyňa
8.6.2016 at 19:12

Ahoj. Prosím tě. Zkoušel jsi v procesing psat v módu android?

Zbyšek Voda
9.6.2016 at 13:44

Dobrý den, bohužel ne. Co byste potřeboval vytvořit?

Roman
18.1.2015 at 12:31

Dobry den
Mam otazku ohladne komunikacie procesing-u a arduina.
Ako ten procesing spracuje pichadzajuce udaje s arduina a naprikalad vypise ich niekde (napr. teplotu) do okna (vedla vypisaneho tlaku tiez meraneho arduinom) a zapise (raz za hodinu) do tabulky ktoru lahko prenesiem do xecelu pre tvorbu grafu. Dakujem

Zbyšek Voda
18.1.2015 at 14:26

Dobrý den.

Článek o komunikaci Arduina s Processing vyjde v dohledné době.
O jednoduchém způsobu zápisu do XLS souboru nevím, ale pokud stačí zapisovat do TXT, tak bude fungovat tento kód: https://www.processing.org/reference/PrintWriter.html

Napsat komentář