62
Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo 0 Univerza v Ljubljani Naravoslovnotehniška fakulteta Oddelek za tekstilstvo, grafiko in oblikovanje Katedra za informacijsko in grafično tehnologijo Uvod v Processing Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim potrebam smeri Grafične in medijske tehnike ter Grafične in interaktivne komunikacije (1. in 2. stopnja), ki se izvajajo na Katedri za informacijsko in grafično tehnologijo (Oddelek za tekstilstvo grafiko in oblikovanje). Povezava do knjige je dostopna na: https://www.slideshare.net/mudzinge/gettingstartedwithprocessing. Dostopna pa je tudi na portalu platforme Processing.org, kjer se nahaja veliko uporabnega materiala. Povzela in pripravila: Helena Gabrijelčič Tomc

Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

0

Univerza v Ljubljani Naravoslovnotehniška fakulteta Oddelek za tekstilstvo, grafiko in oblikovanje Katedra za informacijsko in grafično tehnologijo

Uvod v Processing Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim potrebam smeri Grafične in medijske tehnike ter Grafične in interaktivne komunikacije (1. in 2. stopnja), ki se izvajajo na Katedri za informacijsko in grafično tehnologijo (Oddelek za tekstilstvo grafiko in oblikovanje). Povezava do knjige je dostopna na: https://www.slideshare.net/mudzinge/gettingstartedwithprocessing. Dostopna pa je tudi na portalu platforme Processing.org, kjer se nahaja veliko uporabnega materiala.

Povzela in pripravila: Helena Gabrijelčič Tomc

Page 2: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

1

Kazalo vsebine

1 Processing 3

1.1 Osnove programiranja v Processingu 3

1.2 Risanje 4

1.2.1 Točka 4

1.2.2 Risanje elipse 4

1.2.3 Risanje premikajočih se, interaktivnih krogov 4

2 Osnovni liki in oblike 6

2.1 Linija 6

2.2 Večkotniki 6

2.3 Kvader in krogla 7

2.4 Lok 8

2.5 Zaporedje risanja 9

2.6 Lastnosti risanja (oblik) 9

2.7 Risanje poljubnih oblik 11

2.8 Barve 11

2.9 Določanje prosojnosti 13

3 Spremenljivke 14

3.1 Operatorji 15

3.2 Ponavljanja (ang. Repetition) 16

4 Odzivnost 19

4.1 Funkcija Draw 19

4.2 Funkcija Setup 19

4.3 Sledenje 20

4.4 Neprekinjeno risanje 21

4.5 Funkcija Map() 22

4.6 Odziv na klikanje 23

4.7 Lokacija 25

4.8. Črke (ang. Tape) 27

4.8.1 Pisanje črk in besedila 28

Page 3: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

2

5 Mediji 30

5.1 Slike 30

5.2 Fonti 31

5.3 Skladiščene besedila v nizu String 33

5.4 Vektorska grafika 34

6 Gibanje 35

6.1 Hitrost in smer 35

6.2 Interpolacija 36

6.3 Naključnost 37

6.4 Časovnik 38

6.5 Nihanje 39

6.6 Premiki, rotacije in skaliranje 41

6.7 Rotacija 42

6.8 Skaliranje 44

7 Funkcije 45

7.1 Vračanje vrednosti 47

8 Objekti 48

8.1 Objekti in razredi (ang. Objects and classes) 48

8.2 Ustvarjanje objekta 49

8.3 Določanje več objektov 51

9 Zbirke (ang. Arrays) 52

9.1 Ponavljanje in zbirke 55

9.2 Zbirke objektov 55

10 Napredne rešitve 57

10.1 3D grafika 57

10.2 Luči 58

10.3 Kamera 60

Page 4: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

3

1 Processing

Java je objektno orientiran, prenosljiv programski jezik. Processing je fleksibilna programska

skicirka in jezik, ki omogoča kodiranje v kontekstu vizualne umetnosti. Processing je dostopen

na https://processing.org/.

Komentarji v kodi se označujejo z // To je komentar, ki se ne bo izrisal na slikovni površini

1.1 Osnove programiranja v Processingu

Kodo pišemo ukaznem oknu, kot prikazuje spodnja slika.

Rezultati pa se izpisujejo v prikazovalnem oknu (Display Window) oknu , potem ko

uporabimo gumb za predvajanje Play .

Koda je sestavljena iz funkcij (Functions), ki so osnovni gradniki programa Processing.

Obnašanje funkcij je določeno s parametri (Parameters). Tako recimo se običajni dokument v

Processingu začne s funkcijo size(), ki določa višino in širino prikazovalnega okna. Ukaz

size(480, 120); torej omogoča izris okna širine 480 in višine 120 slikovnih točk. Ukaz se zaključi

s podpičjem.

Page 5: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

4

1.2 Risanje

1.2.1 Točka

Risanje točke omogoča funkcija point(). V oklepaju podamo X in Y koordinate njene lege glede

na površino izrisa. Zaporedje spodnjih funkcij torej na površini 480*480 slikovnih točk ustvari

štiri slikovne točke, ki imajo X in Y vrednosti (100,100), (100,300), (300,100) in (300,300).

size(480, 480); point(100,100); point(100,300); point(300,100); point(300,300);

size(100, 100); point(50,50); point(53,53); point(56,56); point(59,59);

1.2.2 Risanje elipse

V ukazno okno vpišite spodnjo kodo, ki vam izriše elipso, katere središče je 50 slikovnih točk

oddaljeno v smislu višine in dolžine od začetka slikovne površine levo zgoraj 0,0. Višina in

dolžina elipse (v tem primeru je to krog) sta 80 slikovnih točk.

ellipse(50, 50, 80, 80);

1.2.3 Risanje premikajočih se, interaktivnih krogov

S spodnjo kodo bomo izdelali interaktivne kroge, ki se premikajo glede na premikanje miške.

void setup() {

Page 6: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

5

size(650, 650);

}

void draw() {

if (mousePressed) {

fill(0);

} else {

fill(255);

}

ellipse(mouseX, mouseY, 80, 80);

}

Prvi del kode void setup() omogoča izris površine izrisa 650*650 slikovnih točk size(650, 650).

Drugi del kode void draw() vključuje pogojni stavek za interakcijo z miško if (mousePressed), ki

pove ukaz, da če je prisotna interakcija z miško, ki je kliknjena, naj se izrisujejo črni krogi

(fill(0)), sicer (else) pa beli fill(255). Zadnji del kode določa, da se izrisuje elipsa velikosti 80*80

slikovnih točk, ki pa ima pozicijo X in Y glede na premikanje miške: ellipse(mouseX, mouseY,

80, 80).

Page 7: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

6

2 Osnovni liki in oblike

2.1 Linija

Definicija linije je mogoča s funkcijo line(x1,y1,x2,y2) pri čemer sta koordinati x1 in y1

koordinati izhodišča linije, koordinati x2 in y2 pa konca linije. Spodnji primer prikazuje izris

treh linij, ki se povezujejo na površini velikosti 200*400 slikovnih točk.

size(200,400); line(50,50,150,150); line(50,250,150,350); line(50,250,150,150);

Trikotnik se definira s koordinatami treg oglišč na površini izrisa triangle(x1,y1,x2,y2,x3,y3).

Označevanje od 1 do 3 poteka v smeri urinega kazalca.

size(500,500); triangle(250,100,100,300,400,450);

2.2 Večkotniki

Večkotniki so definirani z oglišči in njihovimi koordinatami x in y. Označevanje od 1 do 3 poteka

v smeri urinega kazalca.

Page 8: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

7

size(500,500); quad(100,100,400,100,450,350,150,450);

Medtem ko spremenjen vrstni red oglišč in njihovih koordinat da spodnji rezultat.

size(500,500); quad(100,100,400,100, 150,450,450,350);

2.3 Kvader in krogla

Kvadrat in krogla sta definirana z rect(x,y,width,height) ter ellipse (x,y,width,height). Pri čemer x in y pri pravokotniku pomeni levo zgornje oglišče, pri elipsi pa center elipse. Width in height pomenita geometrijsko širino in višino likov. Processing nima posebnih funkcij za krog in kvadrat, tako da sta v primeru potrebe ustvarjanja teh likov uporabni funkciji rect() in ellipse(), pri katerih je določena višina in širina lika enaka. Kvadre in elipse lahko rišemo tudi tako da ju postavimo iz sredine (kvader) - rectMode() ali iz levega zgornjega konca - ellipseMode().

Page 9: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

8

size(500,500); rect(100,100,200,200); ellipse(350,350,200,100);

2.4 Lok

Lok je definiran z arc(x,y,width,height, start, stop). Start in stop sta v enoti radianih.

size(500,500); arc(250,250,200,200, 0, PI+HALF_PI);

size(500,500);

arc(250,250,200,200, 0, HALF_PI);

____________

size(500,500);

arc(250,250,200,200, PI, TWO_PI+HALF_PI);

____________

size(500,500);

arc(250,250,200,200, QUARTER_PI, PI+QUARTER_PI);

Page 10: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

9

2.5 Zaporedje risanja

Ker program bere kodo od prve vrstice do zadnje ter tako tudi izrisuje ukaze, je potrebno pri

