You are on page 1of 69

processing

guida introduttiva alla programmazione visuale

processing
guida introduttiva alla programmazione visuale

alberto cecchi
1

valerio belloni ...

processing

guida introduttiva alla programmazione visuale

indice: prima parte: seconda parte: terza parte: quarta parte: quinta parte: p.3 p.34 p.48 p.54 p.60

This work is licensed under the Creative Commons AttributionNoncommercial-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-ncsa/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

processing

guida introduttiva alla programmazione visuale

Processing
Programmare per larte
Prima Parte
Possiamo dire che Processing un software grafico che si occupa di Immagini, Forme, Movimenti, Suoni e Interazioni. Processing allo stesso tempo un linguaggio di programmazione, un ambiente di sviluppo nonch un metodo di insegnamento della programmazione. Processing stato inventato da Casey Reas e Ben Fry al fine di insegnare agli studenti nel settore dellarte e della grafica la programmazione software. Oggi Processing utilizzato da studenti, artisti, designers e ricercatori per imparare, sperimentare e produrre. Processing rappresenta in pieno il proverbio di Confucio: se ascolto dimentico, se vedo ricordo, se faccio capisco Processing, in quanto linguaggio di programmazione, un linguaggio testuale (si scrivono le istruzioni) pensato per produrre e modificare immagini. Processing il giusto compromesso tra semplicit (nelluso) e complessita dei risultati che si possono raggiungere. Sono sufficienti pochi minuti di corso affinch uno studente possa scrivere le prime righe di codice ed osservare dei risultati. Utenti avanzati possono invece realizzare progetti anche molto complessi scrivendo direttamente delle librerie che possono anche migliorare ed aumentare le funzionalit del software stesso. I lavori fatti in Processing possono essere facilmente esportati nel web e questo aspetto ha facilitato la distribuzione del software e della sua conoscenza. Il sito ufficiale di Processing www.processing.org, allinterno del sito presente anche un forum con migliaia di iscritti che discutono assiduamente riguardo le problematiche tecniche e creative. Processing facilita linsegnamento della grafica digitale, delle tecniche di interazione come ad esempio disegno vettoriale e raster, image

processing

guida introduttiva alla programmazione visuale

processing, gestione degli eventi del mouse e della tastiera e comunicazione nelle reti di computer. Le librerie estendono le funzionalit di base anche alla generazione dei suoni, alla comunicazione dei dati (input/output) alle funzionalit tridimensionali ed esportazioni file in vari formati. Il linguaggio Processing non molto diverso da tanti altri linguaggi di programmazione. Processing stato progettato raffinando e rivedendo questi linguaggi che lo hanno preceduto. Questo aspetto molto importante, infatti possiamo vedere Processing come uno strumento per avvicinarsi alla programmazione. Chi impara a programmare in Processing avr il futuro molto facilitato qualora volesse imparare a programmare anche in altri linguaggi. Laspetto principale che differenzia Processing da altri linguaggi di programmazione riguarda la sua versatilit per tutto ci che legato alla grafica, al disegno, allanimazione e alle interazioni live. Installare e Aprire Processing Processing appunto Open Source e completamente gratuito. Per Scaricarlo sufficiente andare allindirizzo www.processing.org/ download dove si trovano le versioni per Linux, OSX e Windows. Lambiente di sviluppo di Processing (Processing Development Environment PDE) composto da un semplice editor testuale dove vengono scritte le istruzioni. PDE anche lestensione dei file di lavoro prodotti in Processing. Poi troviamo unarea messaggi, una console testuale e una toolbar dalla quale possono essere effettuate le operazioni pi comuni (nuovo, apri, salva, esporta). Sempre nella Toolbar in alto sono presenti i due tipici pulsanti degli ambienti di programmazione (Stop e Run). Ecco la lista completa dei pulsanti presenti nella Toolbar: RUN STOP NEW OPEN SAVE EXPORT

processing

guida introduttiva alla programmazione visuale

Quando si lancia un programma (Run) il risultato compare in una finestra che si apre automaticamente (display window). Ogni programma scritto con Processing (attraverso leditor testuale) si chiama Sketch. Allinterno delleditor testuale sono presenti le due tipiche funzionalit Taglia e Incolla (Cut and Paste) e Cerca e Sostituisci (Search and Replace). Larea messaggi, in basso ci dice ad esempio se una volta lanciato il programma ci sono errori. In pratica larea messaggi il mezzo che Processing usa per comunicare con noi, scrivendoci in quellarea qualunque tipo di messaggio riguardo il suo comportamento (ad esempio se si scrive uno Sketch errato sar larea messaggi ad avvertirci). Larea della conosole testuale (sotto larea messaggi) ci scrive dei messaggi in forma pi estesa e dettagliata della message window). Questa area ha anche la funzione di controllo durante le operazioni di programmazione. Ad esempio quando si vuole controllare una fare intermedia della programmazione, possiamo far comparire in questa finestra i dati desiderati (pi avanti sar tutto pi chiaro). I menu di Processing sono solo 6: Processing File Edit Sketch Tools Help Questa breve lista dei men allinterno dei quali troviamo pochi comandi, rende lidea della semplicit dellambiente di sviluppo Processing. Vedremo i comandi allinterno dei men pi avanti. Quando si crea un nuovo Sketch (programma) Processing crea automaticamente anche una specifica cartella che avr lo stesso nome dello sketch (come spiegato prima il file dove scritto il programma ha lestensione .pde). Processing un ambiente in grado di gestire file multimediali pertanto se allinterno del nostro progetto per esempio aggiungiamo un suono o unimmagine questi file andranno a collocarsi automaticamente dentro la cartella data, allinterno della cartella dello Sketch. Processing permette di lavorare secondo la logica drag and drop pertanto per aggiungere unimmagine al nostro programma sufficiente prendere il file e trascinarlo sopra leditor testuale dove stiamo scrivendo il nostro Sketch.

processing

guida introduttiva alla programmazione visuale

La cartella dello Sketch che a sua volta conterr anche la cartella data con tutti i file multimediali aggiunti si trover in una directory del computer che possiamo decidere dal men File/Preferences. Programmare in Processing Abbiamo detto che programmare in Processing molto semplice pertanto il modo migliore per capire questo concetto iniziare a scrivere qualche semplice programma cercando di comprenderne il senso. //Creiamo una finestra 320 x 240 pixel// size(320, 240); background(255); Abbiamo scritto tre righe nella finestra testuale dellambiente di sviluppo di Processing. La prima riga potrebbe sembrare semplice e tutti i programmatori giovani o inesperti o egoisti o masochisti tendono a trascurare questo tipo di istruzione che invece determinante. Ogni volta che scriviamo un programma dobbiamo aggiungere dei commenti che possano essere letti dai programmatori ma che non vengano interpretati come istruzioni dal programma stesso. I commenti sono importanti perch attraverso i commenti il programmatore dichiara le operazioni che compie in modo che potr rileggerli in futuro oppure in modo che altri programmatori che apriranno il programma leggendo i commenti possano capire come ha ragionato il programmatore precedente. Commentare un programma significa comunicare con se stessi (nel futuro) e con gli altri. Non commentare un programma significa non comunicare ne con se stessi (quando un anno dopo aprirete un programma fatto e non commentato non ricorderete quali ragionaventi avrete fatto e vi dispererete) ne con altre persone alle quali per lavoro o per divertimento volete lasciare in eredit il vostro lavoro. Un programma non commentato spazzatura. Questo aspetto cos centrale della programmazione risulta ancor pi centrale quando ci riferiamo ad un programma Open Source come Processing. Processing non costa nulla perch delle persone buone danimo hanno lavorato a lungo e hanno deciso di larsciarci in eredit gratuita il loro lavoro. Un programmatore che non scrive i commenti sui programmi realizzati in processing contravviene alla

processing

guida introduttiva alla programmazione visuale

filosofia Open Source perch i suoi programmi saranno difficilmente interpretabili da altri programmatori. La stesso giudizio per vale anche per i programmatori che lavorano in ambiti commerciali. Un programmatore che non commenta i propri software danneggia economicamente il suo datore di lavoro e tutto lambiente nel quale lavora. Torniamo quindi alla nostra prima riga di programma scritta in Processing //Creiamo una finestra 320 x 240 pixel// I due slash // indicano esattamente linizio e la fine di un commento del programmatore. Questo commento molto semplice agli occhi di un programmatore esperto potrebbe sempbrare inutile ma in realt quanto pi diffusamnte documentato un software tanto pi facile sar la sua lettura e correzione in futuro. Per scrivere dei commenti che siano pi lunghi di una riga Processing ci permette di utilizzare anche la seguente forma: /* I commenti sono molto importanti possiamo scriverli anche in pi righe il software non interpreta queste istruzioni */ Vediamo invece ora la prima istruzione (o funzione) vera e propria: size(320, 240); Possiamo notare in questa istruzione tre elementi importanti: - Il comando size - I parametri (320, 240) - Il simbolo che chiude listruzione ; Il comando size stabilisce che deve essere creata una finestra. Questa la tipica istruzione con cui si inizia a programmare in Processing. Con size si stabiliscono le dimensioni della finestra sulla quale poi compariranno i risultati del nostro programma. Le dimensioni che abbiamo stabilito in questo caso sono 320 pixel in larghezza (asse X) e 240 pixel in altezza (asse Y). Con ; invece diciamo a Processing terminata listruzione. Da notare la seguente istruzione:

processing

guida introduttiva alla programmazione visuale

//size(320, 240); Poich la riga inizia con // Processing interpreter tutto ci che segue come un commento e quindi quando si lancer il programma non verr effettuata nessuna azione. A volte i programmatori disordinati tendono a commentare molto le istruzioni durante il processo produttivo. Questa operazione se non documentata un operazione che genera solo confusione. Pertanto quando si commenta unistruzione bene spiegare, attraverso un ulteriore commento il motivo per il quale sono presenti delle istruzioni commentate. Rispetto ai paramentri importante notare che ad esempio nel caso di size debbono essere 2 e la loro posizione obbligatoria. Al primo posto si mette il valore delle X e al secondo posto (dopo la virgola) si mette il valore delle Y. Infine da notare un aspetto molto impor tante della programmazione, la convenzione di chiudere listruzione con ; potrebbe sembrare inutile e noiosa. Potrebbe anche essere cos, ma comunque dobbiamo capire che qualora non mettessimo quel dettaglio ; il nostro programma non funzioner. I linguaggi di programmazione usano una sintassi molto pi rigida della sintassi che si usa quando si parla o quando si scrive una mail. Quando scriviamo una mail ad un amico e ci dimentichiamo una virgola nel contenuto del nostro messaggio esso arriver a destinazione uguamente. Se invece facciamo un errore quando scriviamo lindirizzo mail il messaggio non arriver mai al destinatario. Scrivere unistruzione in Processing come scrivere un indirizzo mail, se non metti la chiocciola o sbagli anche solo un puntino non funzioner nulla. Gli aspetti formali della programmazione sono importanti e non possono essere tralasciati. Un altro aspetto formale che non possiamo tralasciare in Processing che i comandi sono case sensitive. Size e sizenon sono la stessa cosa, il comando size deve essere scritto con tutte le lettere minuscole, se non lo facciamo Processing non interpreta il comando. Size per Processing non significa nulla. Torniamo ora alla terza riga del nostro breve programma: background(255);
8

processing

guida introduttiva alla programmazione visuale

Possiamo facilmente distiguere il comando background il parametro tra parentesi e il termine della riga di istruzione ;. Il comando specifico background indica a Processing il colore che dovr avere lo sfondo della finestra che abbiamo appena creato. 255 indica il colore bianco. Una volta terminato di scrivere il nostro programma in tre righe lo potremo lanciare cliccando sul pulsante RUN. Potremo interrompere lesecuzione del nostro programma cliccando sul pulsante STOP. Numeri e Variabili Abbiamo creato il nostro primo breve programma in Processing. Abbiamo compreso alcuni principi base della programmazione. Questi principi sono pressoch universali nella programmazione e comprenderli in processing ci permetter poi di applicarli a praticamente qualunque altro linguaggio di programmazione. Nel nostro primo programma abbiamo visto che i comandi possono avere dei parametri e che questi parametri si esprimono in numeri. Nella programmazione normale per esprimere i numeri anche attraverso delle variabili. Queste due espressioni producono lo stesso risultato: //senza variabili background(0); //con variabili int X = 0; background (X); Nel secondo caso abbiamo fatto due operazioni. Con la prima operazione abbiamo detto al programma di attivare luso di una variabile che abbiamo chiamato X e abbiamo assegnato un valore a questa variabile 0. Il risultato che background avr un valore pari a zero, proprio come nel primo esempio. Le variabili sono molto utili nella programmazione proprio perch sono variabili e quindi il loro valore pu cambiare in base a degli

