//Tema d'esame 17.VII.17 #include #include #include //Strutture dati typedef struct { double x; double y; } punto; typedef struct { punto v; punto w; punto z; } tri; // Prototipi double dist(punto* , punto*); //Calcola la distanza fra due punti double diam(tri*); //Calcola il diametro di un triangolo punto centr(tri*); //Calcola il centroide di un triangolo double diammax(int n); /* Calcola il diametro massimo fra i diametri dei triangoli dell'array globale elenco di lunghezza n */ double distmed(int n); /* Calcola la media delle distanze fra i triangoli dell'elenco in ingresso di lunghezza n */ int app(tri *, punto *); // Restituisce 1 se il punto appartiene al triangolo, 0 altrimenti int caricatri(char* nomef, int* n); /* Legge i triangoli dal file nomefile e alloca la memoria necessaria per memorizzare l'elenco, cui puntera' la variabile globale argomento elenco. Il secondo argomento puntera' al numero di triangoli letti da file */ void vis(int n); //Visualizza elenco punto* leggi(void); //Legge un punto da console //Elenco dei triangoli tri *elenco=NULL; int main(int argc, char* argv[]) { if (argc<2) { printf("Mancano argomenti sulla riga di comando.\n"); return -1; } int n; //Numero dei triangoli if (caricatri(argv[1],&n)==-1) { printf("Errore nell'apertura del file %s.\n", argv[1]); return -1; } if (caricatri(argv[1],&n)==-1) { printf("Errore nell'allocazione della memoria.\n"); return -1; } printf("Navi caricate.\n"); vis(n); printf("Diametro massimo delle navi: %g\n", diammax(n)); printf("Distanza media fra le navi: %g\n", distmed(n)); /* Gioco */ int colp[n], r=n, i; //r=navi rimaste punto* p=NULL; //Il punto sparato dall'utente //Inizializza array colpite: colp[i]=1 colpita, colp[i]=0 non colpita for (i=0; i0) { printf("Spara: "); if ( (p=leggi())==NULL ) printf("Formato non valido o errore nell'allocazione della memoria. Riprova.\n"); else { for (i=0;ix)-(q->x))*((p->x)-(q->x)) + ((p->y)-(q->y))*((p->y)-(q->y)) ); } double diam(tri* t) //Calcola il diametro di un triangolo { double l1=dist(&(t->v),&(t->w)), l2=dist(&(t->w),&(t->z)), l3=dist(&(t->z),&(t->v)); if ( (l1 >= l2) && (l1 >= l3) ) return l1; if ( l2 >= l3 ) return l2; return l3; } punto centr(tri* t) //Calcola il centroide di un triangolo { punto c={ ( (t->v).x+(t->w).x+(t->z).x )/3, ( (t->v).y+(t->w).y+(t->z).y )/3 }; return c; } double diammax(int n) /* Calcola il diametro massimo fra i diametri dei triangoli dell'array globale elenco di lunghezza n */ { if (n<=0) //Controllo d'errore sul parametro n return-1; int i; double max = diam(&(elenco[0])); double d; for (i=1; imax) max=d; } return max; } double distmed(int n) /* Calcola la media delle distanze fra i triangoli dell'array globale elenco di lunghezza n */ { if (n<=0) //Controllo d'errore sul parametro n return-1; double tot=0; int i,j; /*Il doppio ciclo esamina tutte le coppie non ordinate (=sottinsiemi di cardinalita' 2) di triangoli dell'array a, ossia le coppie {i,j} con 0<=iv.x, x2=t->w.x, x3=t->z.x; double y1=t->v.y, y2=t->w.y, y3=t->z.y; double a=((y2 - y3)*(p->x - x3) + (x3 - x2)*(p->y - y3)) / ((y2 - y3)*(x1 - x3) + (x3 - x2)*(y1 - y3)); double b=((y3 - y1)*(p->x - x3) + (x1 - x3)*(p->y - y3)) / ((y2 - y3)*(x1 - x3) + (x3 - x2)*(y1 - y3)); if ( (0<=a) && (a<=1) && (0<=b) && (b<=1) && (0<=(1-a-b)) && ((1-a-b)<=1) ) return 1; return 0; } void vis(int n) //Visualizza elenco { if ( (elenco==NULL) || (n<0) ) return; int i; for (i=0; ix=x; p->y=y; return p; }