risanju upoštevati določeno zaporedje prikaza likov na slikovni površini. To je prikazano na

spodnji slikah.

size(500, 500); triangle(250,100,100,300,400,450); ellipse(350,350,200,100);

size(500, 500); ellipse(350,350,200,100); triangle(250,100,100,300,400,450);

2.6 Lastnosti risanja (oblik) Osnovne lastnosti risanja oblik (likov) so glajenje linije (ang. antialiasing) z ukazi smooth() in noSmooth() ter debelina črte (ang. stroke) z ukazom strokeWeight(), kjer v oklepaju podamo želeno debelino črte v slikovnih točkah.

size(500, 500); triangle(250,100,100,300,400,450); smooth();

size(500, 500); triangle(250,100,100,300,400,450); noSmooth();

size(500, 500); smooth(); triangle(250,100,100,300,400,450); strokeWeight(8); ellipse(350,350,200,100); strokeWeight(25);

Page 11: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

10

Z ukazi lahko tudi določimo načine risanja začetnih in zaključnih delov strokeJoin() linij ter robov oblik strokeCap().

size(500, 500); smooth(); strokeWeight(20); strokeJoin(ROUND); quad(100,100,400,100,450,350,150,450);

size(500, 500); smooth(); strokeWeight(20); strokeJoin(BEVEL); quad(100,100,400,100,450,350,150,450);

size(500, 500); smooth(); strokeWeight(20); strokeCap(SQUARE); line(70, 25, 340, 250); strokeCap(ROUND); line(70, 200, 340, 450);

Page 12: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

11

2.7 Risanje poljubnih oblik To omogočajo funkcije beginShape(), s katero definiramo začetek, vertex(), s katero definramo oglišča (točke) v smislu x in y koordinat ter endShape(), ki obliko zaključi. Če v oklepaju endShape() uporabimo CLOSE, bo oblika avtomatično zaključena. size(500, 250); beginShape(); vertex(50, 50); vertex(50, 100); vertex(255, 150); vertex(350, 75); endShape(CLOSE);

2.8 Barve

Sivinske odtenke določa enoštevilčna vrednost, ki jo določimo funkcijam: background() - ozadje, fill() – polnilo in stroke() - barva obrobe. Sivinske barve so določene z vrednostmi od vrednosti 0 (črna) do 255 (bela). Polnilo in obrobo lahko tudi kontroliramo z noFill() ter noStroke(). size(500, 500); smooth(); background(50); fill(120); triangle(250,100,100,300,400,450); strokeWeight(8); fill(200); stroke(230); ellipse(350,350,200,100); strokeWeight(25);

size(500, 500); smooth(); background(50); noFill(); triangle(250,100,100,300,400,450); strokeWeight(8); fill(200); noStroke(); ellipse(350,350,200,100); strokeWeight(25);

Page 13: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

12

Barvne vrednosti RGB določamo s trištevilčnimi parametri funkcij : background() - ozadje, fill() – polnilo in stroke() - barva obrobe. Barve se lahko določajo tudi v urejevalniku barv (ang. color selector): Tools – Color Selector.

size(500, 500); smooth(); background(255,0,0); fill(100,255,255); triangle(250,100,100,300,400,450); strokeWeight(8); fill(0,200,0); stroke(0,0,200); ellipse(350,350,200,100); strokeWeight(25);

Page 14: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

13

2.9 Določanje prosojnosti Transparenco določamo s četrto številčno vrednostjo v funkcijah background() - ozadje, fill() – polnilo in stroke() - barva obrobe, s številkami od 0 (popolnoma transparentno) do 255 (netransparentno), kot prikazuje spodnji primer.

size(500, 500); noStroke(); smooth(); background(50); fill(255, 160); rect(150, 150, 200, 200); fill(0, 150, 0, 200); rect(200, 300, 200, 200); fill(0, 0, 100, 75); ellipse(350, 125, 100, 200);

Page 15: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

14

3 Spremenljivke

Spremenljivke shranjujejo vrednosti v spominu z namenom kasnejše uporabe v programu. Če tako recimo želimo narediti tri zaporedne kvadrate, ki imajo enako vrednost začetka izrisa y ter višino in širino, vendar različne vrednosti x, lahko to naredimo z definicijo vrednosti y ter višine in širine, ki se bodo ponavljale, tako kot prikazuje spodnji primer. Sprememba spermenljivk torej spremeni vrednosti v vseh funkcijah, ki vključujejo to spremenljivko. size(500, 250); smooth(); int y=75; int a=100; rect(50,y,a,a); rect(150,y,a,a); rect(250,y,a,a); rect(350,y,a,a);

size(500, 250); smooth(); int y=25; int a=75; rect(50,y,a,a); rect(150,y,a,a); rect(250,y,a,a); rect(350,y,a,a);

Spremenljivke definirajo: ime (name), vrsta podatkov (dataType) in vrednost (value). Ime lahko določimo sami, le bodimo previdni pri imenih, da si jih izberemo tako, da bom njihov pomeni prepoznali tudi pri nadaljnjih uporabah v kodi. V kodi ne smemo imeti dveh spremenljivk z enakim imenom. Spremenljivke lahko definiramo na načine: int a; a = 75; ali int a = 75; Zapis funkcij kot int a; int a=75; pa bo program javil kot napako ker smatra, da sta definirani spremenljivki z enakim imenom. Lastnosti spremenljivk so tudi slednje, da se prilagajajo relativno na funkcije. Tako recimo je prikazano v spodnjem primeru, kjer sta spremenljivki height in width spremenljivki funkcije size().

Page 16: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

15

size(500, 250); smooth(); line(width/2, 0,width/2,height); line(0, height/2,width,height/2); ellipse(width/4, height/4, 80, 80); ellipse(width*3/4, height*3/4, 80, 80);

3.1 Operatorji Operatorji so aritmetične matematične funkcije vsote +, razlike -, množenja *, deljenja / ter enačaja =.

size(500, 250); int x = 50; int h = 40; int y = 75; ellipse(x, y, 100, h); x = x + 200; ellipse (x, y + h, 100, h); x = x + 200; ellipse (x, y + h*2, 100, h);

Pri aritmetiki v Processingu veljajo taka pravila kot v materatiki, torej: int x = 8 + (8 * 2); pomeni dodeli 26 spremenljivki x medtem ko int x = (8 + 8) * 2; pomeni dodeli 32 spremenljivki x Ker so nekateri izračuni pogosto uporabljeni, kot na primer: x += 50; pomeni isto kot x = x + 50 y -= 15; pomeni isto kot y = y – 15 Prav tako pa se zaradi pogoste uporabe prištevanja ali odštevanja vrednosti spremenljivke uporabljajo definicije: x++; ki pomeni enako kot x = x + 1 ter y--; ki pomeni enako kot y = y – 1

Page 17: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

16

3.2 Ponavljanja (Repetition) Pri programiranju se določeni deli kode večkrat ponavljajo, z manjšimi variacijami. Da si v takih primerih olajšamo delo, uporabljamo for zanke (ang. for loop), ki nam omogočajo manjšo količino podatkov v kodi. Spodnji primer prikazuje uporabo for zanke namesto pisanja dolge kode. Med zavitimi oklepaji { in } se nahajajo t.i. bloki (ang. block), to so deli kode, ki se bodo ponavljali. size(525, 250); smooth(); strokeWeight(5); rect(25, 50, 70, 70); rect (125, 50, 70, 70); rect (225, 50, 70, 70); rect (325, 50, 70, 70); rect (425, 50, 70, 70);

size(525, 250); smooth(); strokeWeight(5); for(int i=25;i<475;i+=100) { rect(i,50,70, 70); }

Struktura kode je sestavljena in iniciacije (ang. inicialization, init), testa (ang. test) ter posodabljanja (ang. update), tako kot prikazujejo spodnje vrstice. for (init; test; update) { statements } Vrednost init običajno določa novo spremenljivko, ki naj bo uporabljena v for zanki ter ji določi vrednost. Spremenljivka i je običajno uporabljena, sicer pa to ni točno določeno (in uporabljamo poljubno). Test oceni vrednost spremenljivke in osveži (update) spremembe vrednosti spremenljivke. Zaporedje je prikazano na sliki spodaj.

Page 18: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

17

Na tem mestu test zahteva več pojasnil. To je vedno relacijska trditev (ang. relational expression), ki primerja dve vrednosti z relacijskim operatorjem (ang. relational operator). V tem primeru je i < 400 izraz (ang. expression) in operator je < simbol (manjše kot). Najbolj uporabljeni operatorji so: > večji od < manjši od >= večji ali enak <= manjši ali enak == enak kot != ni enak kot

Relacijska trditev ocenjuje pritrdilno (true) ali napačno (false). Tako recimo, bi bila trditev 10<8 označena kot napačno. Ko je ocena pozitivna se izvede koda v bloku (block), ko pa je negativna (false), se koda ne izvede, for zanka pa se konča. Moč dela s for zankami je predvsem ta, da potem, ko je zanka pravilno napisana, lahko le z majhnimi nadaljnjimi spremembami zelo enostavno izdelamo različne izrise. To prikazujejo spodnji primeri. size(500, 175); smooth(); strokeWeight(4); for (int i = 25; i < 400; i += 10) { line(i, 50, i + 75, 100); }