processing

guida introduttiva alla programmazione visuale

eventi , oppure possono cambiare in base a delle operazioni matematiche. Le variabili sono molto utili anche perch memorizzano dei valori e permettono di riutilizzarli quando serviranno in futuro. Esistono diversi tipi di variabili; nel nostro esempio int indica una variabile che pu assumere un valore numerico intero (senza valori dopo la virgola). float un altro tipo di variabile numerica che pu invece contenere anche valori dopo la virgola. Importante: come in quasi tutti i linguaggi legati allinformatica la virgola che noi utilizziamo nei numeri per indicare i valori decimali, deve essere sostituita dal punto .. Nei linguaggi di programmazione 10.5 equivale al 10,5 nella notazione che utilizziamo in Italia. Da notare che non possibile fare operazioni matematiche mescolando due variabili di tipo diverso (una int e laltra float). Nel linguaggio comune della programmazione listruzione: int X = 0; viene detta inizializzazione o dichiarazione di una variabile. Questo tipo di istruzioni generalmente vengono messe allinizio dei programmi e comunque debbono essere posizionate sempre prima che si utilizzi la variabile stessa. La seguente sequenza non funzionerebbe: background (X); int X = 10; Se vogliamo utilizzare la variabile X prima la dobbiamo inizializzare int X = 10;. Una volta che la variabile stata inizializzata possibile utilizzarla tutte le volte che si desidera. Inoltre dopo linizializzazione la variabile pu essere manipolata. Nellesempio seguente osserviamo che: int X = 10; X = 6; background (X); la variabile X stata prima inizializzata poi successivamente stato assegnato un nuovo valore alla variabile X = 6;.

10

processing

guida introduttiva alla programmazione visuale

Pertanto il valore finale di background (X); sar 6. Ovviamente per brevit sarebbe stato pi intelligente scrivere: int X = 6; background (X); il risultato sarebbe stato identico. Il nome delle variabili Abbiamo visto quindi che le variabili hanno un nome. Ho utilizzato x e come primo passagio potrebbe essere anche corretto ma quandi si scrive un programma pi complesso invece consigliabile dare un nome sensato alle variabili. Il lungo discorso che ho fatto nelle pagine precedenti riguardo i commenti vale anche per le variabili. Ipotizziamo ad esempio di voler disegnare un cerchio attraverso un programma e ipotizziamo che questo cerchio cambier di dimensione durante lesecuizone del programma stesso. Potremmo assegnare a questa variabile semplicemente una lettera X oppure C, ma se immaginiamo che il nostro programma sar abbastanza complesso allora sar sicuramente meglio utilizzare un nome della variabile pi esteso. Possiamo chiamare la variabile che gestir il nostro cerchio ad esempio cerchio. In questo modo quando riapriremo il programma in futuro oppure qualcunaltro aprir il nostro programma il nome della variabile permetter facilmente di comprendere di che variabile si tratta e per che cosa viene utilizzata. Pertanto quando dichiarer la mia variabile allinizio del programma scriver int cerchio = 10; anzich int X = 10; Il termine cerchio ci aiuter molto in futuro quando il nostro programma andr progressivamente coplicandosi. Ma in realt un buon programmatore dovrebbe precedere la dichiarazione della variabile con un commento che spiega a cosa serve quella variabile. Ad esempio:

11

processing

guida introduttiva alla programmazione visuale

// ecco la variabile che gestisce // il raggio del cerchio int cerchio = 10; Il nome delle variabili sempre meglio che sia parlante. Alcuni nomi per sono inibiti e non possono essere utilizzati per le variabili. Ad esempio non posso nominare una variabile int perch facendo questo complicherei molto la vita a Processing che potrebbe fare confusione. Infatti int anche un termine assegnato ad un comando. Di seguito una lista dei nomi di variabili che non possiamo usare in Processing:
abstract assert boolean break byte case catch char class const continue default do double else enum extends false final finally float for goto if implements import init instanceof int interface long native new null package private protected public return setup short start static

12

processing

guida introduttiva alla programmazione visuale

stop strictfp super switch synchronizedthis throw throws transient true try update void volatile while

Questo aspetto comune a praticamente tutti i linguaggi di programmazione. Un consiglio che posso dare ai programmatori italiani proprio quello di dare un nome in italiano alle variabili. Poich i comandi tipicamente sono in inglese si eviter facilmente di utilizzare un nome vietato. Esiste poi una lista di variabili che gestisce autonomamente Processing. Quando ad esempio abbiamo generato la finestra: size(320, 240); Processing ha automaticamente immagazzinato in un due variabili width e height questi valori. Se in futuro vorremo utilizzare questi valori potremo utilizzarli richiamando direttamente le variabili. Variabili e calcoli matematici Le variabili normalmente vengono utilizzate anche per effettuare calcoli matematici. Le operazioni di base che si effettuano sono pi +, meno -, per * e diviso /. Normalmente il risultato di unoperazione matematica viene memorizzato nelle variabili. Ad esempio: int x = 2 + 3; trasferisce il risultato della somma 2+3 nella variabile X al momento della sua inizializzazione int. Oppure: int x = 4;

13

processing

guida introduttiva alla programmazione visuale

int int int int

y s d m

= = = =

6; x + y; s / 2; (x * y)-2;

dichiara il valore delle variabili x e y, poi viene sommato e il risultato memorizzato nella varibile s (da cui avremo s = 10). In d invece memorizziamo il risultato di della somma precedente dividendola per 2 (da cui otterremo d = 5). Infine nella quinta riga abbiamo una vera e propria espressione. Trasferiamo nella variabile m il risultato della moltiplicazione di x per y e successivamente, fuori dalle parentesi, sottraiamo 2 (da cui otteniamo m = 22). Da notare che il risultato di un calcolo matematico deve sempre essere associato a una variabile. Infatti se nella terza riga scriviamo solo: x + y; otterremo un errore quando manderemo in RUN il nostro sketch. Luso delle parentesi cosi come nella matematica serve per dare la priorit ai calcoli. Inoltre moltiplicazione e sottrazione hanno la priorit su addizione e sottrazione. Le variabili posso essere utilizzate molte volte allinterno della stessa espressione. A volte siamo costretti a compiere diverse operazioni ma non ci interessato i risultati intermedi bens solo il risultato finale. Nel seguente programma: int int int s = x y s s = = = / 4; 6; x + y; 2;

dopo avere calcolato x+y e memorizzato il risultato in s utilizziamo nuovamente s nella riga successiva per memorizzare il valore s della riga precedente diviso per 2. Operando in questo modo abbiamo risparmiato una variabile per abbiamo perso il risultato temporaneo della somma x + y. Quando Processing

14

processing

guida introduttiva alla programmazione visuale

eseguir la quarta riga trasferir in s il risultato della nuova operazione (s/2) e il precedente valore di s sar perso. Iniziare a disegnare Le operazioni matematiche che si possono effettuare in Processing sono molte di pi delle quattro operazioni di base, ma stiamo procedendo secondo un livello di difficolt progressivo. Abbiamo capito come si scrive unistruzione in Processing e abbiamo capito limportanza della sintassi. Inoltre abbiamo introdotto il concetto di variabile nella programmazione. Questi primi elementi ci permettono di iniziare a scrivere un programma leggermente pi complesso. Per fare questo per ci avvarremo dellaspetto maggiormente potente in Processing, cio le funnzionalit grafiche. Credo che comprendere una formula matematica sia molto pi semplice se il risultato di questa formula viene tradotto in una dimensione grafica. Prima quindi di addentrarci nei meandri della programmazione e delluso intensivo della matematica iniziamo quindi ad osservare le funzionalit grafiche di Processing. La conoscenza delle funzionalit grafiche faciliter molto lo sviluppo di formule matematiche pi complesse. Abbiamo iniziato la nostra programmazione scrivendo tre righe: //Creiamo una finestra 320 x 240 pixel// size(320, 240); background(255); che, abbiamo visto cliccando su RUN, generano una finestra di sfondo bianco della dimensione di 320 pixel di larghezza e 240 pixel di altezza. Per disegnare qualche cosa dentro questa finestra necessario prima di tutto comprendere il concetto di coordinate. Lasse delle X scorre in orizzontale mentre lasse delle Y scorre in verticale. Langolo in alto a sinistra della nostra finestra ha le coordinate (0, 0). Langolo in basso a destra ha coordinate (320, 240). Langolo in alto a destra ha coordinate (320, 0) mentre langolo in basso a sinistra ha coordinate (0, 240). figura 2 disegno delle coordinate
15

processing

guida introduttiva alla programmazione visuale

Listruzione grafica pisemplice di Processing permette di generare un punto nello schermo. Questa la sua sintassi: point(X, Y); questo comando grafico ha due parametri, X ed Y che indicano le coordnate della finestra nella quale verr disegnato il punto. Se ad esempio decidessimo di disegnare il punto esattamente al centro della finestra che abbiamo appena creato sar sufficiente aggiungere una quarta riga: //Creiamo una finestra 320 x 240 pixel// size(320, 240); background(255); point(160, 120); Dividendo per due la larghezza e laltezza della finestra ottengo le coordinate X,Y del punto centrale della finestra. Per comprendere meglio il funzionamento del sistema delle coordinate sufficiente cambiare i valori X,Y del comando point. Da notare che questi valori debbono necessariamente rimanere allinterno dellintervallo della finestra stessa. Per generare pi punti nella finestra aggiungo pi volte la stessa istruzione cambiando le coordinate. Mantenendo fisso uno dei due valori delle coordinate si ottengono dei punti lungo lasse verticale o orizzontale a seconda del valore tenuto fisso. size(320, 240); background(255); //Creiamo tre punti sullasse verticale //tenendo il valore X stabile point(160, 60); point(160, 120); point(160, 180); Laspetto centrale di Processing in quanto strumento didattico proprio la facilit con la quale possiamo visualizzare dei principi matematici e statistici. Le coordinate X,Y le ritroviamo in infiniti sistemi e rappresentazioni. Manipolare in Processing i valori del

16

processing

guida introduttiva alla programmazione visuale

comando point permette di comprendere immediatamente in modo visivo il funzionamento delle coordinate. Questa guida pu essere letta anche come unintroduzione ai principi della matematica, della programmazione e degli algoritmi, possiamo vedere Processing come lo strumento pi veloce per comprendere questi principi. Una volta compreso il principio delle coordinate sar molto semplice con processing disegnare tutte le forme geometriche di base. Ad esempio questa la sintassi del comando per disegnare una linea: line(x1, y1, x2, y2); Con questo comando viene eseguita una linea che come estremi due punti individuati con X1,Y1 e X2,Y2. size(320, 240); background(255); //Creiamo una linea diagonale //che attraversa la finestra //dallangolo in alto a sinistra //allangolo in basso a destra line(0, 0, 320, 240); Per fare una linea in senso orizzontale il parametro Y dei due punti dovr rimanere costante. Il seguente comando genera una linea che attraversa la finestra orizzontalmente alla sua met. line(0, 120, 320, 120); Per disegnare diverse linee sufficiente mettere unistruzione dopo laltra nello stesso Sketch. Per disegnare diverse linee con dei punti in comune sufficiente scrivere pi istruzioni dove ogni linea ha due coordinate uguali alla linea successiva. //figura composta da due linee //che hanno un punto in comune //100,120 line(0, 120, 100, 120);

17

processing

guida introduttiva alla programmazione visuale

