L'APPLET DI JAVA



  Rinviando il lettore per ogni approfondimento al sito di Java, ci soffermeremo ad illustrare le istruzioni utilizzate per comporre queste pagine. In particolare faremo ricorso a Java per misurare, on line, le distanze sulle immagini.

  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. Quest'ultimo aspetto avviene 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 e su una coppia di immagini stereometriche.

Il fotopiano


  Premesso che per fotopiano s'intende la fotografia di un oggetto avente una dimensione trascurabile rispetto alle altre due e giacente in un piano parallelo a quello della superficie sensibile, il programma dell'applet, destinato a misurare le distanze tra due punti, deve semplicemente rilevare le coordinate dei due punti, calcolare la distanza in pixel e rapportarla ad una distanza di riferimento, misurata in metri.
  Per utilizzare l'applet è necessario fornire, mediante uno documento HTML, le coordinate, in pixels, di due punti dell'immagine (rivevabili con un qualsiasi programma di fotoritocco) e la distanza reale tra i due punti.
  Lo script del documento HTML è il seguente:

<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 520x314 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.

L'immagine stereofotogrammetrica


  Per questo esempio utilizzeremo due fotogrammi di dimensioni 320x240 pixel ottenuti con una camera digitale, nel rispetto del caso normale. I parametri da fornire all'applet, quindi, saranno: la base, la distanza principale ed i due fotogrammi. Lo script del documento HTML sarà il seguente:

<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.