sito dedicato di Java, mentre ci soffermeremo ad illustrare le istruzioni utilizzate per comporre queste pagine.
Cominciamo col dire che, poiché non facciamo parte della categoria dei fortunati possessori di Workstations Sun (per le quali Java è un liguaggio di sistema), noi comuni mortali, possessori di computers sui quali il linguaggio Java viene emulato, lo utilizzeremo solo in caso di necessità.
Indubbiamente ci farebbe molto piacere presentare delle pagine con le scritte lampeggianti e menu che si aprono al semplice passaggio del cursore, ma, almeno fino ad oggi, il tempo che l'emulatore impiega per leggere il programma è di gran lunga superiore al tempo di caricamento dello stesso. Tutto ciò costringe l'utente ad una lunga attesa, che diventa anche inutile se la memoria RAM è insufficiente o se, in mancanza dell'emulatore, si blocca addirittura il sistema.
Noi faremo ricorso a Java solo per misurare, on line, le distanze sulle immagini.
Al pari del "C", Java può fornire delle comuni applicazioni, ma, in questa sede, sarà utilizzato per realizzare degli applet.
Che cos'è l'applet ?
In parole povere, l'applet è un programma che viene scaricato sulla nostra macchina e continua ad operare anche se ci scolleghiamo dalla rete, ma svanisce appena chiudiamo il nostro browser.
Attenzione, l'applet non è un programma dispettoso, ma lo fa semplicemente per consentirci di utilizzarne l'ultima versione, ogni volta che ci colleghiamo.
Di seguito sono riportati i programmi, molto semplici, di due applet destinati a misurare le distanze su di un fotopiano o su una coppia di immagini stereometriche.
<HTML> <HEAD> <TITLE>esempio di Java</TITLE> </HEAD> <BODY> <P ALIGN=CENTER> <applet code=fotopiano width=400 height=420> <param name=fotografia Value=immagini/cattedrale.gif> <param name=Xpa Value=203> <param name=Ypa Value=14> <param name=Xpb Value=203> <param name=Ypb Value=339> <param name=Dmetri Value=28> </applet> </BODY> </HTML> |
Non è difficile notare che il documento carica prima l'applet di nome fotopiano (code=fotopiano) e gli assegna un'area di 400 x 420 pixels (width=400 height=420), quindi assegna i valori ai parametri corrispondenti all'immagine da caricare <param name=fotografia Value=immagini/cattedrale.gif>, alle coordinate del punto A(203,14), a quelle del punto B(203,339) e alla distanza (Dmetri=28). Da non dimenticare, infine, che l'origine del sistema di riferimento X,Y delle coordinate (in pixels) trovasi in alto a sinistra del fotogramma.
Lo script del programma nel linguaggio Java, che, una volta compilato, fornisce l'applet, è il seguente:
import java.awt.*; import java.applet.*; public class fotopiano extends Applet{ Image foto; String sXa, sYa, sXb, sYb, sMetri; int xUp, yUp, xDown, yDown,Xa, Ya, Xb, Yb, XA, YA, XB, YB; double Tara, coeff, Dist,Distanza,Metri; public void init(){ sXa = getParameter("Xpa"); Xa = Integer.valueOf(sXa).intValue(); sYa = getParameter("Ypa"); Ya = Integer.valueOf(sYa).intValue(); sXb = getParameter("Xpb"); Xb = Integer.valueOf(sXb).intValue(); sYb = getParameter("Ypb"); Yb = Integer.valueOf(sYb).intValue(); sMetri = getParameter("Dmetri"); Metri = Double.valueOf(sMetri).doubleValue(); foto = getImage(getDocumentBase(), getParameter("fotografia")); } public boolean mouseDown(Event evt, int x, int y) { xDown = x; yDown = y; return true; } public boolean mouseUp(Event evt, int x, int y){ xUp = x; yUp = y; Dist = Math.sqrt((xUp - xDown)*(xUp - xDown) + (yUp - yDown)*(yUp - yDown)); Tara = Math.sqrt((Xa - Xb)*(Xa - Xb) + (Ya - Yb)*(Ya - Yb)); Distanza = (Math.round(Dist * Metri *100/Tara))/100 ; repaint(); return true; } public void paint(Graphics g) { g.drawImage(foto,0,0,this); g.setColor(Color.yellow); g.fillRect(0,401,400,20); g.setColor(Color.black); Font f = new Font("TimesRoman", Font.BOLD, 13); g.setFont(f); g.drawString("Ultima misura: m. " + Distanza, 10,415); } } |
La parte di colore magenta serve a richiamare le risorse (classi) di Java (
import java.awt.*; import java.applet.*;) e a dichiarare le variabili (
Image, String, int, double).
La parte in rosso trasforma i parametri in valori numerici (sXa = getParameter("Xpa"); Xa = Integer.valueOf(sXa).intValue() ecc.) o in immagine (foto = getImage(getDocumentBase(), getParameter("fotografia"))).
La parte in blu effettua il rilievo vero e proprio. Quando si abbassa il tasto del mouse (evento mouseDown) in un punto, ne vengono rilevate le coordinate (xDown, yDown), mentre quando si alza il tasto del mouse in un altro punto (evento mouseUp) vengono rilevate le coordinate (xUp, yUp), calcolata la distanza in pixels dal precedente punto (Math.sqrt((xUp - xDown)*(xUp - xDown) + (yUp - yDown)*(yUp - yDown))), la quale, successivamente, con una semplice proporzione, viene trasformata in metri sulla base della distanza nota ((Math.round(Dist * Metri *100/Tara))/100).
La parte in verde, infine provvede a disegnare sullo schermo:
- la fotografia (foto), con il vertice superiore sinistro posto nel punto (0,0) e con le dimensioni reali 400x400 px (this) (g.drawImage(foto,0,0,this));
- sotto la fotografia, un rettangolo giallo, largo quanto il fotogramma ed alto 20 pixel (g.fillRect(0,401,400,20));
- sul rettangolo una scritta in nero, con carattere TimesRoman grassetto e altezza 13 pixel ( Font ("TimesRoman", Font.BOLD, 13)) la frase "ultima misura: m. " seguita dalla distanza calcolata in metri, a partire da punto di coordinate (10,412) (g.drawString("Ultima misura: m. " + Distanza, 10,415)).
Se proviamo a caricare l'applet, per conoscere la distanza tra due punti giacenti sulla facciata della cattedrale di Bari, sarà sufficiente abbassare il tasto del mouse quanto il cursore si trova sul primo punto, spostare il cursore sul secondo punto e rilasciare il tasto. La distanza comparirà sulla striscia gialla.
Il limite del programma sopra esposto è dato dalle limitate dimensioni del fotogramma, che deve essere visualizzato integralmente sullo schermo. Se si desidera caricare la stessa fotografia, con dimensioni superiori a quelle dello schermo, dovremo poterla spostare e ciò comporta nuove istruzioni e quindi una nuova programmazione.
Sulla copertina di queste pagine, facendo click sulla fotografia del centro storico di Bari, è possibile richiamare un esempio più elaborato, in quanto è dotato di un pulsante per richiamare le istruzioni in linea, mentre l'evento "mouseDown" viene sfruttato per mostrare le chiese esistenti nei punti gialli cliccabili.
<HTML> <HEAD> <TITLE>esempio di Java</TITLE> </HEAD> <BODY> <P ALIGN=CENTER> <applet code="StereoFot" width=650 height=260> <param name=destra Value=immagini/destra.jpg> <name=sinistra Value=immagini/sinistra.jpg> <name=C Value=391.56> <name=b Value=60> </applet> </BODY> </HTML> |
È facile notare che questo documento richiama l'applet di nome "StereoFot" (cui assegna uno spazio di 650x260 pixel), e fornisce i parametri relativi ai fotogrammi (destro e sinistro), alla base (60 cm.) e alla distanza principale ricavata in pixel (391.56).
Lo script del programma nel linguaggio Java, che, una volta compilato, fornisce l'applet, è il seguente:
import java.awt.*; import java.applet.*; import java.util.*; public class fotopiano extends Applet{ Image Destra, Sinistra; String sC,sB; int b; double C,X1S, Z1S, X1D, Z1D, X2S, Z2S, X2D, Z2D, parA, parB, X1, Y1, Z1, X2, Y2, Z2, Dist; public void init(){ Sinistra = getImage(getDocumentBase(), getParameter("sinistra")); Destra = getImage(getDocumentBase(), getParameter("destra")); sC = getParameter("C"); C = Double.valueOf(sC).doubleValue(); sB = getParameter("b"); b = Integer.valueOf(sB).intValue(); } public boolean mouseDown (java.awt.Event evt,int x, int y) { if ( x < 320 ){ X1D = x - 160; Z1D = 120 - y; }else { X1S = x - 490; Z1S = 120 - y; } return true; } public boolean mouseUp (java.awt.Event evt,int x, int y) { if ( x < 320 ) { X2D = x - 160; Z2D = 120 - y; }else{ X2S = x - 490; Z2S = 120 - y; parA = X1S - X1D; parB = X2S - X2D ; X1 = b * X1S / parA; Y1 = b * (C/100) / parA; Z1 = b * Z1S/ parA; X2 = b * X2S / parB; Y2 = b * (C/100) / parB; Z2 = b * Z2S / parB; Dist = (X2 - X1)*(X2 - X1) + (Y2 - Y1)*(Y2 - Y1) + (Z2 - Z1)*(Z2 - Z1); Dist = Math.sqrt(Dist); Dist = Math.round(Dist); repaint(); } return true; } public void paint(Graphics g) { g.drawImage(Sinistra,0,0,this); g.drawImage(Destra,330,0,this); g.setColor(Color.yellow); g.fillRect(0,240,650,20); g.setColor(Color.black); Font f = new Font("TimesRoman", Font.BOLD, 13); g.setFont(f); g.drawString(" Ultima misura: d = cm. " + Dist, 10,255); } } |
Analogamente a quanto si è detto per il programma destinato a rilevare le misure sul fotopiano, c'è da dire che:
- la parte scritta in color magenta provvede a richiamare le risorse di Java e a dichiarare le variabili;
- la parte scritta in rosso, trasforma i parametri in immagini o in valori numerici;
- la parte scritta in azzurro programma i calcoli da effettuarsi al verificarsi degli eventi mouseDown (tasto del mouse abbassato) e mouseUp (tasto del mouse alzato);
- la parte scritta in verde disegna i due fotogrammi e trascrive il valore numerico della distanza.
Da tener presente che le immagini (di dimensioni 320x240 pixel) sono messe affiancate e con il vertice superiore sinistro posizionato rispettivamente nei punti (0,0) e (320,0), di conseguenza l'origine dei due sistemi di riferimento si trova, rispettivamente, nei punti (160,120) e (490,120).
Al verificarsi dei due eventi, il programma distingue i casi in cui la x sia inferiore o superiore a 320, cioè rileva se l'evento si è verificasto sul primo o sul secondo fotogramma.
Per utilizzare il programma, noi dovremo:
- individuare i due punti su entrambi i fotogrammi;
- abbassare il tasto del mouse sul primo punto del fotogramma di sinistra e sollevarlo in corrispondenza del secondo punto dello stesso fotogramma;
- ripetere l'operazione su secondo fotogramma.
Al verificarsi dell'evento mouseUp sul secondo fotogramma, il programma calcola la distanza tra i due punti A(X1,Y1,Z1) e B(X2,Y2,Z2), le cui coordinate sono state ricavate applicando le tre formule del caso normale.
Analogamente a quanto si è detto per l'applet relativo al fotopiano, il programma "StereoFot", nella versione finale, è stato semplicemente integrato con altre istruzioni che consentono di:
- caricare immagini di dimensioni 800x600 pixel e farle scorrere in finenestre di 300x300 pixel;
- utilizzare i tasti (oltre che il mouse) per lo spostamento delle immagini;
- visualizzare uno dei due fotogrammi per individuare la zona interessata dal rilievo;
- registrare, oltre alla distanza tra due punti, le coordinate dei singoli punti rilevati in modo da poterli rappresentare graficamente nei tre piani di riferimento xy,xz e yz;
Per rendersi conto della precisione conseguibile con il programma, è possibile utilizzare una coppia di fotogrammi di un campo di prova.