Anche se non specificato nel testo, ma come spiegato durante il compito, per rettangolo con diagonale (A,B)-(C,D) si intende il rettangolo cone lati paralleli agli assi cartesiani e con angolo inferiore sinistro il punto (A,B) e con angolo superiore destro il punto (C,D).
Per risolvere questo esercizio si può utilizzare il seguente algoritmo:
Questo è un programma funzionante che realizza l'algoritmo sopra descritto:
#include <stdlib.h>
#include <math.h>
#define N 500
/*
Definizione di rndm(), che restituisce un numero casuale
uniformemente distribuito tra 0 ed 1.
*/
double rndm() {
return (double)rand()/(double)RAND_MAX;
}
int main() {
/* Dichiarazione delle variabili,
i valori di A, B, C, D sono solo esemplificativi. */
double A=0, B=0., C=10., D=5.;
double raggio, xmin, xmax, ymin, ymax, dist;
double x[N], y[N];
int i, j, contatore=0;
/* Inizializzazione della zona in cui devono essere contenuti
i centri delle circonferenze. */
if ( (C-A) > (D-B) ) raggio=(D-B)/100.;
else raggio=(C-A)/100.;
xmin = A+raggio;
xmax = C-raggio;
ymin = B+raggio;
ymax = D-raggio;
/* Generazione dei centri delle circonferenze. */
for ( i=0; i<N; i++) {
x[i] = xmin+rndm()*(xmax-xmin);
y[i] = ymin+rndm()*(ymax-ymin);
}
/* per ogni circonferenza si controlla se questa non ne interseca
nessun altra. Se una circonferenza non ha intersezioni, alla fine
del ciclo interno j vale N.
*/
for ( i=0; i<N; i++) {
for (j=0; j<N; j++) {
if (j!=i) {
dist = sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) );
if ( dist < 2.*raggio ) break;
}
}
if (j==N) contatore++;
}
/* Stampa il risultato ed esce dal programma. */
printf("Trovate %d circonferenze che non si intersecato.\n",contatore);
return 0;
}
Siccome sono metodi molto diffusi di fare la stessa cosa, ecco alcune possibili alternative al codice appena presentato.
Per i virtuosi del C le istruzioni:
if ( (C-A) > (D-B) ) raggio=(D-B)/100.; else raggio=(C-A)/100.;possono essere sostituite dalla molto più compatta, ma criptica:
raggio = ( (C-A)>(D-B)?(D-B):(C-A) )/100.;
Invece di fare il break del ciclo su j, si può memorizzare in una variabile temporanea la minima distanza della circonferenza in questione tra tutte le altre e confrontarla con 2R alla fine del ciclo:
distmin = 100.*raggio;
for (j=0; j<N; j++) {
if (j!=i) {
dist = sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) );
if ( dist < distmin ) distmin=dist;
}
}
if (distmin>2.*raggio) contatore++;