size(500, 175); smooth(); strokeWeight(4); for (int i = 25; i < 400; i += 10) { line(i, 50, i + 75, 100); line(i,150, i+75,100); }

size(500, 175); smooth(); strokeWeight(4); for (int i = 25; i < 400; i += 10) { line(i, 50, i + 75, 100); line(i,100, i+75,50); }

size(500, 175); smooth(); strokeWeight(4); for (int i = 25; i < 400; i += 10) { line(i, 50, i + 75, 100); line(i,100, i+75,50); line(i,150, i+75,100); line(i,100, i+75,150); }

Page 19: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

18

For zanke se lahko pojavljajo tudi ena v drugi, kot prikazuje spodnji primer.

size(480, 120); background(0); smooth(); for (int y = 32; y <= height; y += 8) { for (int x = 12; x <= width; x += 15) { ellipse(x + y, y, 16 - y/10.0, 16 - y/10.0); } }

Page 20: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

19

4 Odzivnost 4.1 Funkcija Draw Pri uporabi spodnje kode: void draw() { println("Jaz pišem"); println(frameCount); } Nam funkcija void draw() v kozoli urejevalnika programa Processing piše stavke "Jaz pišem", dokler ne zapremo okna ali pritisnemo gumb Stop. Vsako dejanje draw() se imenuje okno ali slika (ang. frame). Println() je fukncija, ki izpisuje tekst, frameCount pa je posebna spremenljivka zaporedij (1, 2, 3, …).