line(100, 120, 80, 220); Unendo delle linee possiamo disegnare triangoli, quadrilateri, rettangoli e linee spezzate. //triangolo prodotto //disegnando 3 linee line(0, 120, 100, 120); line(100, 120, 80, 220); line(80,220,0, 120); Ovviamente per Processing prevede le istruzioni per disegnare direttamente Triangoli, Quadrilateri, Rettangoli ed Ellissi. triangle quad rect ellipse Ecco spiegato di seguito il funzionamento di ogni istruzione: triangle (X1, Y1, X2, Y2, X3, Y3); Attraverso i tre punti vengono disegnati i tre lati del triangolo. quad (X1, Y1, X2, Y2, X3, Y3, X4, Y4); Attraverso i quattro punti vengono definiti i quattro lati del quadrilatero. Il quadrilatero che ne deriva pu avere anche tutti i lati diversi e non avere lati paralleli. Importante per quando si disegna un quadrilatero di seguire un ordine dei lati. Se ad esempio scrivete questa istruzione quad (1, 1, 50, 10, 100, 100, 130, 100); succede che anzich generare un quadrilatero genererete due trinagoli. Ci succede perch nel passaggio dal secondo punto al terzo e dal terzo al quarto Processing segue lordine dei punti e quindi i lati del quadrilatero si incrocieranno.

18

processing

guida introduttiva alla programmazione visuale

Scambiando il terzo punto con il quarto otterremo invece un quadrilatero: quad (1, 1, 50, 10, 130, 100, 100, 100); Per quanto riguarda il rettangolo Processing ragiona in modo leggermente diverso, ecco la sintassi: rect(x, y, width, height) si individua con i parametri X,Y langolo in alto a sinistra del rettangolo e successivamente si dichiara la larghezza e laltezza del rettangolo. Ovviamente se width e height hanno lo stesso valore succede che il rettangolo diventa un quadrato. Infine ecco listruzione per generare ellissi e cerchi: ellipse (X, Y, width, height); Con X, Y si stabilisce il centro dellellisse mentre con width, height si stabiliscono larghezza e altezza dellellisse. Se i due parametri width, heightsono uguali si ottiene un cerchio perfetto. Abbiamo quindi visto come si disegnano le figure geometriche di base con Processing. Gli esempi descritti sopra fanno sempre riferimento a delle forme stabili legate cio a dei numeri fissi. Volendo effettuare dei disegni pi complessi e dinamici potremmo associare le nostre forme a delle variabili. Inoltre le forme che abbiamo disegnato fanno sempre riferimento ad un contesto neutraledove il colore di sfondo sempre bianco e le figure sono bianche bordate di nero. Ad esempio il seguente Sketch size(320, 240); background(255); //Creiamo un quadrilatero quad (1, 1, 50, 10, 130, 100, 100, 100); //mettiamo sopra al quadrilatero un cerchio ellipse (20,20, 50, 50);

19

processing

guida introduttiva alla programmazione visuale

produrr graficamente il quadrilatero che conosciamo e successivamente sopra di esso un cerchio le cui coordinate del centro sono 20, 20 ed il cui raggio 50. Il cerchio come possiamo vedere ha uno sfondo bianco pertano si sovrappone, coprendolo in parte, al quadrilatero. Questo comportamento ci spiega due aspetti di Processing. Prima di tutto dobbiamo capire che Processing come tutti i linguaggi di programmazione esegue i comandi leggendoli in sequenza. La sequenza di esecuzione diventa sempre pi importante e strategica quando si complica lo Sketch. Inoltre le figure grafiche hanno un riempimento e non sono trasparenti. Per vedere meglio questo riempimento possiamo cambiare il colore della finestra. background(0); Canbiando il valore di background da 255 (bianco) a 0 (nero) vediamo ancora maglio che le forme geometriche create hanno un colore di riempimento. I numeri compresi tra 0 e 255 rappresentano tutte le gradazioni che vanno dal nero al bianco, cio sono dei grigi sempre meno intensi che alla fine 255 diventa un bianco. Questa modalit di classificazione dei colori vale anche per il colore di riempimento delle forme. Quando questo colore non viene dichiarato Processing stabilisce autonomamente un colore (questo in informatica viene definito valore di default). Per vedere ad esempio quale il colore di default delle finestre sufficiente cancellare listruzione background dal nostro sketch. Mandando in run Processing vediamo che la finestra assume un colore di sfondo grigio. I comandi hanno valori di default diversi infatti le forme geometriche che abbiamo creato hanno un valore di default per il riempimento che il bianco (255). Per cambiare il valore di default per il riempimento delle forme geometriche si utilizza listruzione: fill (); questa istruzione deve precedere il comando per la generazione della forma geometrica. Il seguente sketch

20

processing

guida introduttiva alla programmazione visuale

size(320, 240); fill (80); //Creiamo un quadrilatero quad (1, 1, 50, 10, 130, 100, 100, 100); //mettiamo sopra al quadrilatero un cerchio ellipse (20,20, 50, 50); genera quindi una finestra con un colore di sfondo di default (grigio) e delle forme geometriche con un colore di sfondo stabilito dal valore tra parentesi del comando fill. 80 indica un grigio scuro. Il valore fill funziona per tutte le forme geometriche che verranno generate dopo di esso. Possiamo infatti vedere che sia il quadrilatero che il cerchio hanno lo stesso riempimento. Qualora volessimo generare forme geometriche con valori di sfondo diversi dobbiamo semplicemente mettere dei nuovi comandi fill size(320, 240); //Creiamo un quadrilatero fill (80); quad (1, 1, 50, 10, 130, 100, 100, 100); //mettiamo sopra al quadrilatero un cerchio fill (250); ellipse (20,20, 50, 50); Il fill valido sempre lultimo e vale nello sketch finch non ne dichiariamo uno nuovo. Il cerchio dello sketch qui sopra pressoch bianco (250) il quadrilatero e grigio scuro (80) e se creassimo una nuoma forma geometrica dopo il cerchio senza specificare un nuovo fill esso sarebbe 250. Le forme grafiche hanno altri valori di default. Ad esempio disegnando le forme geometriche notiamo che il bordo della forma ha un colore e uno spessore. Il cerchio che abbiamo creato nel precedente Sketch ha il bordo nero, questo colore di default e pu essere cambiato mettendo, sempre prima dellistruzione che genera la forma geometrica , listruzione: stroke (255);

21

processing

guida introduttiva alla programmazione visuale

in questo caso il cerchio avr un bordo bianco (255) e qualora sia bianco anche il riempimento ovviamente non avremo percezione del bordo stesso. Un modo pi corretto per fare scomparire il bordo da una forma geometrica lapposito comando nostroke (0); cos come possiamo fare scomparire il riempimento con noFill (0); Inoltre possiamo anche decidere lo spessore del bordo delle forme geometriche (e delle linee) attraverso listruzione strokeWeight(4); dove il valore tra parentesi indica lo spessore del bordo espresso in pixel. Da notare un aspetto importante: la W di Weight maiuscola e come ho spiegato nelle prime pagine i comandi sono case sensitive pertanto dobbiamo scriverli tenendo presenti le maiuscole e le minuscole. In generale su questo aspetto per lambiente di sviluppo di Processing ci aiuta poich se per errore digitiamo un comando errato (es: strokeweight) vediamo che Processing non modifica il colore del comando stesso lasciandolo nero. Quando invece digitiamo un comando che per Processing significa qualche cosa (es: strokeWeight) succede che immediatamente il testo viene cambiato di colore e diventa marrone. Da notare infine che in molti linguaggi di programmazione si segue questa convenzione, la prima parola di un comando si scrive in minuscolo la seconda parola (attacata) inizia sempre con una maiuscola, lo stesso vale per leventuali terza o quarta parola. Diversi altri parametri permettono di intervenire sulle forme geometriche ma per ora abbiamo visto quelli essenziali e possiamo procedere oltre nel nostro percorso di addestramento alla programmazione. In seguito scopriremo come gestire i colori (per ora abbiamo visto solamente come gestire i grigi, e come gestire ad esempio le trasparenze nonch le curve e tante altre cose ...).

22

processing

guida introduttiva alla programmazione visuale

Ora per necessario un nuovo salto nella modalit di lavoro. Programmare veramente La programmazione che abbiamo visto fino ad ora composta da una serie di comandi messi in sequenza. Processing elabora le istruzioni una dopo laltra partendo dalla prima riga e terminando allultima. In pratica Processing legge i programmi che abbiamo fatto fino ad ora come noi leggiamo i contenuti di un libro. Abbiamo visto anche il concetto di variabile. Le variabili sono utili perch invece di utilizzare sempre i numeri possiamo sostituirli con delle entit il cui stato varia con lo scorrere del programma. I disegni che abbiamo fatto fino ad ora sono molto semplici e sopratutto sono statici. Infatti tutte le istruzioni che abbiamo scritto vengono elaborate sequenzialmente ma ad una velocit tale percui quando premiamo il tasto RUN davanti a noi compare una figura apparentemente statica. Processing unapplicazione che si presta bene per fare lavori di tipo statico (immagini fisse) ma si presta molto bene anche per fare animazioni. Inoltre anche nellelaborazione di immagini statiche potrebbe succedere che vogliamo produrre molte volte una figura ad intervalli regolari oppure di dimensioni progressivamene crescenti. Questa tipologia di problematiche: animazioni e ripetizioni (iterazioni) possono essere risolte in modo veloce attraverso delle apposite istruzioni. Partiamo da un caso molto semplice: allinterno della nostra finestra vogliamo disegnare dei punti ad intervalli regolari sullasse orizzontale, uno ogni 40 pixel. Disegniamo ora questi punti utilizzando il metodo pi semplice che abbiamo visto. size(320, 240); background(255); //Creiamo sette punti //sullasse orizzontale //tenendo il valore Y stabile point(40, 120); point(80, 120); point(120, 120); point(160, 120);

23

processing

guida introduttiva alla programmazione visuale

point(200, 120); point(240, 120); point(280, 120); Abbiamo visto gi nelle pagine precedenti tutte le istruzioni che permettono di generare questo nuovo Sketch. Premendo RUN vediamo sette punti a intervalli rogolari che attraversano lo schermo in senso orizzontale. Ora introduciamo luso delle variabili. Stabiliamo una variabile che chiamiamo intervallo e che ha il valore di 40, successivamente sostituiamo i valori delle coordinate X dei punti con le variabili. size(320, 240); background(255); // dichiaro la variabile int intervallo = 40; //Creiamo sette punti //sullasse orizzontale //tenendo il valore Y stabile point(intervallo, 120); point(intervallo*2, 120); point(intervallo*3, 120); point(intervallo*4, 120); point(intervallo*5, 120); point(intervallo*6, 120); point(intervallo*7, 120); Abbiamo moltiplicato lintervallo per dei valori progressivamente maggiori ottenendo esattamente lo stesso risultato del precedente Sketch. Il coefficiente di moltiplicazione che applichiamo allinvervallo stabilisce la distribuzione dei punti. Proviamo quindi a trasformare in variabile anche questo coefficiente, chiamandola coefficiente. size(320, 240); background(255); // dichiaro la variabile int intervallo = 40; // dichiaro la variabile // coefficiente int coefficiente = 1;

24

processing

guida introduttiva alla programmazione visuale

//Creiamo sette punti //sullasse orizzontale //tenendo il valore Y stabile point(intervallo*coefficiente, 120); coefficiente = coefficiente + 1; point(intervallo*coefficiente, 120); coefficiente = coefficiente + 1; point(intervallo*coefficiente, 120); coefficiente = coefficiente + 1; point(intervallo*coefficiente, 120); coefficiente = coefficiente + 1; point(intervallo*coefficiente, 120); coefficiente = coefficiente + 1; point(intervallo*coefficiente, 120); coefficiente = coefficiente + 1; point(intervallo*coefficiente, 120); coefficiente = coefficiente + 1; Leggendo con attenzione lo Sketch appena scritto vediamo che esso diventato molto pi lungo. Infatti per poter incrementare ogni volta il coefficiente stata aggiunta lapposita istruzione coefficiente = coefficiente + 1;. Comunque un primo vantaggio possiamo coglierlo dal fatto che osservando con attenzione lo sketch vediamo che le istruzioni sono sempre uguali. Infatti le due righe di istruzione: point(intervallo*coefficiente, 120); coefficiente = coefficiente + 1; si ripetono sette volte generando i sette punti. Per velocizzare loperazione di scrittura dello sketch potremmo scriverlo facendo copia e incolla delle due righe fino a ripeterle sette volte. La logica della programmazione informatica sta esattamente in questi passaggi: - concepire tutti i passaggi che portano al risultato (abbiamo scritto nel primo Sketch tutte le istruzioni che portavano al risultato desiderato) - concepire questi passaggi in modo che siano ripetitivi (abbiamo scritto nel terzo Sketch istruzioni ripetitive che portano al risultato desiderato)

