Grafico con distanze

Siano dati un insieme di punti. Per ogni coppia di punti nell'insieme, si disegni la linea che li unisce. Inoltre, si disegni anche un piccolo quadrato nel punto a metà di questo segmento, e vicino si scriva la distanza fra i due punti.

Il primo problema da risolvere è trovare il modo di rappresentare un insieme di punti. Dal momento che ogni punto è rappresentato da due interi (le sue coordinate) quello che serve è un metodo per rappresentare due insiemi di interi. Un modo che conosciamo è usando i vettori. Possiamo per esempio usare due vettori di interi x e y, che contengono ciascuno una delle coordinate di tutti i punti. Per esempio, le coordinate del primo punto saranno date da x[0] e y[0], le coordinate del secondo punto si possono memorizzare in x[1] e y[1], ecc. Chiaramente, il numero di elementi dei due vettori deve essere lo stesso. Inoltre, il numero di punti che si può rappresentare in questo modo coincide con il numero di elementi dei due vettori, e quindi vale x.length che è uguale a y.length.

Vadiamo ora il problema del tracciamento delle linee. Quello che ci serve è un metodo per tracciare un segmento fra due elementi qualsiasi del vettore. Quindi, deve esistere per esempio una linea fra il terzo e il nono elemento, una fra il settimo e il quinto, ecc.

La soluzione del problema può non essere immediatamente chiara. Proviamo a riformulare il problema in altro modo. Vogliamo un segmento fra il primo punto e il secondo, fra il primo e il terzo ecc. Quindi, se consideriamo solo le linee fra il primo elemento e tutti gli altri, allora il seguente codice è valido:

  for(p=0; p<=x.length-1; p=p+1) {
    g.drawLine(x[0],y[0],x[p],y[p]);
  }

Questo frammento di programma disegna una linea fra il primo punto e tutti gli altri: infatti, il ciclo viene eseguito per ogni indice del vettore tranne il primo, ossia x[p] e y[p] sono di volta in volta tutti gli elementi del vettore tranne il primo. Si noti che in questo caso viene anche fatta una linea fra il primo punto e se stesso (questo problema viene considerato più avanti).

Ora, proviamo a pensare cosa deve succedere quando si deve tracciare una linea tra il secondo punto e tutti gli altri. Il programma che fa questo è molto simile al precedente:

  for(p=0; p<=x.length-1; p=p+1) {
    g.drawLine(x[1],y[1],x[p],y[p]);
  }

Per il terzo punto abbiamo:

  for(p=0; p<=x.length-1; p=p+1) {
    g.drawLine(x[2],y[2],x[p],y[p]);
  }
A questo punto è chiaro che occorre un ciclo for. Infatti, sto ripetendo sempre le stesse istruzioni, una volta con x[0],y[0], una volta con x[1],y[1], ecc. Quindi, usiamo una variabile t che parte da 0 a ci fa arrivare all'ultimo punto (quindi si arriva a x.length. Ad ogni iterazione, consideriamo il punto che ha coordinate x[t],y[t] e tracciamo tutte le linee fra questo punto e ogni altro punto. Quindi, a ogni passo va eseguito il ciclo di sopra, per cui abbiamo due cicli for l'uno dentro l'altro:

    for(t=0; t<=x.length-1; t=t+1) {
      for(p=0; p<=x.length-1; p=p+1) {
        g.drawLine(x[t],y[t],x[p],y[p]);
      }
    }

Se vogliamo evitare il disegno della linea fra il punto e se stesso, possiamo aggiungere un controllo: se t==p allora sto considerando lo stesso punto, per cui non è necessario fare la linea. Quello che si ottiene è:

    for(t=0; t<=x.length-1; t=t+1) {
      for(p=0; p<=x.length-1; p=p+1) {
        if(t!=p) {
          g.drawLine(x[t],y[t],x[p],y[p]);
        }
      }
    }
A questo punto, possiamo risolvere il problema di trovare le coordinate del punto a metà del segmente, e il valore della distanza. Il punto a metà si ottiene semplicemente facendo la media delle coordinate x e delle coordinate y dei due punti estremi del segmento. La distanza si trova usando il teorema di Pitagora. Entrambe queste cose vanno fatte per ogni coppia di punti, per cui le istruzioni necessarie vanno messe subito dopo la drawLine, visto che questa istruzione viene effettivamente eseguita per ogni coppia di punti.

Il programma completo GraficoDistanze.java segue.

/*
  Grafico con distanze
*/

import java.awt.*;

public class GraficoDistanze extends java.applet.Applet {
  public void paint(Graphics g) {
    int x[]={100, 200, 300, 220};
    int y[]={400, 100, 220, 190};
    int p, t;
    int xm, ym;
    double d;

    for(t=0; t<=x.length-1; t=t+1) {
      for(p=0; p<=x.length-1; p=p+1) {
        if(t!=p) {
          g.drawLine(x[t],y[t],x[p],y[p]);	// disegna la linea

          xm=(x[t]+x[p])/2;			// punto intermedio
          ym=(y[t]+y[p])/2;

          g.drawRect(xm-2,ym-2,4,4);		// quadratino al centro

						// calcola la distanza
          d=Math.sqrt((x[t]-x[p])*(x[t]-x[p])+(y[t]-y[p])*(y[t]-y[p]));

          g.drawString(""+d,xm+2,ym+2);		// stampa la distanza
        }
      }
    }
  }
}

Usando i valori messi nel codice come coordinate dei punti, si ottiene il seguente risultato.