4.2 Funkcija Setup Kot nasprotje funkciji draw() Processing omogoča funkcijo setup(), ki se požene le enkrat preden se program ustavi. V tipičnem programu se koda v setup() uporabi za določanje barve ozadja ter obrob ali pa za vnos slike ali določene pisave (če ne vključimo funkcije size(), bo predstavitveno okno velikosti 100*100 pisklov ter sive barve. V funkciji setup() lahko uporabimo tudi spemenljivke (ang. variables), ter če to storimo, jih nato ne moremo (smemo) uporabiti v draw(), tako da jih nato moremo uporabiti kje drugje. Takšne spremenljivke se

Page 21: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

20

imenujejo globalne spremenljivke (ang. global variables), saj se slednje lahko uporabljajo kjerkoli v programu. Postopek je jasneje predstavljen s spodnjim zaporedjem:

1. spremenljivka je določena izven setup() ali draw() 2. koda znotraj setup() je pognana enkrat 3. koda znotraj draw() je pognana neprekinjeno.

Sodelovanje setup() in draw() prikazuje spodnja koda: int x = 340; int y = -70; int diameter = 420; void setup() { size(500, 175); smooth(); fill(150); } void draw() { background(230); ellipse(x, y, diameter, diameter); }

4.3 Sledenje Ko imamo enkrat določeno kontinuirnost, lahko določimo slednje z miško. V spodnji kodi mouseX in mouseY označujeta gibanje miške po ekranu. V tem primeru funkcija void draw() omogoča, da so kvadrati z velikostjo 15 slikovnih točk po višini in širini izrisani z lokacijo miške mouseX in mouseY. void setup() { size(500, 175); fill(20, 175); smooth(); noStroke(); } void draw() { rect(mouseX, mouseY, 15, 15); }

Spodnja koda omogoča, da izrisani kvadrat sledi premiku miške. Pomembno je, da v kodi napišemo backgroud pred vsemi ostalimi fukncijami v void draw(), saj sicer interaktvnost ni mogoča. void setup() { size(500, 175); fill(50, 150); smooth();

void setup() { size(500, 175); fill(50, 150); smooth();

Page 22: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

21

noStroke(); } void draw() { background(125); rect(mouseX, mouseY, 20, 20); }

noStroke(); } void draw() { rect(mouseX, mouseY, 20, 20); background(125); }

4.4 Neprekinjeno risanje Spremenljivki pmouseX in pmouseY shranijo lokacijo miške na predhodnem okvirju (sliki, ang. frame) void setup() { size(500, 175); strokeWeight(10); smooth(); stroke(10, 150); } void draw() { line(mouseX, mouseY, pmouseX, pmouseY); }

Spremenljivke pmouseX in pmouseY se lahko uporabijo tudi za izračun hitrosti miške, ki se določa z merjenjem razdalje trenutke ter nazadnje hitrosti miške. Če je htrost miške majhna je razdalja prav tako majhna, sicer pa ravno obratno. Funkcija dist() olajša računanje, kot je prikazano v spodnjem primeru, kjer je hitrost miške. void setup() { size(500, 175); smooth(); stroke(10, 150); } void draw() { float weight = dist(mouseX, mouseY, pmouseX, pmouseY); strokeWeight(weight); line(mouseX, mouseY, pmouseX, pmouseY); }

Page 23: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

22

Ker večkrat želimo, da se izris zgodi z nekakšnim zamikom z akcijo miške, je uporabna tehnika pojemanja (ang. easing), kot prikazuje spodnja koda izrisa kvadrata z interakcijo miške, katerega izris se dogaja z zamikom glede na gibanje miške. V konzoli se tudi vidi ponavljajoče izrisovanje spremenljivke drawn. Poskusimo lahko z več vrednosti zamika (ang. easing), kot so 0.1, 0.2, 0.3 itd. float x; float easing = 0.01; float diameter = 12; void setup() { size(500, 175); smooth(); } void draw() { float targetX = mouseX; x += (targetX - x) * easing; rect(x, 80, 30, 30); println(targetX + " : " + x); }

4.5 Funkcija Map() Interakcija miške in izris recimo linije lahko potekata tudi tako, da izris ne sega do konca izrisnega okna. V tem primeru lahko uporabljamo tudi spremenljivko tako da mouseX delimo ali množimo z vrednostmi, tako da dobimo želen učinek izrisa (recimo linije). Namesto deljenja ali množenja lahko uporabimo tudi funkcijo map(). Funkcija map() spreminja en obseg vrednosti v drugega. Prva vrednost v funkciji je spremenljivka, ki naj bo spremenjena (konvertirana), druga in tretja parametra sta najnižja in najvišja vrednost spremenljivke, četrta in peta vrednost pa sta najvišja in najnižja vrednost. void setup() { size(500, 175); strokeWeight(12); smooth(); }

void setup() { size(500, 175); strokeWeight(12); smooth(); }

Page 24: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

23

void draw() { background(204); stroke(255,0,0); rect(mouseX, mouseY,30,30); // rdeč kvadrat stroke(0,0,255); float mx = mouseX/2 + 60; rect(mx, mouseY,30,30); // moder kvadrat }

void draw() { background(204); stroke(255,0,0); rect(mouseX, mouseY,30,30); // rdeč kvadrat stroke(0,0,255); float mx = map(mouseX, 0, width, 60, 180); rect(mx, mouseY,30,30); // moder kvadrat }

4.6 Odziv na klikanje V Prcessingu spremenljivka mousePressed omogoča akcijo, ki je odvisna od klika miške (in ne le njene lokacij). Spodnja koda prikazuje izris, ki ob kliku na vodoravno (poševno) črto spremeni barvo v temnejšo. V spodnji kodi velja izris črte v temnejšo barvo le, če je miška kliknjena, kar je prikazano s stavkom if, ki se podobno kot zanka for izjava na spodnji način: if (test) { statements } void setup() { size(500, 175); smooth(); strokeWeight(20); } void draw() { background(50); stroke(210); line(40, 0, 70, height); if (mousePressed == true) { stroke(25);

Page 25: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

24

} line(0, 70, width, 50); }

Simbol == ni enako kot =, saj pomeni vprašanje, ali sta elementa na desno in levo od == enaka (medtem ko simbol = dodeli vrednost spremenljivki). V zgornjem primeru bi lahko namesto if (mousePressed == true) uporabili tudi le if (mousePressed). Rezultat pa bi bil enak. Glede na zgornjo kodo lahko zapišem tudi nekaj nadaljnjih variant. Z ukazi if in else, torej da bo linija izrisana črno le če bo miška kliknjena if (mousePressed) { stroke(0); sicer pa naj bo črta bela else { stroke(255); Primer na desni pa pove, da sta aktivna tako desni kot levi klik, če bomo z miško kliknili na desni klik bo črta vodoravna bela, če pa z levim klikom bo črta črna. void setup() { size(500, 175); smooth(); strokeWeight(60); } void draw() { background(150); stroke(102); line(40, 0, 250, height); if (mousePressed) { stroke(0); } else { stroke(255); } line(0, 70, width, 50); }

void setup() { size(500, 175); smooth(); strokeWeight(60); } void draw() { background(204); stroke(102); line(40, 0, 150, height); if (mousePressed) { if (mouseButton == LEFT) { stroke(255); } else { stroke(0); } line(0, 70, width, 50); } }

Page 26: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

25

Strukture if…else lahko imajo več možnosti, določa pa se kateri blok kode se bo izvedel. To prikazujejo spodnje sheme.

4.7 Lokacija Struktura if se lahko uporabi skupaj z vrednostmi mouseX in mouseY tako da določimo lokacijo kurzorja v izrisnem oknu. V spodnjem primeru ugotavljamo s kodo lokacij kurzorja ter glede na to izrišemo krog. Podane imamo spremenljivke int x=250 ter int y=80, ki določata pozicijo kroga radija 30 slikovnih pik. Ukaz ellipseMode(RADIUS) pove da rišemo elipso iz sredine (torej sta določeni točki začetka na sredini v središču kroga). Nato je vključena funkcija void draw(), ki se ponavlja (kot je bilo povedano na prejšnjih straneh). Dist() funkcijo uporabljamo za testiranje, ali je kurzor v notranjosti kroga ali izven. Če je v notranjosti, torej if (d < radius), se radij poveča za dvakratno vrednost ter se obarva s črno barvo, sicer pa je krog bel, s središčem v spremenljivki x in y ter naj ima tako vrednost kot nazadnje določeni radij. Test je torej definiran v smislu, če je dist(x

Page 27: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

26

,y, mouse X, mouse Y)›radij se išče izven kroga, če pa je dist(x ,y, mouse X, mouse Y) ‹radij, iščemo v krogu. V kodi na desni spodaj pa imamo primer preverjanja z if, kjer ugotavljamo, ali je kurzor znotraj kvadra definiranega s spremenljivkami int x, int y, int w in int h (torej koordinati začetne točke x in y ter širina w in višina h). V if stavku imamo pogoj, da če je lokacija miške v smeri x večja od spremenljivke x, vendar manjša od vrednosti x+w ter večja od vrednosti spremenljivke y vendar manjša od vrednosti y+h, naj bo kvader obarvan zeleno, sicer pa rdeče. Simbol && je logični operator IN ali po angleško AND. int x = 250; int y = 80; int radius = 30; void setup() { size(500, 175); smooth(); ellipseMode(RADIUS); } void draw() { background(204); float d = dist(mouseX, mouseY, x, y); if (d < radius) { radius++; fill(0); } else { fill(255); } ellipse(x, y, radius, radius); }

int x = 200; int y = 50; int w = 80; int h = 60; void setup() { size(500, 175); } void draw() { background(150); if ((mouseX > x) && (mouseX < x+w) && (mouseY > y) && (mouseY < y+h)) { fill(150,0,0); } else { fill(0,150,0); } rect(x, y, w, h); }

Page 28: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

27

4.8. Črke (Tape) Processing spremlja ko so na tipkovnici računalnika uporabljene (kliknjene) tipke, prav tako tudi spremlja zadnjo kliknjeno tipko. Tako kot spremenljivka mousePressed, deluje tudi spremenljivka keyPressed tako da je »pravilno« (true), ko je tipka uporabljena ter »napačno« (false), ko tipka ni uporabljena. Pri tem se uporablja test pravokotnika, ki pokrova določene dele zaslona (rectangle rollover test, glej vir: https://www.slideshare.net/mudzinge/gettingstartedwithprocessing). Spodnja koda prikazuje delovanje spremenljivke keyPressed, ki je uporabljena v stavku if, torej le v primeru, ko pritisnemo tipko na tipkovnici, se izriše druga črta, ki diagonalno prekriža prvo. void setup() { size(500, 250); smooth(); } void draw() { background(150); line(25, 25, 475, 215); if (keyPressed) { line(25, 215, 475, 25); } }

Črke se določa z okrajšavo besede character (char), kot je prikazano spodaj. Definicija črke mora biti točno tako napisana, kot je prikazano spodaj ko koda dodeli črko A spremenljivki c. Spremenljivka key obdrži svojo vrednost (črko) dokler ni kliknjena druga črka. char c = 'A';

Page 29: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

28

4.8.1 Pisanje črk in besedila V spodnji kodi je predstavljena funkcija textSize(), ki določi velikost črk, textAlign() funkcija, ki centrira tekst na x-koordinati in text(), ki izriše črko. Pisanje črk bo razloženo nekoliko kasneje v skripti. void setup() { size(120, 120); textSize(64); textAlign(CENTER); } void draw() { background(0); char c = 'A'; text(c, 60, 80); }

void setup() { size(120, 120); textSize(64); textAlign(CENTER); } void draw() { background(0); char c = 'A'; if (keyPressed) { text(c, 60, 80); } }

Spodnja koda pri kliku tako na tipko črke h ali velike H ter n ali velike N izriše črki do konca void setup() { size(120, 120); smooth(); } void draw() { background(204); if (keyPressed) { if ((key == 'h') || (key == 'H')) {

Page 30: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

29

line(30, 60, 90, 60); } if ((key == 'n') || (key == 'N')) { line(30, 20, 90, 100); } } line(30, 20, 30, 100); line(90, 20, 90, 100); }

Nekatere tipke je zelo težko detektirati, saj niso vezane na določeno črko. Tipke kot Shift, Alt, Ctrl ter tipke puščic navzgor, navzdol itd. so kodirane ter potrebujejo dodaten korak, ki preveri ali so kliknjene. Prvo moramo torej preveriti, če je tipka, ki je bila kliknjena kodirana, nato pa preverimo s spremenljivko keyCode, katera tipka je bila uporabljena. int x = 215; void setup() { size(500, 250); } void draw() { if (keyPressed && (key == CODED)) { // preverimo če je kodirana tipka if (keyCode == LEFT) { // če je tipka leva puščica x--; } else if (keyCode == RIGHT) { // če je tipka desna puščica x++; } } rect(x, 75, 75, 75); }

Page 31: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

30

5 Mediji

5.1 Slike Processing uporablja mapo data, kjer shranjuje medije kot so rastrske slike (jpg, gif, png), ilustracije, vektorske slike. Mapo data dobimo v meniju Sketch izberemo Add file. Če mape tam, bo avtomatično ustvarjen tako, da v okno Processing urejevalnika poskusim ustaviti recimo sliko, v meniju Sketch ter pod ukazom Show sketch folder bo nastala mapa z imenom Data, kjer so shranjene slike, ki smo jih prenesli v urejevalnik Processinga. Ko pišemo ime slike v ukazo okno Processinga je vedno potrebno napisati poleg pravilnega imena slike tudi format .jpg, .gif ali png. Obstajajo trije koraki uporabe slike: 1. sliko naložimo v mapo Data, kot je bilo predstavljeno v predhodnih stavkih, 2. ustvarimo spremenljivko PImage, kjer bo slika shranjena ter 3. naložimo sliko v spremenljivko z ukazom loadImage(). Funkcija, ki prikliče sliko se nato glasi image(img,x,y), kjer img specificira katera slika se bo izrisala, x in y pa sta koordinati začetka slike, kot prikazuje spodnja slika: PImage img; void setup() { size(700, 467); img = loadImage("Flower-Life.jpg"); } void draw() { image(img, 0, 0); }

Ko se v oklepaju uporabi vrednosti mouseX in mouseY kot četrta in peta vrednost ukaza image(), se dimenzije slike spreminjajo z gibanjem miške, kot je prikazano spodaj. Ker je lahko slika pri prikazu neusklajena glede razmerja višine in širine, je potrebno sliko ustrezno pripraviti v programih za pripravo slik.

PImage img;

Page 32: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

31

void setup() { size(700, 500); img = loadImage("Flower-Life.jpg"); } void draw() { background(0); image(img, 0, 0, mouseX, mouseY); }

PImage img; void setup() { size(700,467); img = loadImage("Fower-Life.jpg"); } void draw() { background(204); image(img, 0, 0); image(img, 0, mouseY * -1); }

5.2 Fonti Fonte ustvarimo z ukazi Tools (glavni meni) ter Create font…. Kjer izberemo želeni font in njegove velikosti. S klikom na OK se font ustvari v mapi Data kot format .vlw.

Page 33: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

32

Delo s fonti je podobno kot s slikami, le da je tu potreben en dodaten korak: 1. dodajanje vrste fonta v data mapo; 2. ustvarjanje PFont spremenljivke, ki hrani font; 3. nalaganje fonta v spremenljivko z loadFont() ter uporaba ukaza textFont(), ki nastavi določen font. V nadaljevanju tako lahko uporabimo funkcijo text() ter spreminjamo velikost z textSize(). PFont font; void setup() { size(500, 250); smooth(); font = loadFont("ArialMT-48.vlw"); textFont(font); } void draw() { background(75); textSize(40); text("Danes je prečudovit dan...", 35, 100); textSize(22); text("Danes je prečudovit dan...", 35, 170); }

Če v funkciji text() dodamo še četrto in peto številčno vrednost bo tekst zapisan znotraj izrisanega okna.

Page 34: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

33

PFont font; void setup() { size(500, 250); font = loadFont("ArialMT-48.vlw"); textFont(font); } void draw() { background(75); text("Danes je prečudovit dan...", 26, 30, 250, 250); }

5.3 Skladiščene besedila v nizu String

Besedilo, ki ga zapišemo v funkciji text(), je lahko skladiščeno tudi v nizu tipa podatkov t.i. String, ki vključuje tekstovne podatke. S String lahko torej zgornjo kodo zapišemo kot: PFont font; String quote = "Danes je prečudvit dan…"; void setup() { size(500, 350); font = loadFont("ArialMT-48.vlw"); textFont(font); } void draw() { background(75); textSize(48); text(quote, 26, 30, 250, 250); textSize(30); text(quote, 26, 270, 250, 500); }

Page 35: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

34

5.4 Vektorska grafika V Processingu deluje tudi .svg, ki ga lahko ustavimo v treh korakih:

1. dodajanje .svg v mapo podatkovnih skic (sketch data) 2. ustvarjanje PShape spremenljivke, ki hrani vektorsko datoteko 3. nalaganje vektorja v spremenljivko loadShape().

Nato lahko vektorsko obliko naložimo s funkcijo shape().

PShape vektor; void setup() { size(500, 250); smooth(); network = loadShape("vektor.svg"); } void draw() { background(0); shape(vektor, 30, 10); shape(vektor, 180, 10, 280, 280); }

Page 36: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

35

6 Gibanje Processing poganja 60 slik na sekundo ter omogoča gibanje z ukazi: void draw() { println(frameRate); } Če želimo drugačno število slik, ki se prikazujejo/sek. Lahko to določimo tako, kot je prikazano spodaj. void draw() { println(frameRate); } void setup() { frameRate(15); }

6.1 Hitrost in smer Ustvarjanje zveznega gibanja je možno s podatkovnim tipom spremenljivk float, ki določa številke (tudi z decimalnimi vrednostmi) za doseganje večje ločljivosti pri delu z gibanjem. Tako lahko uporabljamo številke 1.01, 1.02 itd. Spodaj prikazani primer premika obliko od leve proti desni tako da osvežuje v spremenljivko: int radius = 80; float x = -radius; float speed = 1; void setup() { size(500, 250); smooth(); ellipseMode(RADIUS); } void draw() { background(0); x += speed; // poveča vrednost x arc(x, 60, radius, radius, 1, 5); }

Spodnji primer prikazuje, kako lahko enostavni lik popeljemo od leve proti desni, lik pa se, ko pride na konec površine, obrne ter potuje v drugo smer, torej od desne proti levi.

Page 37: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

36

int radius = 40; float x = 110; float speed = 0.5; int direction = 1; void setup() { size(240, 120); smooth(); ellipseMode(RADIUS); } void draw() { background(0); x += speed * direction; if ((x > width-radius) || (x < radius)) { direction = -direction; // zamenja smer } if (direction == 1) { arc(x, 60, radius, radius, 0.52, 5.76); // oblika kaže v desno } else { arc(x, 60, radius, radius, 3.67, 8.9); // oblika kaže v levo } }

6.2 Interpolacija Interpolacijo med dvema ključnima sličicama se določa tako, da pred glavno kodo določimo skupino spremenljivk, ki bodo ustrezne prehode omogočale, kot prikazuje spodnja koda. int startX = 20; // začetna koordinata x int stopX = 420; // končna koordinata x int startY = 30; // začetna koordinata y int stopY = 180; // končna koordinata y float x = startX; // trenutna koordinata x float y = startY; // trenutna koordinata y float step = 0.009; // velikost vsakega koraka (0.0 to 1.0) float pct = 0.0; // procent potovanja (0.0 to 1.0) void setup() { size(500, 250); smooth(); } void draw() { background(0); if (pct < 1.0) { x = startX + ((stopX-startX) * pct); y = startY + ((stopY-startX) * pct); pct += step; }

Page 38: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

37

ellipse(x, y, 50, 50); }

6.3 Naključnost Naključnost določamo s funkcijo random() Spodnji primer prikazuje kako lahko kvadrat uporabo interakcije z miško linije iz naključno "razmečemo" kvadrat po površini izrisa. float speed = 2.5; int width = 20; float x; float y; void setup() { size(200, 100); smooth(); x = width/2; y = height/2; } void draw() { x += random(-speed, speed); y += random(-speed, speed); rect(x, y, width, width); }

Če ne želimo, da kvadrat uide izven površine izrisa dodamo omejitev gibanja, kot prikazuje spodnja koda: float speed = 2.5;

Page 39: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

38

int width = 20; float x; float y; void setup() { size(200, 100); smooth(); x = width/2; y = height/2; } void draw() { x += random(-speed, speed); y += random(-speed, speed); x = constrain(x, 0, width); y = constrain(y, 0, height); rect(x, y, width, width); }

6.4 Časovnik Vsak Processing program šteje čas, ko se je zagnala določena koda v milisekundah, to lahko uporabimo za animacije, ki na se zgodijo ob točno določenem času. Pri tem funkcija millis() izpisuje to vrednost štetja. V konzoli urejevalnika Processing lahko minevanje časa opazujemo s kodo: void draw() { int timer = millis(); println(timer); } V spodnji kodi je tako predstavljeno, kako lahko začnemo animacijo pri 2 sek, poleg tega pa se po 4 sek spremeni smer animacije. Spremenljivki sta torej time1 in time2, ki določata, kdaj naj se vrednost spremenljivke x spremeni. Pri tem je gibanje v desno po 2 sek bistveno hitreje (x += 2;), kot pa v levo po 4 sek (x -= 0.5;). int time1 = 2000; int time2 = 4000; float x = 0; void setup() { size(500, 250); smooth(); } void draw() { int currentTime = millis(); background(204); if (currentTime > time2) { x -= 0.5; } else if (currentTime > time1) {

Page 40: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

39

x += 2; } rect(x, 60, 100, 100); }

6.5 Nihanje Funkcije sin() and cos() vrnejo vrednosti med –1 in 1 za določene vrednosti kotov teh dveh funkcij. Tako kot kadar določimo kot s funkcijo arc(), morajo biti vrednosti kotov podane v radianih. Da pa sta funkciji sin in cos ugodni za uporabo morata biti množen z večjo vrednostjo. V spodnje primeru se funkcija sin() uporablja za spremembo vrednosti med –1 in 1, s tem ko se vrednost kota povečuje. Funkcija map() se spremenljivka sinval spremeni iz vrednosti od -1 do 1 v vrednosti od 0 do 255. Nove vrednosti so uporabljene za določanje novih barvnih vrednosti ozadja izrisnega okna. float angle = 0.0; void draw() { float sinval = sin(angle); println(sinval); float gray = map(sinval, -1, 1, 0, 255); background(gray); angle += 0.1; }

V spodnji kodi je predstavljeno gibanje treh krogov v smislu sinusnega valovanja. Spremenljivka scalar omogoči drugačno intenziteto nihanja. float angle = 0.0; float offset = 100; float scalar = 60; float speed = 0.05; void setup() {

Page 41: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

40

size(500, 250); smooth(); } void draw() { background(0); float y1 = offset + sin(angle) * 0.5 *scalar; float y2 = offset + sin(angle + 0.4) * scalar; float y3 = offset + sin(angle + 0.8) * 1.5 *scalar; ellipse( 80, y1, 40, 40); ellipse(160, y2, 40, 40); ellipse(220, y3, 40, 40); angle += speed; }

Vrednost scalar se lahko tudi povečuje pri izrisu vsake slike, kar omogoča izris spirale kot je prikazano spodaj. float angle = 0.0; float offset = 60; float scalar = 2; float speed = 0.05; void setup() { size(120, 120); fill(0); smooth(); } void draw() { float x = offset + cos(angle) * scalar; float y = offset + sin(angle) * scalar; ellipse( x, y, 2, 2); angle += speed; scalar += speed; }

Page 42: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

41

6.6 Premiki, rotacije in skaliranje Translacije ali premiki delujejo tako da pomaknejo koordinatno izhodišče, kot prikazuje spodnji primer, kjer so vsi kvadrati izrisani na koordinatah (0,0), le da se slednje premikajo zaradi funkcije translate(). void setup() { size(250, 250); } void draw() { translate(mouseX, mouseY); rect(0, 0, 50, 50); }

V spodnjem primeru je mali kvadrat izrisan z zamikom x+45 ter y+35 v primerjavi s prvim velikim kvadratom.

void setup() { size(250, 250); } void draw() { translate(mouseX, mouseY); rect(0, 0, 50, 50); translate(45, 35); rect(0, 0, 25, 25); }

Page 43: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

42

Transformacije se lahko osamimo tako, da ne vplivajo na nadaljnje ukaze. S tem namenom uporabimo funkcije pushMatrix() in popMatrix(). Funkcija pushMatrix() shrani kopijo trenutnih koordinat, medtem ko funkcija popMatrix() resetira sistem. Obe funkciji morata vedno biti uporabljeni v paru. V spodnjem primeru se mali kvadrat vedno izrisuje v levem zgodnjem kotu, saj je ukaz translate (mousex, mousey) resetiran iz strani funkcije popMatrix(). void setup() { size(250, 250); } void draw() { pushMatrix(); translate(mouseX, mouseY); rect(0, 0, 50, 50); popMatrix(); translate(45, 35); rect(0, 0, 25, 25); }

6.7 Rotacija Funkcija rotacije rotate() rotira koordinatni sistem in ima en parameter, ki je kot rotacije v radianih. Vedno rotira relativno na (0,0), ki je izvor rotacije. Če želimo vrteti obliko okoli središča je potrebno najprej uporabiti funkcijo translate() ter nato rotate(), tako kot je prikazano spodaj.

Page 44: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

43

float angle = 0.0; void setup() { size(250, 250); smooth(); } void draw() { translate(mouseX, mouseY); rotate(angle); rect(-15, -15, 50, 50); angle += 0.1; }

Če se zaporedje pojavitve v kodi funkcij translete() in rotate() spremeni je drugačen tudi rezultat, tako kot prikazuje spodnji primer, ki je izpeljan iz zgodnjega, le da je zaporedje obeh funkcij sedaj zamenjano. float angle = 0.0; void setup() { size(250, 250); smooth(); } void draw() { rotate(angle); translate(mouseX, mouseY); rect(-15, -15, 50, 50); angle += 0.1; }

Page 45: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

44

6.8 Skaliranje Tudi funkcja skaliranja scale() poveča ali pomanjša koordinate na izrisnem oknu. Torej je tudi tukaj potrebno najprej premakniti center oblike s funkcijo translate(), nato se jo skalira s funkcijo scale() ter nato izriše iz koordinat (0,0), kot je prikazano s spodnjo kodo. S premikom miške na izrisno okno se kvadrati premikajo po površini. float angle = 0.0; void setup() { size(400, 400); smooth(); } void draw() { translate(mouseX, mouseY); scale(sin(angle) + 2); rect(-15, -15, 50, 50); angle += 0.1; }

Page 46: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

45

7 Funkcije

Funkcije so osnovni gradniki Processing kode, ki so medseboj neodvisni zato se lahko modularno sestavljajo. Funkcije so tako size(), line(), fill(). Spodnja koda prikazuje izris sove brez funkcij z enostavnimi oblikami. Funkcija translate() je uporabljena za premik koordinatnega izhodišča, zato so nekatere koordinate tudi negativne. Če želimo sedaj narediti še eno sovo poleg prve je potrebno podvojiti dolžino kode (katere vsebina je ekrana), le da se premakne izhodišče v desno, kar bo omogočalo izris druge sove na novo mesto.

smooth(); } void draw() { background(204); translate(110, 110); stroke(0); strokeWeight(70); line(0, -35, 0, -65); // telo noStroke(); fill(255); ellipse(-17.5, -65, 35, 35); // podr. levega očesa ellipse(17.5, -65, 35, 35); // podr. desnega očesa arc(0, -65, 70, 70, 0, PI); // brada fill(0); ellipse(-14, -65, 8, 8); // levo oko ellipse(14, -65, 8, 8); // desno oko quad(0, -58, 4, -51, 0, -44, -4, -51); // kljun }

void setup() { size(480, 120); smooth(); } void draw() { background(204); translate(110, 110); stroke(0); strokeWeight(70); line(0, -35, 0, -65); // telo noStroke(); fill(255); ellipse(-17.5, -65, 35, 35); // podr. levega očesa ellipse(17.5, -65, 35, 35); // podr. desnega očesa arc(0, -65, 70, 70, 0, PI); // brada fill(0); ellipse(-14, -65, 8, 8); // levo oko ellipse(14, -65, 8, 8); // desno oko quad(0, -58, 4, -51, 0, -44, -4, -51); // kljun translate(70, 0); stroke(0); strokeWeight(70); line(0, -35, 0, -65); // telo noStroke(); fill(255); ellipse(-17.5, -65, 35, 35); // podr. levega očesa ellipse(17.5, -65, 35, 35); // podr. desnega očesa arc(0, -65, 70, 70, 0, PI); // brada fill(0); ellipse(-14, -65, 8, 8); // levo oko ellipse(14, -65, 8, 8); // desno oko quad(0, -58, 4, -51, 0, -44, -4, -51); // kljun }

Page 47: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

46

Zgornji izris lahko rešimo tudi tako, da vpeljemo funkcijo, ki bo izrisala objekt, pri tem pa je slednjo potrebno napisati le enkrat. Tako prikazuje nadaljnji primer (levo spodaj), kjer je vpeljala funkcija owl(), ki se jo s funkcijo draw() prikliče dvakrat za izris, poda pa se drugačno izhodišče izrisa. Če želimo izris objektov po celi širini lahko to naredimo tako da kodo za izris objekta zapišemo le enkrat pred tem pa dodamo funkcije, da naj se ta objekt izrisuje po celotni širini slikovne površine (spodaj desno).

void setup() { size(480, 120); smooth(); } void draw() { background(204); owl(110, 110); owl(180, 110); } void owl(int x, int y) { pushMatrix(); translate(x, y); stroke(0); strokeWeight(70); line(0, -35, 0, -65); // telo noStroke(); fill(255); ellipse(-17.5, -65, 35, 35); // podr. levega očesa ellipse(17.5, -65, 35, 35); // podr. desnega očesa arc(0, -65, 70, 70, 0, PI); // brada fill(0); ellipse(-14, -65, 8, 8); // levo oko ellipse(14, -65, 8, 8); // desno oko quad(0, -58, 4, -51, 0, -44, -4, -51); // kljun popMatrix(); }

void setup() { size(480, 120); smooth(); } void draw() { background(204); for (int x = 35; x < width + 70; x += 70) { owl(x, 110); } } void owl(int x, int y) { pushMatrix(); translate(x, y); stroke(0); strokeWeight(70); line(0, -35, 0, -65); // Body noStroke(); fill(255); ellipse(-17.5, -65, 35, 35); // podr. levega očesa ellipse(17.5, -65, 35, 35); // podr. desnega očesa arc(0, -65, 70, 70, 0, PI); // brada fill(0); ellipse(-14, -65, 8, 8); // levo oko ellipse(14, -65, 8, 8); // desno oko quad(0, -58, 4, -51, 0, -44, -4, -51); // kljun popMatrix(); }

V nadaljevanju lahko spreminjamo tudi sivine izrisanih površin objekta z dvema vpeljanima parametroma.

void setup() { size(480, 120); smooth(); }

Page 48: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

47

void draw() { background(204); randomSeed(0); for (int i = 35; i < width + 40; i += 40) { int gray = int(random(0, 102)); float scalar = random(0.25, 1.0); owl(i, 110, gray, scalar); } } void owl(int x, int y, int g, float s) { pushMatrix(); translate(x, y); scale(s); // Set the size stroke(g); // Set the gray value strokeWeight(70); line(0, -35, 0, -65); // Body noStroke(); fill(255-g); ellipse(-17.5, -65, 35, 35); // Left eye dome ellipse(17.5, -65, 35, 35); // Right eye dome arc(0, -65, 70, 70, 0, PI); // Chin fill(g); ellipse(-14, -65, 8, 8); // Left eye ellipse(14, -65, 8, 8); // Right eye quad(0, -58, 4, -51, 0, -44, -4, -51); // Beak popMatrix(); }

7.1 Vračanje vrednosti Funkcija lahko izračuna ter nazaj poda vrednost v osnovni program. Tak primer je napr. funkcija random() ali sin(). Ko se uporablja tovrstna funkcija, je običajno izračunana vrednost dodeljena spremenljivki, kot je spodaj prikazano, kjer random() vrne vrednost med 1 in 10, ki je nato dodeljena spremenljivki r. float r = random(1, 10); Funkcija, ki vrne vrednost je pogosto tudi uporabljena kot parameter druge funkcije, kot prikazuje spodnji primer: point(random(width), random(height));

Page 49: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

48

8 Objekti Objekti so kolekcije spremenljivk in funkcij, ki so v določeni odvisnosti. V kontekstu objektov je spremenljivka imenovana polje (ang. field) ali spremenljivka primera (ang. instance variable) medtem ko je funkcija imenovana metoda (ang. method). Spremenljivke in funkcije delujejo tako kot smo jih spoznali ptedhodno, le da v kontektu objektov dobijo nove dimenzije delovanja. Lahko tudi rečemo, da objekti kombinirajo sorodne podate (fields) in sorodne, povezane metode, torej akcije in obnašanja (ang. actions and behaviours). Ideja je, da se grupira povezane podatke s povezanimi metodami, ki delujejo na te podatke.

8.1 Objekti in razredi (ang. objects and classes) Razred je specifikacija objekta, torej kot nek načrt objekta. Tako kot objekti, razredi definirajo tipe podatkov in obnašanje, a vsak objet ki je iz določenega razreda ima spremenljivke, ki imajo lahko različne vrednosti. Vsak objekt je torej primerek (ang. instance) razreda ter vsak primerek ima nabor polij in metod. Postopek poteka v štirih korakih: 1. ustvarjanje bloka (ang. block) 2. dodajanje polij (ang. fields) 3. pisanje konstruktorja (ang. constructor), ki dodeli vrednost polju 4. dodajanje metode. Primer je prikazan na podlagi spodnjih primerov: 1.ustvarjanje bloka, pri čemer je priporočljivo prvo črko imena razreda pisati z velikimi tiskanimi črkami class JitterBug { } 2. dodajanje polij, ki bodo imela določene vrednosti preko konstruktorja class JitterBug { float x; float y; int diameter; float speed = 0.5; }

V tem primeru smo določili vrednosti za x, y in diameter. 3. pisanje konstruktorja; konstruktor ima vedno enako ime kot razred, Namen konstruktorja je da dodeli začetne vrednosti poljem, ko je objekt (primerek razreda) ustvarjen. Koda znotraj bloka konstruktorja je pognana enkrat, ko je objekt prvo ustvarjen. V našem primeru bomo definirali tri spremenljivke, katerim bomo dodali ime temp (kot temporary), a bi tu lahko bila uporabljena katerakoli beseda, saj so slednje uporabljene le za dodeljevanje vrednosti poljem, ki so deli razredov. Ker konstruktor nikoli ne vrne vrednosti, nima pred sabo zapisanih drugih tipov podatkov, kot recimo tudi ne void. Ko dodamo konstruktor izgleda razred tako, kot je prikazano spodaj.

Page 50: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

49

class JitterBug { float x; float y; int diameter; float speed = 0.5; JitterBug(float tempX, float tempY, int tempDiameter) { x = tempX; y = tempY; diameter = tempDiameter; } }

4. dodajanje metode je zadnji korak, ki podobno kot pisanje funkcije, le da so slednje tukaj vključene v razred. Pole tega se tu uporabljajo tudi drugačni razmiki med vrstricami, med vsako vrstico v razredu je nekaj vrstic praznih, da nakazuje vključenost v bloke. V konstruktorju in metodi vključuje koda ponovno več praznih vrstic, da kaže hierarhijo.

class JitterBug { float x; float y; int diameter; float speed = 2.5; JitterBug(float tempX, float tempY, int tempDiameter) { x = tempX; y = tempY; diameter = tempDiameter; } void move() { x += random(-speed, speed); y += random(-speed, speed); } void display() { ellipse(x, y, diameter, diameter); } }

8.2 Ustvarjanje objekta Potrebna sta dva koraka za ustvarjanje objekta:

1. deklaracija spremenljivke objekta 2. ustvarjanje, iniciacija objekta s ključno besedo new.

JitterBug bug; // deklaracija objekta void setup() {

Page 51: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

50

size(480, 120); smooth(); // ustvarjanje objekta ter določanje parametrov bug = new JitterBug(width/2, height/2, 20); } void draw() { bug.move(); bug.display(); } // JitterBug razred class JitterBug { float x; float y; int diameter; float speed = 2.5; JitterBug(float tempX, float tempY, int tempDiameter) { x = tempX; y = tempY; diameter = tempDiameter; } void move() { x += random(-speed, speed); y += random(-speed, speed); } void display() { ellipse(x, y, diameter, diameter); } }

Vsak razred je tip podatkov (ang. data type) ter vsak objekt je spremenljivka. Objekt je deklariran tako da se določi tip podatkov, kateremu sledi ime spremenljivke: JitterBug bug; Naslednji korak je iniciacija objekta s ključno besedo new, kar določi prostor za objekt v spominu ter ustvari polje. Ime konstruktorja je napisan desno od ključne besede new, kateri sledi parameter konstruktorja (če so slednji določeni) JitterBug bug = new JitterBug(200.0, 250.0, 30); Tri številke v oklepaju so parametri, ki so posredovani konstruktorju razreda JitterBug. Število

ter parametrov ter njihovi tipi podatkov se morajo ujemati s tistimi od konstruktorja.

Page 52: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

51

8.3 Določanje več objektov Uporaba pike v kodi bug.move(); omogoča dostopnost do metod objekta v funkciji draw(). Operator pike . je uporabljen za povezavo imena objekta z njegovim poljem in metodami. To postane bolj jasno v primerih, ko imamo dva objekta iz enega razreda, kot je predstavljeno v spodnji kodi. Tako se na primer ukaz jit.move() nanaša na metodo move(), ki pripada objekti jit, medtem ko bug.move() se nanaša na metodo move(), ki pripada objektu z imenom bug. JitterBug jit; JitterBug bug; void setup() { size(480, 120); smooth(); jit = new JitterBug(width * 0.33, height/2, 50); bug = new JitterBug(width * 0.66, height/2, 10); } void draw() { jit.move(); jit.display(); bug.move(); bug.display(); } // JitterBug razred class JitterBug { float x; float y; int diameter; float speed = 2.5; JitterBug(float tempX, float tempY, int tempDiameter) { x = tempX; y = tempY; diameter = tempDiameter; } void move() { x += random(-speed, speed); y += random(-speed, speed); } void display() { ellipse(x, y, diameter, diameter); } }

Page 53: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

52

9 Zbirke (ang. Arrays) Zbirke so seznami spremenljivk, ki delijo isto ime. Zbirke so uporabne, saj lahko ustvarjamo z več spremenljivkami brez da bi določevali nova imena za vsako od spremenljivk. To omogoča krajšo in optimalnejšo kodo. Lahko si pogledamo primer premikanja petih kvadrov po površini, pri čemer je koda še obvladljiva. Vendar če želimo vključiti več objektov je pisanje kode za vsak objekt zelo zamudno, koda pa postane dolga in neobvadljiva. Zato lahko vpeljemo zbirke. float x1 = -20; float x2 = 20; void setup() { size(250, 150); smooth(); noStroke(); } void draw() { background(0); x1 += 0.5; x2 += 0.5; rect(x1, 30, 40, 40); rect(x2, 90, 40, 40); }

float x1 = -10; float x2 = 10; float x3 = 35; float x4 = 18; float x5 = 30; void setup() { size(250, 150); smooth(); noStroke(); } void draw() { background(0); x1 += 0.5; x2 += 0.5; x3 += 0.5; x4 += 0.5; x5 += 0.5; rect(x1, 20, 15, 15); rect (x2, 40, 15, 15); rect (x3, 60, 15, 15); rect (x4, 80, 15, 15); rect (x5, 100, 15, 15); }

V primeru večjega števila objektov, za katere želimo da se premikajo lahko uporabimo, kot rečeno, zbirko, kot je prikazano spodaj.

float[] x = new float[3000]; void setup() { size(250, 150); smooth();

Page 54: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

53

noStroke(); fill(255, 200); for (int i = 0; i < x.length; i++) { x[i] = random(-1000, 200); } } void draw() { background(0); for (int i = 0; i < x.length; i++) { x[i] += 0.5; float y = i * 0.4; rect(x[i], y, 15, 15); } }

Vsak del v zbirki se imenuje element (ang. element) ter vsak od teh elementov ima indeks vrednost (ang. index value), ki omogoča določanje pozicije znotraj zbirke. Tako kot koordinata na ekranu se indeks vrednost za zbirko prične z vrednostjo 0, drugi element ima vrednost 1, tretji 2 itd. Če je v zbirki 30 vrednosti, je indeks vrednost zadnjega elementa 29. Konceptualno strukturo zbirke prikazuje spodnja slika, ki prikazuje da je zbirka seznam ene ali več spremenljivk, ki delijo isto ime. Delo z zbirko je enako delu z eno spremenljivko, saj sledi istemu vzorcu. Spremenljivko lahko ustvarimo z: int x; Zbirko pa le tako da dodamo oglate klepaje, kot je prikazano spodaj: int[] x; Če tako želimo narediti 5000 spremenljivk lahko to storimo z: int[] x = new int[5000];

Zbirko lahko ustvarimo z različnimi tipi podatkov, slikami (PImage), oblikami (PShape) funkcijami (boolean), nizi (Stings) itd. Spodnja koda tako ustvari zbirko 50 spremenljivkami tipa PImage.

Page 55: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

54

PImage[] images = new PImage[50]; Vsaka zbirka lahko deluje le z enim tipom podatkov, ki jih torej ne smemo mešati znotraj ene zbirke. Če potrebujemo delati z različnimi tipi podatkov, lahko to storimo z delom z objekti. Delo z zbirkami vključuje tri korake:

1. deklaracija zbirke ter definicija tipa podatkov; 2. ustvarjanje zbirke s ključno besedo new (ovo) ter definicija dolžine; 3. dodeljevanje vrednosti vsakemu elementu.

Spodaj so predstavljeni trije različni načini določevanja in dodeljevanja zbirke, ki pa imajo enak rezultat:

int[] x; // deklaracija zbirke void setup() { size(200, 200); x = new int[2]; // ustvarjanje zbirke x[0] = 12; // dodeljevanje prve vrednosti x[1] = 2; // dodeljevanje druge vrednosti }

int[] x = new int[2]; // deklaracija in ustvarjanje zbirke void setup() { size(200, 200); x[0] = 12; // dodeljevanje prve vrednosti x[1] = 2; // dodeljevanje druge vrednosti }

int[] x = { 12, 2 }; // deklaracija, kreiranje in dodeljevanje void setup() { size(200, 200); }

Primer, ki smo ga prej predstavili s potujočimi kvadrati, lahko sedaj predstavimo z zbirkami. Brez zbirke Z zbirko float x1 = -20; float x2 = 20; void setup() { size(250, 150); smooth(); noStroke(); } void draw() { background(0); x1 += 0.5; x2 += 0.5; rect(x1, 30, 40, 40); rect(x2, 90, 40, 40); }

float[] x = {-20, 20}; void setup() { size(250, 150); smooth(); noStroke(); } void draw() { background(0); x[0] += 0.5; // Increase the first element x[1] += 0.5; // Increase the second element rect(x[0], 30, 40, 40); rect(x[1], 90, 40, 40); }

Page 56: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

55

9.1 Ponavljanje in zbirke Spodnji primer prikazuje zanko, ki omogoči izris različno in naključno debelih črt. Zbirka je najprej zapolnjena z naključnim številom znotraj setup() ter nato so te vrednosti uporabljene za določanje debeline črt znotraj draw(). Vsakič ko se zažene program, je nova naključna številka uporabljena v zbirki.

float[] gray; void setup() { size(500, 250); gray = new float[width]; for (int i = 0; i < gray.length; i++) { gray[i] = random(0, 255); } } void draw() { for (int i = 0; i < gray.length; i++) { stroke(gray[i]); line(i, 0, i, height); } }

9.2 Zbirke objektov Spodnji primer ustvari 33 objektov JitterBug, ki so nato osveženi in prikazani posamezno znotraj funkcije draw(). Za to je potrebno dodajanje razreda JitterBug v kodo, kot je prikazano spodaj. JitterBug[] bugs = new JitterBug[33]; void setup() { size(500, 250); smooth(); for (int i = 0; i < bugs.length; i++) { float x = random(width);

Page 57: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

56

float y = random(height); int r = i + 2; bugs[i] = new JitterBug(x, y, r); } } void draw() { for (int i = 0; i < bugs.length; i++) { bugs[i].move(); bugs[i].display(); } } class JitterBug { float x; float y; int diameter; float speed = 2.5; JitterBug(float tempX, float tempY, int tempDiameter) { x = tempX; y = tempY; diameter = tempDiameter; } void move() { x += random(-speed, speed); y += random(-speed, speed); } void display() { ellipse(x, y, diameter, diameter); } }

Page 58: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

57

10 Napredne rešitve Interaktivna grafika je resda fokus platforme Processing, a vsekakor je njena uporaba bistveno širša. To si lahko pogledate tudi s primeri prosto dostopnih knjižnic na povezavi: http://processing.org/reference/libraries/, kjer si lahko ogledate področja uporabe na primerih videa, zvoka itd. Knjižnice se lahko uporabljajo tako, da jih snamete iz interneta ter nato naložite v mapo Libraries. Nato jih lahko odprete z ukazi Import Library v meniju skicirke programa Processing.

10.1 3D grafika Obstajata dva načina za 3D ustvarjanje v Processingu, oba pa zahtevata dodajanje tretjega parametra funkciji size(), ki omogoči spremembo v načinu risanja grafike. Privzeto je grafika 2D (oz. njeno upodabljanje), kar omogoča JAVA2D rendered (upodobljevalnik). Nekoliko hitrejši ter slabše kvalitete je P2D upodobljevalnika. Slednji pa je lahko spremenjen tudi v upodobljevalnik Processing 3D, t.i. P3D ali OpenGL, ki omogoča vašemu programu risanje v dodatni dimenziji, torej v smeri z-osi. Processing 3D (ki je vgrajen v platformo) : size(800, 600, P3D); ali OpenGL (ki ga je potrebno naložiti iz knjižnjice) : size(800, 600, OPENGL); Veliko funkcij (point(), line(), vertex()) ter transformacij (translate(), rotate(), scale()), ki smo jih spoznali predhodno v tej skripti ima možnost dela v 3D-ju. Tretjo dimenzijo omogoča dodajanje z-koordinate poleg x in y. Spodaj predstavljena koda omogoča risanje v OpenGL, ki ga na začetku tudi importiramo v kodo ter s izpiše v transformaciji size() kot size(440, 220, OPENGL); import processing.opengl.*; void setup() { size(440, 220, OPENGL); noStroke(); fill(255, 190); } void draw() { background(0); translate(width/2, height/2, 0); rotateX(mouseX / 200.0); rotateY(mouseY / 100.0); int dim = 18; for (int i = -height/2; i < height/2; i += dim*1.2) { for (int j = -height/2; j < height/2; j += dim*1.2) { beginShape(); vertex(i, j, 0); vertex(i+dim, j, 0); vertex(i+dim, j+dim, -dim);

Page 59: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

58

vertex(i, j+dim, -dim); endShape(); } } }

Delo v 3D-ju omogoča izris objektov s tretjo dimenzijo (kocke, kvadri, sfere) ter tudi uporabo novih funkcij, kot so kamera, vrsta materiala in osvetljevanje.

10.2 Luči Spodnji primeri prikazujejo kodo delovanja in spremembe parametrov luči.

Ambientalne luči

Usmerjene luči

void setup() { size(420, 220, OPENGL); noStroke(); fill(255); } void draw() { lights(); ambientLight(150, 102, 102); background(0); translate(width/2, height/2, -20); int dim = 18; for (int i = -height/2; i < height/2; i += dim*1.4) { for (int j = -height/2; j < height/2; j += dim*1.4) { pushMatrix(); translate(i, j, -j); box(dim, dim, dim); popMatrix(); } } }

void setup() { size(420, 220, OPENGL); noStroke(); fill(255); } void draw() { lights(); directionalLight(255, 255, 255, -1, 0, 0); rotateY(PI/24); background(0); background(0); translate(width/2, height/2, -20); int dim = 18; for (int i = -height/2; i < height/2; i += dim*1.4) { for (int j = -height/2; j < height/2; j += dim*1.4) { pushMatrix(); translate(i, j, -j); box(dim, dim, dim); popMatrix(); } } }

Page 60: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

59

ambientLight(102, 102, 102); //directionalLight(255, 255, 255, // Color // -1, 0, 0); // Direction XYZ

Točkovne luči (interakcija z miško) Reflektor (interakcija z miško) void setup() { size(420, 220, OPENGL); noStroke(); fill(255); } void draw() { lights(); pointLight(80, 0, 80,mouseX, 110, 50); rotateY(PI/24); background(0); background(0); translate(width/2, height/2, -20); int dim = 18; for (int i = -height/2; i < height/2; i += dim*1.4) { for (int j = -height/2; j < height/2; j += dim*1.4) { pushMatrix(); translate(i, j, -j); box(dim, dim, dim); popMatrix(); } } }

void setup() { size(420, 220, OPENGL); noStroke(); fill(255); } void draw() { lights(); spotLight(255, 0, 0, mouseX, 0, 200, 0, 0, -1, PI, 2); rotateY(PI/24); background(0); background(0); translate(width/2, height/2, -20); int dim = 18; for (int i = -height/2; i < height/2; i += dim*1.4) { for (int j = -height/2; j < height/2; j += dim*1.4) { pushMatrix(); translate(i, j, -j); box(dim, dim, dim); popMatrix(); } } }

//pointLight(80, 0, 80, // Color // mouseX, 110, 50); // Position

//spotLight(255, 0, 0, // Color // mouseX, 0, 200, // Position // 0, 0, -1, // Direction XYZ // PI, 2); // Concentration

Page 61: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

60

Kot smo spoznali poznamo v Processingu štiri tipe luči:

1. ambientalna: ustvarja enakomerno svetlobo po celotni sceni in se večinoma uporablja v kombinaciji z drugimi lučmi

2. usmerjena luč ustvarja zelo kontrastno osvetljevanje torej meče direktno osvetljevanje na objekt ter pri ter ustvarja močne sence

3. reflektor (ang. spot light) osvetljuje sceno v obliki stožca ter je definirana s smerjo, lokacijo ter barvo

4. točkovna luč seva iz ene točke (kot žarnica) ter je določena z barvo. Luči se vsakič lahko resetirajo z ukazom draw(), torej mora biti funkcija light() podana vedno pred ukazom draw() za doseganje konsistentnih rezultatov.

10.3 Kamera Privzeto Processing ustvari kamero s funkcijo camera(), ki je usmerjena v sredino scene ter tako deluje v perspektivi. Nastavitve, ki jih ima kamera so: postavitev kamere, lokacija, kamor je kamera usmerjena ter orientacija (gor, dol td.). V spodnjem primeru je uporabljena interakcija miške, za premik lokacije kamor je kamera usmerjena. import processing.opengl.*; void setup() { size(420, 220, OPENGL); noStroke(); } void draw() {

Page 62: Uvod v Processing - ntf.uni-lj.si · Skripta je delno povzeta po knjigi z naslovom Getting started with Processing avtorjev Casey Reas in Ben Fry ter je namenjena le internim študijskim

Uvod v Processing Interna študijska skripta za študente študijskih smeri Katedre za informacijsko in grafično tehnologijo

61

lights(); background(0); float camZ = (height/2.0) / tan(PI*60.0 / 360.0); camera(mouseX, mouseY, camZ, width/2.0, height/2.0, 0, 0, 1, 0); translate(width/2, height/2, -20); int dim = 18; for (int i = -height/2; i < height/2; i += dim*1.4) { for (int j = -height/2; j < height/2; j += dim*1.4) { pushMatrix(); translate(i, j, -j); box(dim, dim, dim); popMatrix(); } } } camera(mouseX, mouseY, camZ, // Camera location width/2.0, height/2.0, 0, // Camera target 0, 1, 0); // Camera orientation