25

processing

guida introduttiva alla programmazione visuale

- trasformare i passaggi da ripetitivi a ricorsivi (ora trasformeremo le operazioni ripetitive in ricorsive scrivendo un ciclo): size(320, 240); background(255); // dichiaro la variabile int intervallo = 40; // dichiaro la variabile // coefficiente int coefficiente = 1; //Creiamo sette punti //sullasse orizzontale //tenendo il valore Y stabile for (coefficiente = 1; coefficiente coefficiente = coefficiente+1) { point(intervallo*coefficiente, 120); }

<

8;

Lunico elemento nuovo nello Sketch precedente esattamente listruzione for che ha la seguente sintassi: for (coefficiente = 1; coefficiente coefficiente = coefficiente+1) { point(intervallo*coefficiente, 120); } < 8;

I principi di ricorsivit vengono stabiliti tra parentesi dopo avere scritto listruzione for. Tra parentesi troviamo tre elementi separati da ;. Il primo elemento coefficiente = 1 stabilisce il valore di partenza del ciclo. Il secondo elemento coefficiente < 8 stabilisce il valore di interruzione del ciclo. Il terzo elemento stabilisce laggiornamento del valore che avverr ricorsivamente (lincremento della variabile) che nel nostro caso coefficiente = coefficiente+1. In seguito allistruzione for tra le parentesi graffe vengono messe le operazioni da compiere durante tutta la durata del ciclo point (intervallo*coefficiente, 120).

26

processing

guida introduttiva alla programmazione visuale

Leggiamo come se fosse scritta in lingua italiana listruzione fordel nostro ciclo: Incrementa il coefficiente di una unit e finch il suo valore minore di 7 disegna un punto. Attraverso le istruzioni di tipo for possiamo quindi ripetere unoperazione finch non si verifichi una condizione di interruzione. Abbiamo quindi sintetizzato il nostro sketch, da notare che ora, qualora volessimo disegnare 100 punti invece di 7 la lunghezza dello sketch sarebbe sempre la stessa mentre invece nella modalit precendente avremmo dovuto scrivere 100 righe di codice, una per punto. Il seguente Sketch disegna 100 punti, con un intervallo tra un punto e laltro di 3 pixel: size(320, 240); background(255); // dichiaro la variabile int intervallo = 3; // dichiaro la variabile // coefficiente int coefficiente = 1; //Creiamo sette punti //sullasse orizzontale //tenendo il valore Y stabile for (coefficiente = 1; coefficiente < 101; coefficiente = coefficiente+1) { point(intervallo*coefficiente, 120); } Per fare questa semplice modifica abbiamo solamente modificato la variabile int intervallo = 3; ed abbiamo cambiato il valore di interruzione del ciclo for con coefficiente < 100. La verifica di interruzione del ciclo for avviene attraverso un simbolo comunemente conosciuto: <. In processing possibile anche controllare se un valore maggiore > oppure se un valore uguale ==. Nel caso di uguale (come in molti linguaggi di programmazione) si utilizza due volte il simbolo = per evitare che il programma compia unoperazione sulla variabile. Pertanto quando scriviamo:

27

processing

guida introduttiva alla programmazione visuale

X = 5 trasferiamo il valore 5 nella variabile X Mentre se scriviamo X == 5 controlliamo se il valore di X uguale (==) a 5. La programmazione in Processing ci permette quindi di evitare di scrivere infinite operazioni descrivendole una ad una. Attraverso i cicli for possiamo ripetere delle operazioni infinite volte cambiando ogni volta loperazione grazie alluso delle variabili. Le condizioni Unaltra istruzione (oltre al ciclo for) determinante nel processo di apprendimento della programmazione. Questa istruzione if . Continuiamo a lavorare nel nostro precedente Sketch e modifichiamolo decidendo che i nostri punti devono diventare delle linee quando il valore del coefficiente supera la soglia di 90 (elimino i commenti per risparmiare carta visto che sono presenti nello Sketch precedenti). size(320, 240); background(255); int intervallo = 3; int coefficiente = 1; for (coefficiente = 1; coefficiente < 101; coefficiente = coefficiente+1) { if (coefficiente > 90) { line (intervallo*coefficiente, 120, intervallo*coefficiente, 130); } point(intervallo*coefficiente, 120); } Abbiamo aggiunto listruzione if : if (coefficiente > 90) { line (intervallo*coefficiente, 120, intervallo*coefficiente, 130); }

28

processing

guida introduttiva alla programmazione visuale

che controlla se il coefficiente maggiore di 90 e qualora lo sia disegna una linea verticale lunga 10 pixel (notare il valore della coordinata Y che prima 120 poi 130). Mandando in RUN lo sketch completo vediamo che Processing disegna 90 punti e poi inizia a disegnare delle linee. La gestione delle condizioni nella programmazione determinante, infatti ogni volta che verifichiamo se una condizione si verifica automaticamente creiamo un bivio nel percorso possibile che pu compiere il programma. Quando al mattino usciamo di casa controlliamo se piove e qualora stia piovendo prendiamo lombrello. In quel momento compiamo unoperazione di tipo if . Quando allinterno di un programma ad esempio vogliamo gestire le possibili interazioni con lutente che lo user dobbiamo farlo attraverso delle operazioni if . Tutti i software che producono delle interazioni con lutente lo fanno ragiornando attraverso dei comandi di tipo if . I cicli for insieme ai controlli if sono due elementi centrali della logica di programmazione (in processing e praticamente in qualunque altro linguaggio di programmazione). Il controllo if permette anche di gestire la condizione negativa (detta else ossia altrimenti). Pertanto possiamo decidere anche di cambiare il nosro sketch cos come segue: size(320, 240); background(255); int intervallo = 3; int coefficiente = 1; for (coefficiente = 1; coefficiente < 101; coefficiente = coefficiente+1) { if (coefficiente > 90) { line (intervallo*coefficiente, 120, intervallo*coefficiente, 130); } else { point(intervallo*coefficiente, 120); } } Oltre al controllo precedente (if coefficiente > 90) abbiamo aggiunto la verifica della condizione negativa else. In questi passaggi importante seguire anche luso delle parentesi poich se
29

processing

guida introduttiva alla programmazione visuale

utilizzate in modo errato producono degli errori in fase di esecuzione. Rispetto alluso delle parentesi vale sempre una regola semplice: le parentesi aperte debbono essere tante quante le parentesi chiuse. Inoltre le parentesi sono sempre legate, quindi se si apre una parentesi tonda si deve chiudere la parentesi tonda. Quando si apre una graffa si deve chiudere la graffa. Inoltre le parentesi possono essere nidificate, messe cio una dentro laltra. Nello Sketch sopra ad esempio abbiamo messo dentro alle parentesi del ciclo for (che quindi inglobano il resto delle istruzioni) le parentesi relative ad if e ad else. Possiamo dire che abbiamo messo due piccole scatole (if e else) dentro una scatola pi grande (for). Programmare le animazioni Le istruzioni che abbiamo visto fino ad ora ci hanno permesso di capire i principi base della programmazione. Per generare delle forme grafiche sufficiente scrivere le specifiche istruzioni. Le forme grafiche hanno sempre delle coordinate e dei valori (colore, spessore...) che possono essere espressi in numeri o attraverso delle variabili. Lesecuzione delle istruzioni da parte di Processing procede linearmente a meno che, attraverso le istruzioni for non realizziamo dei cicli. Nel caso in cui volessimo per realizzare delle animazioni dobbiamo ragionare in modo diverso. Unanimazione composta da fotogrammi (immagini fisse) successivi. Lesecuzione dei fotogrammi ad una velocit sufficiente genera un effetto di animazione nel nostro cervello. Processing un software che ci permette di disegnare attrvaerso le istruzioni grafiche e ci permette anche di disegnare in movimento. Riconfiguriamo ora lo Sketch realizzato precedentemente dandoci un nuovo obiettivo. Produrre attraverso unanimazione dei punti successivi che compaiono progressivamente. Per ottenere questo nuovo effetto dobbiamo utilizzare le istruzioni che permettono di gestire le funzioni: // configuro i parametri // di esecuzione void setup () {
30

processing

guida introduttiva alla programmazione visuale

size (320,240); background (255); } int intervallo = 0; // definisco la funzione // dentro la funzione // metto le istruzioni ricorsive void draw (){ frameRate (1); point(intervallo, 120); intervallo = intervallo + 10; } Le funzioni utilizzate in questo nuovo Sketch sono due: void setup () {} void draw () {} Con void setup vengono definite tutte quelle parti del programma che rimarranno effettive durante la sua esecuzione. Le istruzioni interne alla funzione void setup vengono eseguite una sola volta. Infatti dentro le parentesi {} sono state messe le due istruzioni tipiche di ogni Sketch per la definizione della finestra e del suo colore di sfondo. Inoltre stata anche messa linizializzazione della variabile intervallo che necessaria ununica volta. Con void drawviene invece definita la funzione ricorsiva che verr eseguita ricorsivamente senza sosta. frameRate (1); stabilisce la velocit dellanimazione che ho impostato ad 1 fotogramma al secondo in modo al fine di cogliere bene gli effetti dello Sketch. Poi metto listruzione per disegnare il punto e listruzione per spostare di intervalli regolari il punto stesso (intervallo = intervallo + 10). Quando verr mandato in RUN lo Sketch si otterr unanimazione alla velocit di un frame al secondo dove compare un nuovo punto ogni frame. Questo punto (grazie al contatore) avr ad ogni frame una coordinata Y incrementata di 10. Mandando in RUN lo Sketch cos come stato configurato succede che i punti creati nel fotogramma precedente rimangono persistenti nel video pertanto ad ogni fotogramma avremo un punto in pi. Qualora invece volessimo avere un effetto di spostamento del punto dovremmo ad ogni nuovo frame cancellare il punto creato nel fotogramma precedente. Per fare questo sufficiente spostare

31

processing

guida introduttiva alla programmazione visuale

