Calcolatore (5) - Grafica, …
(vedi qui per aggiornamenti)

#1  Coordinate schermo (concrete) e cartesiane (virtuali)
    Con un computer si possono disegnare, muovere e trasformare figure. Nella voce  calcolatore (4) abbiamo visto come un'immagine che appare sullo schermo è digitalizzata. Sotto a sinistra è riprodotto il momento in cui, con un programma per costruire immagini, si sta tracciando un punto-pixel (il puntatore del mouse ha assunto l'aspetto di una matita). In fondo alla finestra associata alla applicazione appaiono le coordinate-schermo del pixel (29 e 24 in questo caso): sono i numeri d'ordine della colonna e della riga in cui è collocato; le colonne vengono numerate a partire da sinistra iniziando con il numero 0; analogamente, a partire dall'alto (non dal basso!), vengono numerate le righe.

 

    Sopra a destra è raffigurata una successione di segmenti tracciata al computer e (nell'ingrandimento) sono evidenziate le coordinate-schermo dei loro estremi.
    Sotto è riportato un programma in Qbasic per tracciare la stessa figura (in colori invertiti). Rinviamo all'help per la spiegazione delle istruzioni. Nei linguaggi di programmazione per Windows le istruzioni per tracciare linee e punti sono simili, ma occorre aggiungere vari comandi per definire le finestre, i modi in cui aggiornarne il contenuto, …. Nel seguito, per semplicità, faremo altri esempi riferendoci al QBasic, anche se, in modalità grafica, non ha un buon funzionamento nelle ultime versioni di Windows. Si veda l'ultimo paragrafo per un esempio di programma realizzato in un linguaggio di programmazione specifico per Wiindows.

SCREEN 12       'imposto la modalita` grafica
PSET (10, 10)   'traccio un punto
LINE -(30, 30)  'congiungo il punto precedente a uno nuovo
COLOR 10
LINE -(60, 30)
LINE -(30, 60)
COLOR 14
LINE -(0, 0)
Al posto delle righe 2 e 3 potevo usare: LINE (10, 10)-(30, 30).

#2  Come viene memorizzata una immagine? Oltre che memorizzarla pixel per pixel, se ne possono memorizzare solo alcuni punti mediante i quali, con opportuni programmi, si può ricostruire l'intera immagine.
    Ad esempio nel caso della figura precedente si possono memorizzare in un file le coordinate dei soli punti (10,10), (30,10), (60,30), (30,60) e (0,0); per vedere l'immagine si può poi utilizzare una applicazione che legga dal file le coordinate dei punti e man mano, in modo simile al programma sopra riprodotto, li congiunga con dei segmenti.
    Ad esempio nel caso dell'applicazione Poligon del software MaCoSa, con cui sono stati realizzati i grafici presenti in questo "dizionario", per ottenere la figura precedente si possono o introdurre le coordinate dei 5 punti direttamente durante l'esecuzione del programma o richiamarle da un file in cui siano già state memorizzate. Qualcosa di simile si può fare con Derive (e con Maple). Ecco come si presentano i file per queste due applicazioni (in un caso un file i cui in righe successive sono indicati prima la quantità dei punti e poi le loro coordinate, nell'altro un'unica riga in cui tra parentesi quadre è rappresentata la sequenza delle coppie di coordinate, a loro volta racchiuse tra parentesi quadre). Sotto è riprodotta la figura come viene visualizzata a seconda che si scelga l'opzione "punti congiunti" (a sinistra) o l'opzione "punti non congiunti" (a destra).

5
10,10
30,30
60,30
30,60
0,0
  POLIGON   
 
DERIVE
   [[10,10],[30,30],[60,30],[30,60],[0,0]]


[a destra è descritto il rettangolo cartesiano visualizzato; nel caso di
Derive occorre operare qualche zoom prima di vedere tutta la figura,
e non è facile ottenere una rappresentazione monometrica]

#3  Confrontando queste con le figure precedenti si noti che i punti non vengono rappresentati in corripondenza dei pixel aventi le loro coordinate come coordinate-schermo (del resto la "scala" in queste applicazioni può essere modificata) e che l'immagine appare capovolta: queste (e altre) applicazioni matematiche accettano input in coordinate virtuali, cioè coordinate cartesiane usuali e poi le trasformano automaticamente, in base alla scala scelta, in coordinate-schermo, cioè nelle coordinate che individuano concretamente la posizione dei punti da visualizzare.

    Il programma seguente illustra come tracciare punti introdotti in coordinate cartesiane avendo associato al rettangolo concreto (sulla finestra del Qbasic) che ha come estremi opposti i pixel (19,12) e (216,130) il rettangolo cartesiano che ha come estremi (-10,5) e (10,-5). Nella figura sottostante si vede come al punto (x,y) = (-3.2,0.7) è associato il pixel (86,63); il commento a lato spiega le parti sottolineate nel programma.

SCREEN 12
o1=19 : o2=216 : v1=12 : v2=130   'coordinate schermo della finestra
x1=-10 : x2=10 : y1=-5 : y2=5     'coordinate del rettangolo cartesiano
RapOr=(o2-o1)/(x2-x1) : RapVer=(v2-v1)/(y2-y1)    'rapporti di scala
Punto:
  LOCATE 20,1: INPUT x,y   'dalla riga 20 di testo batti coord.cartes.
  o=o1+(x-x1)*RapOr : v=v1+(y2-y)*RapVer   'trasformo in coord.schermo
  PSET (o,v)
GOTO Punto

  

• il punto (x,y)=(-3.2,0.7) dista, in coordinate cartesiane, x-x1 = x-(-10) = 6.8 dal bordo sinistro della finestra;
• trasformo questa distanza in coordinate schermo moltiplicando per il rapporto di scala orizzontale RapOr = DistanzaSchermo/DistanzaCartesiana = (216-19)/20 = 9.85;
• aggiungo 6.8*9.85 a o1 = 19 e ho l'ascissa schermo 85.98 = 86 in cui devo rappresentare (x,y);
• in modo analogo trovo l'ordinata schermo.

    Si tratta di un procedimento sostanzialmente simile a quello che si deve fare per tracciare a mano un grafico su carta millimetrata o quadrettata: scegliere la porzione di foglio, scegliere la scala, calcolare delle distanze, ….
    In modo più formale possiamo dire che, per passare dal piano numerico "virtuale" a quello delle coordinate-schermo, operiamo una traslazione (di passi -x1 e -y2), un ribaltamento (verticale, passando da y-y2 a y2-y) e una trasformazione di scala (di fattori RapOr e RapVer).
    In Qbasic esistono le istruzioni VIEW e WINDOW che consentono, rispettivamente, di definire una finestra per le uscite grafiche e di associare ad essa un rettangolo del piano cartesiano, in modo che nelle istruzioni grafiche (LINE, PSET, …) si possano impiegare direttamente le coordinate cartesiane: il programma traduttore automaticamente (con un calcolo simile a quello descritto sopra) opera la trasformazione in coordinate schermo.  Esiste anche l'istruzione VIEW PRINT … TO … che consente di definire una finestra per le uscite alfanumeriche o uscite "testo" (sequenze di lettere, cifre e altri caratteri). Programmi più sofisticati, come il VisualBasic e il RapidQBasic, consentono l'uso di una quantità maggiore di finestre.  Rimandiamo ai relativi help.
    I software "matematici", come Maple, Derive o il programma Poligon (incorporato negli Oggetti Matematici), consentono tutti di descrivere le figure direttamente in coordinate cartesiane; al loro interno sono presenti sottoprogrammi per il cambio di coordinate costituiti da istruzioni simili a quelle del programma descritto sopra.

#4  Paint e Draw
    Le applicazioni per la grafica sono classificabili in due tipi: di tipo paint (dipinto) o bitmap (mappa di bit) e di tipo draw (disegno) o vettoriale.
    Le applicazioni "paint" registrano le immagini pixel per pixel. Se (con opportuni comandi) traccio un rettangolo (o un poligono) e poi un segmento ottenendo una figura simile a quella sotto indicata con (1), questa viene identificata con l'insieme dei pixel colorati in nero: non posso più separare segmento e poligono in quanto questi sono stati "fusi" in un'unica figura; posso - vedi (2) - selezionare con il mouse una parte di questa figura costituita da parti di poligono e di segmento e - vedi (3) - spostarla (traslarla).

    Una applicazione "draw", invece, memorizza il poligono [o un'altra figura] non come insieme di pixel, ma con tre tipi di informazione: l'informazione che si tratta di un poligono [o la categoria di figura], quella costituita dalla sequenza delle coordinate dei suoi vertici [o le informazioni quantitative che ne caratterizzano dimensioni e posizione]; analogamente il segmento viene memorizzato attraverso l'informazione che si tratta di un segmento e le coordinate dei suoi estremi; l'intera figura è memorizzata registrando separatamente le informazioni relative alle due sottofigure. Cliccando sul poligono - vedi (a) - o sul segmento - vedi (b) - si possono edidenziare i punti che caratterizzano le due figure. Volendo - vedi (c) - con il mouse posso posizionare diversamente, l'una rispetto all'altra, le due sottofigure. Agendo sui punti evidenziati, posso anche cambiare forma o orientamento di ciascuna sottofigura.
[ l'aggettivo vettoriale con cui vengono chiamate queste applicazioni deriva dal fatto che un segmento è interpretato non come un insieme di punti ma come se fosse un "vettore" applicato (A,v), che ha certe dimensioni (le componenti del vettore libero v) e una certa posizione (il punto di applicazione A), che posso modificare operando con il mouse ]

    Entrambi i tipi di applicazioni consentono di realizzare, oltre a traslazioni (come visto sopra), altre  trasformazioni geometriche:
selezionata una figura (una parte di piano nelle applicazioni "paint", un oggetto con una certa struttura nelle applicazioni "draw") su di essa o su una sua copia (realizzata con un copia/incolla e l'eventuale scelta se sovrapporre la nuova figura in modo "trasparente" o "opaco") si possono operare trasformazzioni di scala, ribaltamenti, rotazioni, "inclinamenti" lungo la direzione orizzontale o verticale (vedi la nota successiva), …
    Sotto è illustrato come una una figura (A) può essere sottoposta a (B) un ribaltamento rispetto a un asse verticale, (C) una trasformazione di scala (non monometrica), (D) una inclinamento di 45° lungo la direzione orizzontale mediante una applicazione paint: anche lo spessore delle linee viene modificato. Un'applicazione draw, invece, trasformerebbe solo i punti che caratterizzano la figura e, a partire da questi, costruirebbe le linee che costituiscono la figura nel suo nuovo aspetto.

    Molte applicazioni integrano una sottoapplicazione "paint" e una "draw". Vari programmi per l'elaborazione di testi contengono sottoprogrammi grafici di tipo paint o draw. Un'efficiente applicazione draw è incorporata nel gratuito Open Office. Esistono anche applicazioni di geometria dinamica, come il gratuito GeoGebra, che consentono di integrare facilmente modalità di disegno con tecniche algebriche e con tecniche manuali (movimento del mouse)  [clicca su per entrambi i software].

#5 Nota.  Quando, cliccando su un'opportuna icona o operando su un menu a cascata o …, comandiamo l'esecuzione di una trasformazione, l'applicazione la esegue operando sulle coordinate della figura (sulle coordinate-schermo dei pixel che la compongono o sulle coordinate dei punti che la caratterizzano, a seconda dell'applicazione) mediante una opportuna funzione a 2 input e 2 output (ne abbiamo visto alcuni esempi alla voce  trasformazioni geometriche).
    Vediamo meglio che cosa è un inclinamento lungo una direzione, come quello considerato sopra che ha trasformato (A) in (D) o come quello che trasforma il pesce sotto a sinistra nel pesce sotto a destra. Questo tipo di trasformazione è chiamato anche deformazione lineare o, in inglese, shearing, che significa "tosatura": il suo effetto assomiglia a quello prodotto da una macchina tosatrice o tagliaerba: i peli o i fili d'erba vengono inclinati uniformemente lungo la direzione in cui passa la macchina. L'effetto può essere descritto più precisamente come quello che subisce la figura disegnata su un rettangolo di gomma quando questo viene deformato facendolo diventare un parallelogramma di uguale altezza e uguale base, ovvero su un rettangolo costituito da tante striscioline che poi vengono fatte scorrere in modo che le loro estremità rimangano allineate (da ciò si deduce che l'area non viene modificata).

    Quello sopra illustrato è un inclinamento orizzontale di 30° e corrisponde alla funzione (x, y) (x+y·tan(30°), y): la y di ogni punto P della figura rimane immutata mentre la x subisce un incremento proporzionale alla y (x aumenta di y·tan(30°)), la lunghezza del cateto opposto all'angolo di 30° del triangolo rettangolo raffigurato sopra a destra).  In maniera analoga si può realizzare un inclinamento lungo la direzione verticale: si tratterà di una funzione del tipo (x, y) (x, y+x·k) (x non muta e y cresce di una quantità proporzionale a x).

#6  Variabili indiciate
    Il programma in Qbasic seguente è una modifica del programma considerato all'inizio di questa voce; dando in input 4 come "n.lati" e, come "x, y", man mano: 10,10; 30,30; 60,30; 30,60 e 0,0, esso genera la stessa figura generata dal programma iniziale e la riproduce traslata ripetutamente (6 volte) con passo orizzontale 10 e verticale 5; vedi figura sotto a destra.

 
SCREEN 12
INPUT "n.lati"; N
' "dimensiono" x() e y()
DIM x(N), y(N)  
FOR i = 0 TO N
  INPUT "x, y"; x(i), y(i)
NEXT
CLS     'pulisco lo schermo
h=15: k=10
FOR j=0 TO 6
  PSET (x(0)+j*h, y(0)+j*k)
  FOR i = 1 TO N
    LINE -(x(i)+j*h, y(i)+j*k)
  NEXT
NEXT

    Introdotto 4 come N, il programma impiega le variabili x(0), y(0), …, x(4), y(4), che sono una versione per linguaggio di programmazione delle variabili x0, y0, …, x4, y4, cioè di variabili dotate di indici, o variabili indiciate.
    In un linguaggio di programmazione, in cui la scrittura è "a 1 piano", non posso scrivere, per esempio, x e, a un livello più basso, l'indice 0. Quindi l'indice viene messo tra parentesi. Questa scrittura corrisponde all'usuale scrittura degli output di una funzione e, in effetti, la scrittura di x0, x1, … xN può essere pensata come una abbreviazione di x(0), x(1), …,x(N): x(.) è una funzione che all'indice 0 associa il valore x(0), …, all'indice N associa il valore x(N).
    L'istruzione DIM serve per "dichiarare le dimensioni" delle variabili indiciate, cioè quali sono i valori massimi che possono assumere gli indici. In assenza di dichiarazione, in Qbasic una variabile indiciata può essere impiegata solo con indici compresi tra 0 e 10.
    In JavaScript le variabili indiciate vengono dichiarate con istruzioni come var x = new Array(12)  (che dichiara la possibilità di usare x[0], ..., x[12]: in JavaScript l'indice va messo tra parentesi quadre; array è il termine inglese usato per indicare una "tabella").
    In QBasic si possono usare anche variabili a più indici (A(1,3), ...). In JavaScript una variabile a più indici viene realizzata come una variabile indiciata che ha variabili indiciate come valori (A[1][3] è l'elemento di posto 3 di A[1][.]).
    In Poligon si possono usare u[0],…,u[400],…,z[0],…,z[400] e le assegnazioni possono essere effettuate anche nella forma x[]=2,7,5 che equivale alle tre assegnazioni x[0]=2, x[1]=7, x[2]=5. Esistono, poi, specifici comandi per operare con variabili indiciate e rappresentare figure memorizzate con esse. Ad es. la sequenza di figure ottenuta sopra potremmo ottenerla coi comandi:  x[]=10,30,60,30,0   y[]=10,30,30,60,0   2d(x,y,4)   x[]=x[]+15   y[]=y[]+10   2d(x,y,4)   x[]=x[]+15   y[]=y[]+10 … o, direttamente, con un solo opportuno "ciclo". Vedi l'Help.

#7  Sottoprogrammi e file
    Il programma in Qbasic seguente costituisce un'ulteriore modifica (dei programmi precedenti: e ): memorizza due spezzate e le traccia utilizzando un medesimo sottoprogramma SUB (la sequenza di istruzioni delimitate da SUB e END SUB).

SCREEN 12
INPUT "n.lati 1^ figura"; N
DIM x1(N), y1(N)  
FOR i = 1 TO N: INPUT "x, y"; x1(i), y1(i): NEXT
INPUT "n.lati 2^ figura"; M
DIM x2(M), y2(M)  
FOR i = 1 TO M: INPUT "x, y"; x2(i), y2(i): NEXT
CLS : colore = 14
CALL TRACCIA (x1(),y1(),N)    ' o:  TRACCIA x1(),y1(),N
CALL TRACCIA (x2(),y2(),M)


SUB TRACCIA(x(), y(), N): SHARED colore
COLOR colore
PSET (x(0), y(0))
FOR j = 1 TO N
  LINE -(x(j), y(j))
NEXT
END SUB

    L'esecuzione del SUB viene chiamata nel programma principale con CALL o semplicemente usando il nome del SUB. Nella chiamata vengono elencate le variabili (con l'aggiunta di "( )" se sono indiciate) o, più in generale, i termini che nell'esecuzione devono essere impiegati al posto delle corrispondenti variabili elencate nella intestazione del sottoprogramma, cioè tra parentesi a destra della parola chiave SUB.
    Le variabili elencate nell'intestazione del SUB (nel nostro caso x(), y() e N) vengono chiamate parametri formali: non sono "sostanziali" in quanto l'esecuzione viene fatta non con esse, ma di volta in volta con al loro posto i termini elencati nelle varie chiamate, che vengono detti argomenti attuali.  È qualcosa di analogo a quanto accade quando dico che    a2 sta per a·a  o  definisco F: x 3x+1 e poi scrivo 32, w2, f(5), f(z) o f(z-2) per, rispettivamente, 3·3, w·w, 3·5+1, 3z+1 e 3(z-2)+1 : a e x sarebbero i parametri formali.
    La variabile colore, presente nel SUB, mediante il comando SHARED è dichiarata "condivisa" ("shared" in Inglese) col "programma principale"; si dice anche che è una variabile globale.  Nei sottoprogrammi "gosub" tutte le variabili sono globali: il GOSUB si limita a trasferire l'esecuzione al sottoprogramma come fosse un GOTO, il RETURN la riporta al punto della chiamata.
    Invece la variabile  j  del SUB è una variabile locale: se al di fuori del SUB venisse impiegata una variabile con lo stesso nome ( j ) questo uso non interferirebbe con quello nel SUB; è come se fossero due variabili diverse. Se nel SUB al posto di  j  si mettesse ad es.  k  esso si comporterebbe allo stesso modo. Si può anche dire che è una variabile muta: la sua "voce" non è sentita al di fuori del sottoprogramma.  È analogo l'impiego della variabile j per descrivere l'insieme dei multipli di 3 con la notazione {jN : j/3N} (l'insieme dei numeri naturali j tali che la loro divisione per 3 ha come risultato un numero natutale); avremmo potuto descrivere lo stesso insieme con {kN : k/3N} o usando una qualunque altra variabile al posto di k.
    Nelle function di Javascript le variabili diverse dai parametri formali sono interpertate come globali, a meno che non vengano dichiarate all'interno della function con un var; ad esempio l'istruzione "var x;" all'inizio di una function fa sì che x sia intesa locale.

#8   Per memorizzare le coordinate di una figura (o altri tipi di informazioni) in modo da poterle utilizzare anche al di fuori dell'esecuzione di un particolare programma non è sufficiente ricorre alle variabili indiciate: occorre registrale in un file. I linguaggi di programmazione sono dotati di opportune istruzioni per scrivere/leggere file. Ad esempio quella che segue può essere un programma che costruisce il file "fig4.gfu" collocato nel sottodirectory "figure" del directory da cui è stato lanciato il programma; si tratta di un file per Poligon del tipo di quello descritto sopra:

INPUT N        'leggo il numero dei punti e lo metto in N
DIM x(N),y(N)  'definisco 2 variabili indiciate dove mettere le coordinate
FOR i = 1 TO N
  INPUT x(i),y(i)  ' via via leggo e metto in x(),y() le coordinate
NEXT
'costruisco il file, lo chiamo n.1, e lo apro per introdurvi dei dati
OPEN "figure\fig4.gfu" FOR OUTPUT AS #1
PRINT #1, N         'scrivo nel file quantita' di punti e coordinate
FOR i = 1 TO N : PRINT #1, x(i),y(i) : NEXT
CLOSE #1            'chiudo il file

    Rinviamo all'help del Qbasic per altre informazioni

#9   Esempio di programma grafico per Windows. Qui sotto è riprodotto un semplice programma per realizzare figure in RapidQBasic. Viene creata una finestra per Windows (QForm), a cui viene dato nome "Finestra"; all'interno di essa viene creato uno spazio per le immagini (QCanvas) con nome "Foglio"; lo spazio è maggiore della finestra, per cui all'avvio del programma compaiono su di essa due barre di scorrimento per esaminarlo. Nello spazio vengono tracciate le figure descritte nel sottoprogramma Disegna: un'ellisse inscritta nel rettangolo avente (10,10) e (100,100) come vertici opposti, di bordo blu e interno bianco; un segmento rosso da (10,10) a (55,55); un segmento verde da (100,100) a (200,200), che si vede parzialmente (i colori sono nella forma RGB, ossia espressi indicando in 255-esmi le "quantità" di rosso (red), verde (green) e blu (blue) da comporre).

Declare Sub Disegna

Create Finestra as QForm
  width=200 : height=200

  Create Foglio as QCanvas
    width=300 : height=300
    OnPaint = Disegna
  End Create

  ShowModal 
End Create

Sub Disegna
 red=rgb(255,0,0): green=rgb(0,205,0)
 blue=rgb(0,0,255): white=rgb(255,255,255) 
 Foglio.Circle (10,10,100,100,blue,white)
 Foglio.Line (10,10,55,55,red)
 Foglio.Line (100,100,200,200,green)
End Sub
 

Esercizi:  

 altri collegamenti     [nuova pagina]     Considerazioni Didattiche