Skip to content

Come creare la prima locandina

Daniele Olmisani edited this page Oct 24, 2015 · 1 revision

Per iniziare

In questo capitolo vedremo come creare una elegante locandina minimalista utilizzando Processing (www.processing.org). Seguiremo, passo per passo, tutte le operazioni necessarie per creare la locandina de Il Signore degli Anelli, film di animazione del 1978, diretto da Ralph Bakshi (The Lord of the Rings - http://www.imdb.com/title/tt0077869).

Il risultato finale sarà (più o meno) questo:

In questo capitolo faremo uso di OpenProcessing (www.openprocessing.org). Un sito web dove è possibile scrivere ed eseguire programmi in Processing senza dover installare niente sul proprio computer. Comunque, le stesse operazioni possono essere facilmente ripetute utilizzando l'ambiente di sviluppo ufficiale di Processing (www.processing.org).

Prepariamo il piano di lavoro

Come ogni attività fai da te che si rispetti, iniziamo con il ripulire il piano di lavoro. Andiamo sulla pagina principale di OpenProcessing e selezioniamo il collegamento Create a new sketch. Sulla tastiera, premiamo CTRL-A e poi Canc per cancellare il programma di esempio.

Adesso abbiamo il campo libero per dipingere (ehm... digitare) il nostro capolavoro.

Tiriamo fuori lo scheletro dall'armadio

Nella finestra di scrittura (quella tutta bianca... perché l'abbiamo appena ripulita), inseriamo la struttura principale del nostro programma.

void setup() {
}

void draw() {
}

Premiamo il pulsante Run per ottenere il seguente risultato:

Sempre che, ovviamente, il programma sia stato inserito correttamente.

Diamo un occhiata in dettaglio a quello che abbiamo appena inserito. Il nostro programma è composto da due funzioni principali:

  • la funzione setup() che conterrà le istruzioni necessarie per preparare l'area di disegno.
  • la funzione draw() che, invece, conterrà le istruzioni per il disegno vero e proprio.

Queste due funzioni sono eseguite ogni volta che viene premuto il pulsante Run.

Pensiamo un po' più in grande

Il disegno che abbiamo ottenuto ha una dimensione predefinita di 100 per 100 punti (pixel). Creiamo un po' di spazio aggiungendo le istruzioni necessarie per avere una area di disegno di 640x480 pixel.

void setup() {
    size(480, 640);
}

void draw() {
}

Premendo ancora il pulsante Run otteniamo questa nuova immagine, un po' più grande rispetto la precedente:

Una immagine sul computer non è composta da tratti continui (come un segno di penna su un foglio), ma è simile ad un quadro di un pittore del Puntinismo (https://it.wikipedia.org/wiki/Puntinismo), composto da tanti puntini colorati. Nel gergo dell'informatica i punti colorati che compongono una immagine sono chiamati pixel.

Cosa farò da grande: il Pittore o il Regista?

Processing è nato per costruire sequenze animate, ma può essere anche usato (come nel nostro caso) per disegnare immagini statiche. Le nostre locandine non saranno animate, quindi specifichiamo nella sezione setup() che il nostro disegno sarà composto da un singolo quadro (o fotogramma).

void setup() {
    size(480, 640);
    noLoop();
}

void draw() {
}

Questa aggiunta non comporta grandi cambiamenti nel nostro disegno. Infatti, premendo il pulsante Run otteniamo lo stesso disegno del passo precedente:

Comunque questo passaggio è importante perché stiamo informando Processing che la funzione draw() dovrà essere richiamata una solo volta. Evitando, in questo modo, di sovrascrivere il quadro già disegnato.

Disegniamo un cerchio senza matita e compasso

E' giunto il momento di disegnare qualcosa. Incominciamo con qualcosa di semplice e proviamo a disegnare una circonferenza.

Non serve la sensibilità artistica di Giotto per disegnare un cerchio perfetto, ma una semplice funzione. La funzione ellipse(x, y, w, h) permette di tracciare una ellisse nell'area di disegno.

Questa funzione accetta quattro parametri:

  • x e y definiscono dove posizionare il centro della ellisse
  • w e h definiscono la lunghezza dell'asse verticale ed orizzontale della ellisse

Se i due valori w e h sono uguali, allora otteniamo una circonferenza

Proviamo a disegnare la nostra circonferenza all'origine degli assi nel punto (0, 0) con diametro, per il momento, di 200 pixels.

void setup() {
    size(480, 640);
    noLoop();
}

void draw() {

    ellipse(0, 0, 200, 200);
}

Dopo aver modificato il testo del programma, premiamo il pulsante Run per vedere come abbiamo modificato l'immagine:

Oops! Cosa è successo? Per motivi prevalentemente storici, l'origine degli assi della nostra area di disegno si trova nell'angolo in alto a sinistra. Inoltre, l'asse delle ordinate (quello delle y, per intenderci) va dall'alto verso il basso, mentre quello delle ascisse (quello delle x) va da sinistra a destra.

Cambiamo punto di vista

Vediamo come sia possibile centrare meglio la nostra circonferenza, in modo che sia completamente inclusa nella area di disegno. Per fare questo, utilizzeremo la funzione translate(dx, dy). Questa funzione permette di spostare tutto il disegno per una specifica distanza orizzontale (valore dx) e verticale (valore dy). Per semplificare i calcoli utilizzeremo le variabili width ed height. Queste variabile sono definite dal sistema di disegno di Processing e permettono di ottenere, rispettivamente, la larghezza l'altezza dell'area di disegno. Quindi il comando translate(width/2.0, height/2.0) non farà altro che spostare la circonferenza esattamente al centro dell'area di disegno.

void setup() {
    size(480, 640);
    noLoop();
}

void draw() {

    translate(width/2.0, height/2.0);

    ellipse(0, 0, 200, 200);
}

Premiamo il pulsante Run per aggiornare il disegno:

Prendiamo le misure

Abbiamo scelto di disegnare una circonferenza di diametro prefissato di 200 pixels. Ma come fare per mantenere le proporzioni invariate indipendentemente dalla dimensioni dell'area di disegno? Supponiamo di volere che il diametro della circonferenza sia circa il 60% delle dimensioni dell'area di disegno. Con l'istruzione float s = 0.6 * min(width, height); stiamo dicendo di fare questo:

  • min(width, height) scegliamo la dimensione più piccola tra larghezza ed altezza dell'area di disegno
  • 0.6 * min(width, height) di questo valore ne calcoliamo il 60%
  • float s = 0.6 * min(width, height) memorizziamo il valore ottenuto in una variabile di nome s

Tra width e height scegliamo la dimensione più piccola perché la circonferenza non esca fuori dall'area di disegno. La parola chiave float indica che stiamo trattando valori numerici non interi (con la virgola, per intenderci). Una variabile permettere di memorizzare un particolare valore. Tutte le volte che si vorrà utilizzare il valore memorizzata sarà sufficiente inserire il nome della variabile.

In questo modo, con l'istruzione ellipse(0, 0, s, s) stiamo chiedendo di disegnare la circonferenza di diametro pari al valore memorizzato nella variabile s.

void setup() {
    size(480, 640);
    noLoop();
}

void draw() {

    translate(width/2.0, height/2.0);

    float s = 0.6 * min(width, height);
    ellipse(0, 0, s, s);
}

Forgiamo l'Unico Anello

void setup() {
    size(480, 640);
    noLoop();
}

void draw() {

    translate(width/2.0, height/2.0);

    float s = 0.6 * min(width, height);

    noFill();
    strokeWeight(0.15*s);

    ellipse(0, 0, s, s);
}

Aggiungiamo un tocco di colore

void setup() {
    size(480, 640);
    noLoop();
}

void draw() {

    translate(width/2.0, height/2.0);

    float s = 0.6 * min(width, height);

    background(43, 61, 38);
    stroke(243, 220, 0);

    noFill();
    strokeWeight(0.15*s);

    ellipse(0, 0, s, s);
}

Salviamo il tutto

void setup() {
    size(480, 640);
    noLoop();
}

void draw() {

    translate(width/2.0, height/2.0);

    float s = 0.6 * min(width, height);

    background(43, 61, 38);
    stroke(243, 220, 0);

    noFill();
    strokeWeight(0.15*s);

    ellipse(0, 0, s, s);
    
    save("the-lord-of-the-rings.png");
}

Rifiniamo qualche dettaglio

final color PAPER = color(45, 60, 40);
final color INK = color(245, 220, 0);

void setup() {
    size(480, 640);
    noLoop();
}

void draw() {

    translate(width/2.0, height/2.0);

    float s = 0.6 * min(width, height);

    background(PAPER);
    stroke(INK);

    noFill();
    strokeWeight(0.15*s);

    ellipse(0, 0, s, s);
    
    save("the-lord-of-the-rings.png");
}

Mettiamoci una firma sopra

// Manuale di Programmazione Cinematografica
// Daniele Olmisani, 2015

// The Lord of the Rings

final color PAPER = color(45, 60, 40);
final color INK = color(245, 220, 0);

void setup() {
    size(480, 640);
    noLoop();
}

void draw() {

    translate(width/2.0, height/2.0);

    float s = 0.6 * min(width, height);

    background(PAPER);
    stroke(INK);

    noFill();
    strokeWeight(0.15*s);

    ellipse(0, 0, s, s);
    
    save("the-lord-of-the-rings.png");
}