listruzione background (255);dalla funzione setup alla funzione draw. Mandando nuovamente in RUN lo Sketch modificato notiamo che il punto del frame precedente scompare ed abbiamo un effetto di movimento (anche se molto a scatti e lento). Per velocizzare il movimento sufficiente modificare i parametri frameRate (lo impostiamo a 5 poi a 15). Per dare maggiore fluidit sufficiente abbassare lincremento costante della variabile intervallo; anzich 10 mettiamo 3 poi 1. Continuando a modificare questi due parametri possiamo capire sempre meglio il loro uso. Da ricordare che nel cinema e nella televisione si lavora allincirca ad una frequenza di 25 fotogrammi al secondo. Processing ha un valore di default del frameRate di 60. Pertanto se allinterno della funzione draw non dichiariamo una velocit questo valore sar automaticamente impostato a 60 (molto veloce). Da notare infine che, mandando in esecuzione lo Sketch, il punto si sposta progressivamente da sinistra a destra finch non scompare. In realt, pur scomparendo il punto Processing continua ad elaborare lo Sketch incrementando il valore intervallo anche oltre la dimensione della finestra dichiarata in size. Questo aspetto dovr essere tenuto presente quando verranno programmati degli Sketch sempre pi complessi poich in termini di elaborazione essi impegnano il computer pur non generando alcun effetto visibile. Farsi in casa una funzione I processi base della programmazione sono stati introdotti. Le funzioni sono molto importanti poich permettono di eseguire in modo ricorsivo delle operazioni. La programmazione in Processing permette anche di definire delle funzioni da richiamare quando se ne ha bisogno. Ad esempio possiamo definire una funzione che disegna due punti che si muovono da sinistra a destra. Costruisco una funzione come segue: void punti () { // con il controllo if // faccio in modo di ripartire // ogni volta che esco dallo schermo if (intervallo > 320) { intervallo = 10;

32

processing

guida introduttiva alla programmazione visuale

} intervallo = intervallo + 10; point (intervallo, 120); point (intervallo +1, 118); } dopo listruzione che introduce le funzioni (void) viede dato un nome alla funzione stessa. In questo caso punti. Poi per vedere leffetto in modo continuativo utilizzo anche una istruzione if che praticamente controlla se i punti hanno superato la dimensione dello schermo if (intervallo > 320). In caso affermativo riporto la variabile intervallo al suo valore di partenza (intervallo = 10;) e quindi i punti riappariranno nello schemo a sinistra in modo infinito. Le due istruzioni point definiscono la posizione dei due punti che scorreranno in senso orizzontale (infatti come coordinata X hanno una variabile mentre come coordinata Y hanno un numero fisso). Lutilit delle funzioni definite sta nel fatto che possono essere richiamate quando sono necessarie. Pertanto una volta definite potranno essere utilizzate molte volte. Di seguito uno sketch che richiama la funzione punti (tolgo i commenti ricorsivi dallo Sketch per brevit). int intervallo = 10; void setup () { size (320,240); } void draw (){ frameRate (15); background (255); punti (); } void punti () { if (intervallo > 320) { intervallo = 10; } intervallo = intervallo + 10; point (intervallo, 120); point (intervallo +1, 118);

33

processing

guida introduttiva alla programmazione visuale

} Leggendo il contenuto della funzione void draw () vediamo il richiamo alla funzione creata punti ();. Per richiamare una funzione creata sufficiente quindi scrivere il nome della funzione e mettere le due parentesi tonde e la virgola. Il flusso di esecuzione dello Sketch salter quindi alla funzione punti e la scorrer come se fosse un sottoprogramma. Terminata la funzione Processing torner a leggere listruzione subito dopo il richiamo. Da ricordare che tutte le istruzioni della funzione void draw () sono eseguite da processing in modo infinito. E comunque possibile interrompere questo ciclo infinito attraverso listruzione noLoop (); sia in un punto specifico durante lesecuzione della funzione draw sia come caratteristica generale dello sketch mettendo listruzione nellarea setup. Volendo far ripartire il loop infinito di draw invece sufficiente mettere listruzione loop (); nel punto desiderato. Variabili, funzioni, interazioni (if) e cicli rapresentano la base della programmazione. Chi ha letto e compreso tutto ci che scritto nelle pagine precedenti pu tranquillamente dire in giro che conosce i rudimenti della programmazione.

34

processing

guida introduttiva alla programmazione visuale

Seconda Parte
I colori Molte istruzioni sono state volontariamente tralasciate nella prima parte del testo perch lintento era far comprendere i principi base e successivamente incrementare la conoscenza intorno ad essi. Ad esempio nella Prima parte ho descritto il metodo utilizzato in Processing per definire il bianco, il nero e tutte le tonalit di grigio che stanno in mezzo. Traducendo in termini informatici e matematici la modalit di classificazione utilizzata da Processing per le scale di grigio possiamo dire che vengono utilizzati 8 bit. Infatti 8 bit permettono di ottenere 28 (256) combinazioni diverse (da 0 a 255). Il criterio che processing utilizza per i colori praticamente lo stesso solamente che applica la scala ai tre colori primari utilizzati per classificare i colori negli schermi (anche quelli televisivi). Questi colori sono Il Rosso il Verde (Green) e il Blu, il metodo viene infatti chiamato RGB. Processing utilizza 8 bit per classificare ognuno dei tre colori primari del metodo RGB. Vediamo prima di tutto un semplice Sketch per capire meglio il metodo: size (320, 240); fill(255, 255, 255); ellipse (50, 50, 20, 20); Lo Sketch produce un cerchio (ellipse) di colore bianco poich nella istruzione fill sono stati impostati i parametri RGB al massimo valore (255, 255, 255). Ne consegue che se impostiamo tutti e tre i parametri al mimimo otteniamo il nero (0, 0, 0). Questo metodo anche detto additivo. I tre numeri hanno una posizione fissa, il primo indica il Rosso, il secondo il Verde e il tezo il Blu. Di seguito una breve tabella con alcuni esempi di colore ottenuti attraverso il metodo RGB: (255, 0, 0) = Rosso (0, 255, 0) = Verde (0, 0, 255) = Blu

35

processing

guida introduttiva alla programmazione visuale

(255, 255, 0) = Giallo (150, 150, 150) = Grigio (250, 200, 200) = Rosa Le combinazioni possibili prodotte da 24 bit sono circa 16 milioni di colori. Il metodo RGB pu essere applicato in sostituzione del metodo a 8 bit. Ad esempio per tornare allo Sketch precedente potremmo stabilire di voler disegnare un cerchio bianco con bordo rosso. Per fare questo utilizziamo unistruzione che abbiamo gi visto stroke per in questo caso dichiariamo i 3 colori primari. size (320, 240); fill(255, 255, 255); stroke (255, 0, 0); ellipse (50, 50, 20, 20); Inoltre aggiungendo listruzione background possiamo anche stabilire il colore di sfondo della finestra. Ad esempio se allo sketch precedente aggiungiamo listruzione background (0, 0, 0) dopo listruzione size, otteniamo uno sfondo verde. Trasparenza Processing permette anche di gestire un quarto parametro per gestire i colori. Anche questo quarto parametro viene gestito con uno spettro di 8 bit, esso la trasparenza (anche detto canale alpha). Vediamo uno Sketch: size (320, 240); fill(0, 0, 255, 200); ellipse (50, 50, 20, 20); fill(255, 0, 0, 100); ellipse (40, 40, 20, 20); fill(255, 0, 255, 50); ellipse (20, 20, 50, 50); Il precedente Sketch produce tre cerchi con colori diversi e gradi di riempimento diversi (il quarto parametro dellistruzione fill).

36

processing

guida introduttiva alla programmazione visuale

Quando il canale Apha impostato a 0 la figura risulta completamente trasparente mentre quando il canale impostato a 255 la figura risulta essere piena. Il grado di trasparenza particolarmente utile quando si hanno delle figure sovrapposte e si vuole lasciare trasparire le figure sottostanti. Eseguendo il precedente Sketch possiamo notare che i tre cerchi sono sovrapposti secondo lordine definito nella scrittura dello Sketch: il primo cerchio risulta essere pi in fondo e vicino allo sfondo, mentre lultimo cerchio risulta essere pi in superficie e quindi sopra i due cerchi scritti precedentemente. Il grado di trasparenza applicabile anche ai grigi. Ecco una tabella esplicativa delle possibili situazioni, riportata allistruzione fill ma estensibile a background: fill (100); = riempimento grigio fill (100, 50); = riempimento grigio con un alto livello di trasparenza fill (255, 0, 0); = riempimento con metodo RGB fill (255, 0, 0, 120); = riempimento con metodo RGB e un medio livello di trasparenza Unultima cosa interessante sui colori riguarda le variabili. E possibile definire delle variabili di tipo colore e successivamente richiamare il colore direttamente scrivendo il nome della variabile. color rosso = color(255, 0, 0); fill(rosso); Ad esempio nelle due righe sopra ho definito il colore rosso e successivamente lo richiamo allinterno di un parametro fill. Quest opportunit permette di gestire colori particolari dei quali magari si gi provata in passato la combinazione. In questo modo mettendo allinizio dello Sketch il codice del colore sar pi facile in seguito nello Sketch richiamarlo. Nei semplici Sketch questo tipo di funzionalit potrebbero sembrare inutili, ma quando si inizia a scrivere degli Sketch lunghi centinaia di righe ci si accorge dellutilit di queste funzioni (nonch dei commenti //). Il caso Quando si realizza arte con il computer i colori sono ovviamente determinanti. Designare senza colori molto pi difficile e limitativo. Mentre alcuni tipi di disegni possono essere facilmente

37

processing

guida introduttiva alla programmazione visuale

riprodotti anche in scale di grigio, altri tipi di rappresentazione necessitano dei colori. Se ben usata, lopzione dei colori permette di ottenere dei risultati e delle rappresentazioni visive molto pi efficaci. C un altro aspetto concettuale che riguarda la programmazione che altrettanto determinante: la casualit (random). Generare dei numeri a caso attraverso il computer permette di ottenere delle forme visuali molto pi credibili che non utilizzando delle rigide formule trigonometriche. Le numerazioni casuali sono molto utili ad esempio quando si vuole simulare un movimento di un soggetto organico oppure quando si vuole disporre in modo naturale degli oggetti. Ad esempio vuolendo simulare una distesa derba potremmo in teoria decidere di mettere un filo ogni 4 pixel ma questa disposizione cos rigida e costante darebbe immediatamente un effetto estetico di artificialit allimmagine risultante. Se invece disponiamo i fili derba in modo casuale entro un certo intervallo (tra 1 e 6 pixel) otteniamo un effetto naturale nella distribuzione dellerba stessa. Inoltre la casualit molto importante anche quando si vogliono gestire dei giochi. Tutti gli eventi a partire da un lancio di moneta o di dado possono essere gestiti attraverso la generazione di un evento casuale nel computer. La casualit ha quindi uno spazio importante nella generazione di immagini e nella gestione delle animazioni fatte con Processing e con qualunque altro software. Da notare inoltre che la casualit in quanto tale non gestibile dai computer. Infatti i computer ragionano in base a regole molto rigide e cicliche e quando gli si chiede di generare un numero casuale essi hanno difficolt e quindi vanno alla ricerca di eventi da misurare. Il movimento del mouse un tipico evento misurato dal computer che poi rielaborato pi volte produce un numero casuale. Questo aspetto cos complesso per il computer completamente invisibile agli utenti ma emblematico di quanto sia ritenuto importante il fattore casuale nella programmazione. Nonostante il computer non sia geneticamente in grado di produrre eventi casuali, gli si chiede di gestirli perch attraverso questa casualit si possono simulare infiniti eventi. Modifichiamo quindi lultimo Sketch della prima parte utilizzando un fattore casuale: int intervallo = 10; void setup () {

38

processing

guida introduttiva alla programmazione visuale

size (320,240); } void draw (){ frameRate (5); background (255); punti (); } void punti () { if (intervallo > 320) { intervallo = 10; } intervallo = intervallo + int (random (20)); point (intervallo, 120); point (intervallo +1, 118); } Nella funzione void punti ho corretto la linea che calcola il salto che i punti devono compiere ad ogni nuovo frame: intervallo = intervallo + int (random (20)); Precedentemente il valore di incremento era 10 mentre ora il valore di incremento (che definisce lo spostamento dei punti) sar un valore casuale compreso tra zero e 20 (int (random (20)); ). random (20); genera un numero casuale con virgola (di tipo float) compreso tra 0 e 20. Listruzione int () serve ad arrotondare i numeri con decimali in numeri interi. Questa istruzione int necessaria in quanto Processing non permette di mescolare numeri con virgola (di tipo float) con numeri interi (di tipo int). Mandando in RUN lo Sketch vediamo che ora i punti si spostano sempre da sinistra a destra ma procedendo in modo irregolare a volte hanno delle accelerazioni mentre altre volte procedono lentamente. Questo andamento casuale e lanciando pi volte lo Sketch si otterranno sempre risultati diversi. Osservando i punti compiere questo tipo di movimenti abbiamo un effetto di movimento che suscita molta pi curiosit, la sensazione che dona questo tipo di movimento pi organica e viva che non il movimento rettilineo uniforme del precedente Sketch. Per modificare leffetto degli scatti possiamo agire su diversi parametri. Aumentando il valore di random (20) otteniamo scatti sempre pi

39

processing

guida introduttiva alla programmazione visuale

variegati, mentre otteniamo scatti meno evidenti mettendo dei valori pi bassi. Inoltre, aumentando il framerate otteniamo maggiore velocit dellanimazione con pi fluidit nel movimento dei punti. Interveniamo nuovamente sullo Sketch al fine di aumentare leffetto organico del movimento: int intervallo = 10; void setup () { size (320,240); } void draw (){ frameRate (10); background (255); punti (); } void punti () { if (intervallo > 320) { intervallo = 10; } intervallo = intervallo + int (random (5)); point (intervallo, int (random (118, 121))); point (intervallo +1, int (random (116, 119))); } Ora, analizzando la funzione void punti vediamo che ho inserito un fattore di casualit anche nello spostamento sulla coordinata Y. Pertanto i punti si sposteranno anche leggermente in alto o in basso durante il loro consueto movimento verso destra. Analizzando listruzione vediamo che tra parentesi questa volta ci sono due parametri int (random (116, 119)). Quando listruzione random contiene due parametri significa che stato definito un parametro inferiore e un parametro superiore dellintervallo casuale. Nello Sketch precedente, il valore di Y 120 per il primo punto, ora invece sar un valore casuale compreso tra 118 e 121.

40

processing

guida introduttiva alla programmazione visuale

Mandando in RUN questo ultimo Sketch vediamo che i due punti spostandosi leggermente anche in alto e in basso avranno un effetto ancor pi organico. Sembreranno volare come due mosche. Pi avanti affronteremo ancor pi approfonditamente questo concetto. Per il momento lutilizzo della funzione random sar molto utile perch ci permetter di osservare degli esempi pi complessi e variegati, a volte dai comportamenti inattesi (perch casuali). Curve Abbiamo gi esplorato le forme grafiche di base di Processing (point, line, rect, triangle, quad, ellipse). Osservando i cicli e le funzioni abbiamo capito che possiamo assegnare le coordinate di queste forme geometriche a delle variabili anche casuali. Processing permette anche di generare delle curve secondo un metodo detto di Bezier. In pratica possono essere dichiarate, oltre ai due punti di inizio e fine della curva, anche le tangenti ai due punti. Vediamo un esempio scrivendo il seguente Sketch e mandandolo in RUN: size (320, 240); noFill (); bezier(10, 20, 100, 5, 280, 155, 10, 175); Il punto di inizio e di fine della curva sono la prima e la quarta coordinata dellistruzione. La seconda e la terza coordinata indicano invece le tangenti. Per capire meglio cosa siano le tangenti consiglio di aggiungere due istruzioni in grado di visualizzarle: size (320, 240); noFill (); bezier(10, 20, 100, 5, 280, 155, 10, 175); line (10,20, 100,5); line (10,175, 280,155); Grazie alle due linee appena disegnate possiamo ora vedere le tangenti. Da notare che la curva risultante dalle nostra istruzioni tende ad essere pi accentuata verso il basso.

41

processing

guida introduttiva alla programmazione visuale

Osservando la tangente pi in basso comprendiamo il motivo. La tangente molto pi lunga pertanto essa attrae molto di pi la curva. Semplificando possiamo vedere la curva di Bezier come se fosse un elastico: con la prima e la quarta coordinata vengono fissati (inchiodati) i punti di inizio e fine dellelastico. Attraverso la seconda e terza coordinata si attrae lelastico. Quanto pi lontane sono le coordinate di attrazione tanto pi lelastico sar teso e quindi la curva sar pi accentuata. Per avere prova della desrcizione appena effettuata scrivete la seguente istruzione: bezier(10, 20, 10, 20, 10, 175, 10, 175); Il punti di tiraggio dellelastico sono ora gli stessi dei punti di terminazione dellelastico stesso. Ne risulta che la curva di Bezier una linea retta (perch il tirante non attivo avendo le stesse coordinate del punto). Attraverso questo metodo possiamo disegnare praticamente qualunque tipo di cur va. Questa funzionalit risulter particolarmente utile quando vorremo generare delle forme organiche che molto difficilmente hanno spigoli e angoli netti. Lo Sketch di seguito ci mostra il variare di una curva di bezier al variare delle coordinate delle tangenti: int contatore = 10; void setup () { size (320,240); } void draw (){ frameRate (10); background (255); //incremento il contatore contatore = contatore + 1; // definisco la curva di bezier // associando le tangenti // a un contatore per osservare // il cambiamento della curva bezier (10,10, contatore, 10, 200, 60,200); }
42

contatore,

processing

guida introduttiva alla programmazione visuale

Osservando infine il risultato delle nostre curve notiamo che esse hanno sempre un effetto di scalettatura. Questo effetto (detto aliasing) pu essere eliminato attraverso listruzione smooth (); da mettere allinizio dello Sketch. Leffetto sar di una curva molto pi morbida. In termini e l a b o r a t iv i q u e s t a g r a d e vo l e f u n z i o n a l i t e s t e t i c a d i ammorbidimento aumenter limpegno del computer. Ovviamente il fenomeno avverr quando avremo disegnato molte curve e avremo delle animazioni molto veloci. Complichiamo ulteriormente il nostro lavoro introducendo anche un fattore di casualit nella generazione della curva. Questo esercizio utile perch viene formulato in modo nuovo uno Sketch contenente solo funzionalit gi viste. Lo Sketch mandato in RUN genera una curva di bezier che nel tempo si espande verso destra o verso sinistra seguendo la casualit: int contatore = 10; // la variabile casuale float ai = 1; void setup () { size (320,240); smooth (); } void draw (){ frameRate (10); background (255); // genero un numero casuale ai = random (1); // controllo il numero estratto if (ai > 0.5) { contatore = contatore + 2; bezier (100,10, contatore, 10, contatore, 200, 120,200); } else { contatore = contatore - 2; bezier (100,10, contatore, 10, contatore, 200, 120,200); } }

43

processing

guida introduttiva alla programmazione visuale

La variabile ai legata alla generazione di un numero casuale (con decimali e quindi di tipo float) compreso tra 0 e 1. La probalit che questo numero sia superiore o inferiore a 0.5 del 50%. Tendenzialmente quindi avremo una curva che si muove c a s u a l m e n t e ve r s o d e s t r a e ve r s o s i n i s t r a ch e p e r probabilisticamente tende ad essere stabile (cio tende a ritornare alla sua posizione di partenza. Modificando listruzione if (ai > 0.5) ad esempio in if (ai > 0.4) altereremo probabilisticamente rapporto e quindi la curva tender a modificarsi verso una direzione. I vettori Quando nella programmazione si parla di vettori non ci si riferisce a delle forme grafiche bens a dei contenitori. Abbiamo gi visto nella prima parte il tipo di contenitori pi diffusi nella programmazione: le variabili. I vettori sono delle variabili concatenate in sequenza. Il termine inglese per definire i vettori Array e questi sono alcuni esempi di istruzioni: int[] vettore; float [] vettore2; Nel primo caso abbiamo la dichiarazione di un vettore che conterr dei valori interi mentre nel secondo caso abbiamo la dichiarazione di un vettore che conterr dei valori con virgola. Una volta dichiarato il tipo di vettore necessario inizializzarlo: vettore = new int[50]; vettore2 = new float[150]; Nel primo caso abbiamo inizializzato un vettore che conterr un massimo di 50 valori diversi mentre nel secondo caso abbiamo inizializzato un vettore che ne conterr 150. Queste dimensioni sono normali in molti tipi di programmi e questo proprio il motivo per il quale si usano i vettori anziche le variabili. Nel caso in cui si vogliano immagazzinare 50 informazioni usando le variabili sarebbe necessario inizializzare 50 diverse variabili. I vettori sono quindi il modo pi elegante e rapido per organizzare i dati allinterno di un programma. Troviamo i vettori praticamente in tutti i linguaggi di programmazione.

44

processing

guida introduttiva alla programmazione visuale

Vediamo ora uno Sketch che utilizza i vettori:


size (320, 240); smooth (); noFill (); int[] curva = new int[10]; // ciclo per riempire l'array for (int cicli = 0; cicli < 10; cicli = cicli +1) { curva[cicli] = int (random (200)); } // ciclo di lettura dell'array for (int cicli = 0; cicli < curva.length; cicli = cicli +1) { bezier(curva[cicli], 0, curva[cicli], 100, 200, 240, 240, 240); } // secondo ciclo di lettura dell'array for (int cicli = 0; cicli < curva.length; cicli = cicli +1) { ellipse (curva[cicli], 5, 10, 10); }

Nella quarta riga osserviamo lstruzione di inizializzazione dellarray: int[ ] curva = new int[10]; che sar quindi composto da numeri interi e si chiamer curva. Subito dopo leggiamo un ciclo for che ha la funzione di riempire larray. Il ciclo compie 10 giri e mette in ogni casella dellarray un valore casuale compreso tra 0 e 200 (curva[cicli] = int (random (200))). Successsivamente abbiamo due altri cicli. Con il primo ciclo vengono disegnate 10 curve i cui parametri sono letti dallarray precedentemente creato ( bezier(curva[cicli], 0, curva[cicli], 100, 200, 240, 240, 240)). Da notare che il parametro di chiusura del ciclo for viene stabilito attraverso un controllo della lunghezza dellarray (cicli < curva.length). Curva.lenght dichiara infatti la lunghezza dellarray che avevamo chiamato curva. Il secondo ciclo di lettura dellarray simile al primo con la differenza che vengono disegnati dei cerchi in corrispondenza del termine superiore delle curve create precedentemente. Questo secondo ciclo stato creato appositamente per dimostrare lutilit di un array. Infatti nel secondo ciclo stato riletto tutto il
45

processing

guida introduttiva alla programmazione visuale

contenuto memorizzato nellarray e che volendo potrebbe essere ulteriormente letto per funzioni future. Larray quindi ci permette di immagazzinare grandi quantit di dati evitando di dover creare numerose variabili. Inoltre grazie alla loro sequenzialit gli array facilitano laccesso per la lettura e la scrittura attraverso i cicli. Il seguente Sketch compie le stesse funzioni del precedente in modalit continuous generando un effetto di animazione. In questo caso il vettore viene riempito e svuotato automaticamente ad ogni nuovo ciclo automatico di void draw.
int[] curva = new int[10]; void setup () { size (320, 240); smooth (); noFill (); frameRate (10); } void draw () { // azzero lo schermo background (255); // ciclo per riempire l'array for (int cicli = 0; cicli < 10; cicli = cicli +1) { curva[cicli] = int (random (200)); } // ciclo di lettura dell'array for (int cicli = 0; cicli < curva.length; cicli = cicli +1) { bezier(curva[cicli], 0, curva[cicli], 100, 200, 240, 240, 240); } // secondo ciclo di lettura dell'array for (int cicli = 0; cicli < curva.length; cicli = cicli +1) { ellipse (curva[cicli], 5, 10, 10); } }

Notiamo nello Sketch precedente che ad ogni inizio di ciclo viene pulito lo schermo attraverso listruzione background (255);. Se togliamo questa istruzione vedremo che le curve si sovrapporranno progressivamente andando a formare dopo diversi secondi un intero spicchio nero. Le ultime sezioni bianche che rimangono sono i

46

processing

guida introduttiva alla programmazione visuale

numeri compresi tra zero e 200 che non sono mai stati generati. Probabilisticamente potrebbero passare anche diversi minuti senza che la funzione random generi un numero.

47

processing

guida introduttiva alla programmazione visuale

Terza Parte
Il testo Processing, come tutti i linguaggi di programmazione, permette di gestire il testo. I due comandi pi importanti sono: char (); String (); Qesti due comandi sono in realt due nuove tipi di variabili. La variabile di tipo char pu contenere un unico carattere mentre la variabile di tipo String pu contenere intere parole o frasi. Per assegnare un carattere a una variabile si scrive: char carattere = 'F'; In questo modo la lettera F viene memorizzata nella variabile carattere. Per assegnare una parole o una frase a una variabile si scrive: String testolungo = manuale di Processing; Da notare che String inizia con la lettera grande mentre char inizia con la lettera piccola. Da ricordare che i comandi di Processing debbono essere scritti tenendo conto anche di maiuscole e minuscole. Inoltre da notare che listruzione Char richiede gli apici () per evidenziare il carattere mentre listruzione String richiede le virgolette (). String pu contenere anche testi lunghi un inico carattere. Nellinformatica esiste una tabella di corrispondenza tra i caratteri e i numeri. Praticamente ogni lettera dellalfabeto stata classificata con un numero in modo sequenziale. Questa tabella di corrispondenza si chiama ASCII e ad esempio la lettera A corrisponde al numero 65. La lettera B corrisponde al numero 66 e cos via. Questa tabella di corrispondenza indispensabile poich senza di essa il computer (che ragiona per numeri) non potrebbe elaborare i testi. Le variabili di tipo char, essendo lunghe un unico carattere, possono essere ricondotte ai numeri e viceversa. Se ad esempio scriviamo:
48

processing

guida introduttiva alla programmazione visuale

char carattere = F; int numero = carattere; La variabile carattere viene riempita con il valore F, poi con la seconda istruzione la variabile numero viene riempita con il numero corrispondente alla lettera F (70) secondo il codice ASCII. Questa operazione di conversione bidirezionale dei numeri in lettere e delle lettere in numeri possibile solamente attraverso listruzione char. Con listruzione String essendo essa potenzialmente associata a testi pi lunghi di una lettera ci non possibile. Attraverso lespressione char () possiamo richiamare direttabente il codice ASCII del carattere. Ad esempio se scriviamo: char lettera = char(70); Otteniamo che la variabile lettera viene associata con la lettera F (avente come codice ASCII il numero 70). Listruzione String permette di fare operazioni sul testo. Se ad esempio associamo due variabili a due diverse parole, successivamente possiamo attaccare (sommare) le due parole. String prima = Manuale di ; String seconda = Processing; String somma = prima + seconda; La variabile somma avr come risultato Manuale di Processing. Da notare che dopo lespressione Manuale di stato lasciato appositamente uno spazio in modo che esso risulta presente nella somma delle due variabili. Il modo pi velore per vedere il risultato di queste operazioni sule variabili testuali (ma anche per quelle numeriche) luso dellistruzione println(somma); Questa istruzione println mostra un valore nella finestra della console. La stessa finestra dellambiente di sviluppo dove ci appaiono gli errori. Questa finestra utile quindi anche quando si sta lavorando ad un programma e si voglieno controllare dei valori intermedi e temporanei di alcune variabili. Caratteri sullo schermo Processing utilizza i font che sono stati precedentemente dichiarati. A differenza dei normali programmi di scrittura, dove troviamo il men a tendoina con tutti i font disponibili, Processing, essendo un
49

processing

guida introduttiva alla programmazione visuale

ambiente di sviluppo permette di utilizzare qualunque font che sia stato precedentemente impostato. Infatti Processing utilizza solamente tipi di carattere in formato VLW. Quando allinterno di uno Sketch sviluppato in Processing intendiamo utilizzare un font dobbiamo prima di tutto importare il font stesso attraverso il Men Tool comando Create Font. Dando questo comando si apre una finestra nella quale compare la lista dei caratteri installati nel proprio computer. Si seleziona il carattere e la relativa dimensione che si vuole importare e cliccando su OK verr automaticamente creato un file che poi potr essere richiamato allinterno dello Sketch. Se ad esempio vogliamo utilizzare il font Courier nella dimensione 12 allinterno del nostro Sketch dopo avere generato il file dovremo richiamare un file di questo nome: Courier-12.vlw. Ecco uno Sketch: size (320, 240); background (255); // Inizializzo la variabile PFont carattere; // Carico il font nello Sketch carattere = loadFont("Courier-12.vlw"); // Stabilisco il font che sto per usare textFont(carattere); fill(0); // Scrivo il testo text("Manuale di Processing", 30, 100); Con PFont viene inizializzata una variabile che conterr il nome del font stesso. Con carattere = loadFont("Courier-12.vlw"); carico nello Sketch il font che intendo utilizzare e ovvimente potrei carirarne anche pi di uno. Poi successivamente, quando star per utilizzare il font, dichiaro il suo uso con textFont(carattere); e con fill (0); stabilisco che il carattere sar di colore nero. Con listruzione text dichiariamo il testo che vogliamo scrivere (potremmo in alernativa mettere il nome di una variabile String) in seguito troviamo le coordinate X,Y dove comparir il testo. Nel seguente Sketch abbiamo la situazione del precedente con lunica differenza che attraverso listruzione textSize(18); il testo avr una dimensione diversa da quella importata.

50

processing

guida introduttiva alla programmazione visuale

size (320, 240); background (255); PFont carattere; carattere = loadFont("Courier-12.vlw"); textFont(carattere); textSize(18); fill(0); text("Manuale di Processing", 30, 100); Questa operazione di ingrandimento rappresenta un degradamento della qualit del carattere che risulter sgranato tanto pi sar stato ingrandito. Infatti atttaverso lazione di importazione del carattere abbiamo importato delle immagini bitmap (pixel per pixel) del font. Qualitativamente quindi consigliabile importare i caratteri in tutte le dimensioni che si vorranno utilizzare. Il seguente Sketch invece un semplice esempio di animazione di un testo. Si tratta allincirca della somma dello Sketch precedente e dell Sketch utilizzato nelle pagine precedenti per animare un punto facendolo scorrere da sinistra a destra:
void setup () { size (320, 240); } int intervallo = 0; void draw (){ background (255); PFont carattere; carattere = loadFont("Courier-12.vlw"); frameRate (10); textFont(carattere); textSize(12); fill(0); text("ciao a tutti", intervallo, 120); intervallo = intervallo + 1; }

Lavorare con le Stringhe Processing permette di lavorare con le stringhe attraverso delle apposite istruzioni. Se ad esempio abbiamo la variabile testolungo associata ad una string:

51

processing

guida introduttiva alla programmazione visuale

String testolungo = manuale di Processing; Possiamo misurare la lunghezza della stringa attraverso listruzione lunghezza = testolungo.length (); Dove lunghezza sar una variabile di tipo int e in questo caso restituir il numero 21, ossia la lunghezza del testo manuale di Processing inclusi gli spazi tra una parola e laltra. Mentre con la linea di comando: char iniziale = (testolungo.charAt(0)); Trasferisce il primo carattere (indicato con la posizione 0) della variabile testolungo nella variabile iniziale. Pertanto charAt(1) restituir la a di manuale mentre il numero 6 ci dar la lettera e. Il numero 20 la lettera g di Processing. Attraverso listruzione substring (); possiamo invece prendere delle parti di una scringa ed associarle ad unaltra variabile (oppore stamparle...). string pezzo = testolungo.substring(2,6); Con questa linea di istruzione abbiamo trasferito in una nuova variabile pezzo tutte le lettere comprese tra la posizione 2 e la posizione 6 esclusa della variabile testolungo. In pratica abbiamo trasferito nual nella variabile pezzo. Il seguente Sketch produce una linea la cui lunghezza inversamente legata alla lunghezza di un testo associato ad una variabile di tipo String. size (320, 240); String testolungo = "Manuale Processing" ; // misuro la lunghezza di testolungo int lunghezza = testolungo.length (); // memorizzo il primo carattere // nella variabile iniziale char iniziale = (testolungo.charAt(0)); //produco una linea //usando la lunghezza line (lunghezza, lunghezza, 100, 100); di

52

processing

guida introduttiva alla programmazione visuale

Notiamo che il primo punto della linea legato alla variabile lunghezza che abbiamo utilizzato per misurale la lunghezza del testo manuale di Processing. Aggiungesto altre parole al testo manuale di Processing e mandando in RUN lo Sketch vediamo che la linea tende progressivamente ad accorciarsi.

53

processing

guida introduttiva alla programmazione visuale

Quarta Parte
Grafica e Movimenti pi complessi Processing un software specializzato per la grafica e le animazioni. Tutte le istruzioni che abbiamo visto fino a questo punto ci hanno permesso di comprendere i principi fondamentali della computergrafica bidimensionale. Le forme che abbiamo disegnato fino ad ora sono relativamente semplici. Abbiamo visto con le curve di Bezier come sia possibile disegnare qualunque tipo di curva utilizzando 4 paramentri. Vediamo ora prima di tutto come animare le forme grafiche. In realt abbiamo gi visto come sia possibile, attraverso luso dei contatori e la pulizia dello schermo , animare curve e punti. Processing ci viene incontro in queste funzionalit di animazioni attraverso tre funzioni di animazione: translate (); rotate (); scale (); Attraverso queste tre semplici istruzioni possiamo applicare degli effetti graficamente complessi a tutte le immagini presenti allinterno del nostro Sketch. Sappiamo che scrivendo queste due istruzioni: size (320, 240); line(10, 20, 100, 120); otteniamo una linea che attraverso lo schermo. Attraverso listruzione translate(); abbiamo la possibilit di traslare la linea sulle coordinate X e Y. Infatti se scriviamo: size (320, 240); translate(100, 0); line(10, 20, 100, 120); succede che la linea, a differenza del precedente Sketch, avr delle cordinate traslate di 100 pixel sullasse delle X. Le nuove coordinate della linea saranno: (110, 20, 200, 120). I due valori X dei due punti sono stati incrementati di 100 pixel.

54

processing

guida introduttiva alla programmazione visuale

Ecco il risultato aritmetico dellistruzione: line (10 + 100, 20 + 0, 100 + 100, 120 + 0); Ovviamente possiamo traslare sia le coordinate X che le Y, ecco un esempio: size (320, 240); translate(100, 25); line(10, 20, 100, 120); La linea disegnata sullo schermo avr le seguenti coordinate: line (110, 45, 200, 145); Listruzione traslate attiva per tutte le forme grafiche che appaino successivamente ad essa. Pertanto se tracciamo due linee dopo listruzione traslate otteniamo che tutte e due le linee saranno traslate. size (320, 240); translate(100, 25); line (10, 20, 100, 120); line (20, 40, 200, 100); Mandando in RUN lo Sketch vediamo che sia la prima che la seconda linea risultano traslate. Inoltre le traslazioni si sommano, pertanto se vogliamo ulteriormente traslare una linea dopo una prima traslazione sar sufficiente inserire la nuova traslazione. size (320, 240); translate(100, 25); line (10, 20, 100, 120); translate(80, 15); line (20, 40, 200, 100); La seconda linea del precedente Sketch traslata nelle sue coordinate di 180 (100+80) pixel sullasse X e 40 pixel sullasse Y (25+15). Mentre la prima linea risulta traslata solamente dei valori del primo comando traslate.

55

processing

guida introduttiva alla programmazione visuale

Per ripristinare le condizioni originarie sufficiente mettere in negativo i valori di traslate. Nel sequente Sketch le coordinate della seconda linea sono normali. size (320, 240); translate(100, 25); line (10, 20, 100, 120); translate(-100, -25); line (20, 40, 200, 100); Poich la seconda istruzione traslate sottrae esattamente i valori della prima istruzione, la seconda linea avr le coordinate: line (20, 40, 200, 100); Proprio come indicato nello Sketch stesso. Rotazione I principi della traslazione valgono anche nel caso della rotazione. Essi quindi sono validi finch non intervenga un nuovo valore che si somma al precedente. Per capire lunit di misura dela rotazione dobbiamo capire il concetto di radiante. Normalmente misuriamo i giri in gradi, quindi un giro completo di 360 gradi mentre un giro di 180 gradi mezzo giro. Una ruotazione ad angolo retto una ruotazione di 90 gradi. I radianti sono legati alla costante matematica detta Pi greco PI o . Il pi greco misura il rapporto tra una qualunque circonferenza di un cerchio e il suo relativo diametro. Questo rapporto costante e viene sintetizzato in 3.14 anche se i decimali dopo la virgola sono infiniti. La corrispondenza tra i gradi e i radianti molto semplice: - due radianti (2 * ) sono 360 gradi - un radiante () 180 gradi - mezzo radiante (/2) 90 gradi In processing si scrive PI. Il seguente Sketch mostra la ruotazione di una stessa linea di 90 gradi: size (240, 240); line(0, 0, 100, 0); rotate(PI/2); line(0, 0, 100, 0);
56

processing

guida introduttiva alla programmazione visuale

Mandando in RUN lo Sketch lediamo una linea in alto orizzontale (la prima linea dello Sketch) e una seconda linea verticale che la seconda linea dello Sketch. La seconda linea ha subito quindi una rotazione di 90 gradi in senso orario. Le dimensione dello schermo questa volta sono state impostate a (240, 240) al fine di facilitare la comprensione dei gradi. Osserviamo infatti una rotazione di 45 gradi: size (240, 240); line(0, 0, 240, 0); rotate(PI/4); line(0, 0, 240, 0); Vediamo che la seconda linea in questo caso ruotata di 45 gradi e grazie al fatto che la finestra quadrata possiamo osservare che essa traccia una pate della diagonale della finestra stessa. Di seguito vediamo tre linee. La prima non subisce alcuna ruotazione mentre la seconda subisce una ruotazione di 45 gradi (PI/4) e la terza ruota di 90 gradi (PI/4 + PI/4 = PI/2). size (240, 240); line(0, 0, 240, 0); rotate(PI/4); line(0, 0, 240, 0); rotate(PI/4); line(0, 0, 240, 0); La funzione di ruotazione funziona quindi come la funzione di traslazione. Per eliminare il suo effetto sufficiente riproporre il valore in negativo: size (240, 240); line(0, 0, 240, 0); rotate(PI/4); line(0, 0, 240, 0); rotate(- PI/4); strokeWeight (5); line(0, 0, 200, 0); In questo caso la terza linea sembra scomparire mentre in realt essa perfettamente sovrapposta alla prima linea. Per questo motivo ho
57

processing

guida introduttiva alla programmazione visuale

aumentato lo spessore della linea strokeWeight (5); inoltre ho leggermente accorciato la lua lunghezza in modo che si possa cogliere anche la prima linea. Infine per comprendere completamente il tipo di ruotazione che avviene mandiamo in RUN il seguente Sketch size (240, 240); ellipse (100, 0, 20, 20); rotate(PI/4); ellipse (100, 0, 20, 20); Vediamo anche in questo caso che il cerchio si sposta. Mentre se il cerchio ruotasse su se stesso non dovremmo vedere alcuno spostamento. In effetti con il comando rotate cos come con il comando translate ci che ruota non loggetto bens la finestra con tutto ci che disegnato al suo interno. Questa ruotazione fa perno sulla coordinata (0,0) dello schermo. Scala Per ingrandire o rimpiccolire un oggetto si utilizza listruzione scale ();. Il seguente Sketch mostra due cerchi dove il secondo cerchio stato raddoppiato nelle sue dimensioni: size (240, 240); ellipse (100, 100, 20, 20); scale (2); ellipse (100, 100, 20, 20); Le coordinate del cerchio cambiano proprio perch la finestra che si raddoppia nella sua dimensione con tutti i suoi contenuti. Il seguente Sketch mostra tre cerchi. Il terzo cerchio ha le stesse proporzioni del primo ma ho modificato il riempimento e ridimensionato il raggio. size (240, 240); ellipse (100, 100, 20, 20); scale (2); ellipse (100, 100, 20, 20); scale (0.5); fill (100,20);

58

processing

guida introduttiva alla programmazione visuale

ellipse (100, 100, 10, 10); Vediamo che attraverso listruzione scale (0.5); stato diviso per due il precedente rapporto di ingrandimento scale(2). In questo modo il rapporto finale 0.5*2 cio 1. Questultimo Sketch ci mostra tre cerchio scalati ogni volta per due. Il terzo cerchio sar quindi 4 volte (2*2) pi grande del primo. size (240, 240); ellipse (50, 50, 20, 20); scale (2); ellipse (50, 50, 20, 20); scale (2); ellipse (50, 50, 20, 20); Da notare che anche la distanza tra il secondo e il terzo cerchio doppia rispetto alla distanza tra il primo e il secondo cerchio. Infine notiamo che le tre funzionalit di modifica delle forme grafiche possono ovviamente essere utilizzate in modo combinato. size (240, 240); ellipse (50, 50, 20, 20); scale (2); ellipse (50, 50, 20, 20); translate (20, 0); ellipse (50, 50, 20, 20); Nel precedente Sketch i cerchio risulter traslato di 20 pixel sullasse delle X e ingrandito di due volte. Il secondo cerchio ha invece subito solamente lingrandimento ma non la traslazione.

59

processing

guida introduttiva alla programmazione visuale

Quinta parte
Arduino Arduino una piattaforma open source per lo sviluppo e la progettazione di oggetti interattivi. Lo scopo principale di questa scheda quella di dare la possibilit a sviluppatori e artisti di progettare prototipi letteralmente giocando con lelettronica e sperimentando con sensori, attuatori e controller elettronici. Questa particolare ricerca nellinterazione tra il calcolatore e il mondo fisico nota come Physical Computing ed era fino a pochi anni fa una disciplina conosciuta e utilizzata solo in campo ingegneristico, che richiedeva una conoscenza avanzata dellelettrotecnica e del software. Questo livello di complessit ha tenuto per anni lontani gli ideatori, gli obbisti e gli artisti dalle infinite possibilit che lelettronica pu aprire nel mondo del design e dellarte in generale. Lo scopo degli sviluppatori di Arduino quello di fornire uno strumento semplice che permetta a chiunque di iniziare a costruire progetti interattivi in modo immediato ed economico. Grazie a questa semplicit di utilizzo e alla crescente diffusione, oggi Arduino oltre a risolvere numerosi problemi nello sviluppo e nella realizzazione di oggetti interattivi, alla base di una nuova filosofia che cresce e si alimenta dal mondo dellopen source e dalla condivisione di conoscenze tipica della rete. Nel mondo anglosassone questo modo di procedere nello sviluppo noto come Tinkering, una forma di deriva creativa guidata dallimmaginazione e dalla curiosit. Mentre il percorso di sviluppo ingegneristico classico presuppone una progettazione che procede in modo razionale dal punto A al punto B, il Tinkering presuppone il perdersi in questo percorso e scoprire un nuovo punto C. Tinkering significa in pratica trovare risultati curiosi provando e sbagliando procedimenti ignoti.

60

processing

guida introduttiva alla programmazione visuale

Costruire senza le istruzioni, giocando con i fallimenti, non preoccupandosi del modo giusto o sbagliato di fare le cose. Uno dei modi migliori di utilizzare questo processo creativo riutilizzare tecnologie esistenti, smontare vecchi apparecchi elettronici e usarne parti interessanti sfruttandole per utilizzi lontani da quelli per cui erano state progettate. Questo approccio spontaneo e casuale alla base di alcune nuove forme darte come il Circuit Bending: un genere musicale suonato con vecchi strumenti giocattolo elettronici, smontati e modificati per creare suoni completamente diversi da quelli pensati dal costruttore originario. Arduino insomma rappresenta oggi una nuova ottica con cui guardare la tencologia che ci circonda, sviluppare nuove funzioni per strumenti vecchi ed esplorare nuove possibilit senza il bisogno di perdersi in anni di studi ma semplicemente giocando con ci che gi abbiamo a portata di mano sfruttando listinto di ogni bambino... smontare i giocattoli per vedere cosa c dentro. LHardware: Arduino una scheda composta principalmente da un processore e una serie di ingressi e uscite sia digitali che analogici, alimentabile sia via USB che tramite un alimentatore esterno.

61

processing

guida introduttiva alla programmazione visuale

Il Software: Il processore di Arduino programmabile attraverso un ambiente di sviluppo(IDE) basato su Processing. Tutto il software necessario allutilizzo di Arduino oltre a svariati esempi di codice scaricabile gratuitamente dal sito www.arduino.cc Una volta scritto il programma nelleditor principale (proprio come un programma in Processing) va controllata la sua correttezza, premendo verify, se il codice scritto correttamente apparir il messaggio Done compiling, a questo punto possibile caricare il programma nel processore di Arduino. Premendo il bottone reset su Arduino si hanno 6 secondi per premere Upload to I/O board nella parte alte dellIDE. Questo procedimento invia il programma alla scheda, lo salva nella sua memoria e lo esegue automaticamente.

62

processing

guida introduttiva alla programmazione visuale

La BreadBoard Prima che il vostro circuito funzioni perfettamente ci sar bisogno di vari tentativi e saldare diversi tentativi su una piastra un lavoro lungo e dispendioso. Lequivalente elettronico dello schizzo iniziale di un progetto fatto su un foglio di carta la BreadBoard. Si tratta in pratica di una piastra di plastica piena di fori ognuno dei quali contiene un contatto. Quando si mette un componente in uno di questi fori si crea un contatto elettrico con tutti gli altri fori della stessa colonna verticale. Le due coppie di linee di fori in alto e in basso della Breadboard (solitamente colorate di rosso e blu e con il segno+ e -) sono invece collegate in orizzontale e sono usate per portare lalimentazione in tutta la piastra.

63

processing

guida introduttiva alla programmazione visuale

LInterazione Lutilizzo piu frequente di Arduino lo sviluppo di oggetti interattivi. Il funzionamento base che accomuna questo dipo di dispositivi segue uno schema molto semplice: Le informazioni che il dispositivo legge dal mondo esterno attraverso dei sensori vengono elaborate dal programma allinterno del processore, questo decider il comportamento del dispositivo che interagir di consegueza con il mondo esterno attraverso degli attuatori. Sensori e attuatori sono componenti elettronici, i primi leggono delle informazioni dal mondo fisico e le trasformano in segnali interpretabili dal processore, i secondi convertono i segnali del processore in azioni fisiche. Per semplificare queste definizioni con un esempio, nel corpo umano, gli occhi sono dei sensori che convertono la luce in immagini, il cervello (nel nostro caso il processore) elabora le immagini e manda segnali ai muscoli (attuatori).

64

processing

guida introduttiva alla programmazione visuale

Un primo esempio pratico Vediamo con un esempio pratico come lo schema precedente di interazione possa trovare un applicazione con Arduino. Costruiamo un semplice dispositivo che accende un LED (lightemitting diode) quando viene premuto un bottone. In questo caso il bottone rappresenta il sensore e il LED lattuatore. Iniziamo costruendo il semplice circuito illustrato nella seguente figura.

65

processing

guida introduttiva alla programmazione visuale

N.B. il LED va inserito con il contatto piu corto nel pin GND e con quello piu lungo nel pin 13. Scriviamo poi nellIDE il seguente programma:
// primo esempio di interazione con Arduino const int buttonPin = 7; // numero del pin del bottone const int ledPin = 13; // numero del pin del LED int buttonState = 0; // variabile che legge il bottone void setup() { // inizializza il pin del LED come output pinMode(ledPin, OUTPUT); // inizializza il pin del bottone come input pinMode(buttonPin, INPUT); } void loop(){ // legge lo stato del bottone buttonState = digitalRead(buttonPin); // controlla se il bottone e premuto // se e premuto e LOW if (buttonState == LOW) { // accende il LED digitalWrite(ledPin, HIGH);

66

processing

guida introduttiva alla programmazione visuale

} else { // spegne il LED digitalWrite(ledPin, LOW); } } Carichiamo il codice nella scheda e vediamo che il LED si illumina quando il pulsante viene premuto.

Questo avviene perch la funzione digitalRead();

legge se un voltaggio passa nel pin precedentemente dichiarato, se il voltaggio inferiore a 2.5V (bottone premuto) allora la funzione ritorner un valore LOW e di conseguenza accender il LED con la funzione: digitalWrite(ledPin, HIGH); mentre se passer un voltaggio superiore allora ritorner un valore HIGH (che corrisponde al bottone non premuto). Proprio come in un programma in Processing dobbiamo inizialmente dichiarare variabili e costanti, anche nel programmare Arduino necessario dichiarare come i pin della scheda verranno utilizzati. allinterno della funzione void setup(); dobbiamo configurare se il comportamento di un determinato pin sar di INPUT o di OUTPUT. Nel nostro precedente esempio con il codice pinMode(ledPin, OUTPUT); abbiamo dichiarato che il pin 13 verr utilizzato come Output mentre con

67

processing

guida introduttiva alla programmazione visuale

pinMode(buttonPin, INPUT); dichiariamo che il pin 7 si comporter come INPUT. La funzione digitalRead(pin); legge il valore HIGH o quello LOW da uno specifico pin digitale mentre quella analogRead(pin); legge un valore intero da 0 a 1023 da uno dei pin da 0 a 5. La funzione digitalWrite(pin, valore); manda in output un valore HIGH o uno LOW ad uno specifico pin. Mentre la funzione analogWrite(pin, valore); manda un valore analogico da 0 a 255 ad uno dei pin 9, 10 o 11 (nei modelli di Arduino pi nuovi, quelli con il processore ATmega 168 si possono utilizzare i pin 3, 5, 6, 9, 10 e 11). In questo caso ad un valore di 0 corrisponde 0 volts mentre ad un valore di 255 corrisponde un voltaggio di 5V.

68

processing

guida introduttiva alla programmazione visuale

Questo manuale scritto sotto licenza Creative Commons e gli autori accettano volentieri proposte di nuove parti da aggiungere ad esso. Chi volesse proporsi pu scrivere a: Alberto Cecchi: mail@albertochecchi.name Valerio Belloni: valerio78@gmail.com

processing guida introduttiva alla programmazione visuale ver. 0.9 oct. 2009

69