domenica 24 febbraio 2008

sabato 23 febbraio 2008

Quando colpirà la freccia il bersaglio?

/*
* Descrizione : Distanza di caduta ed tempo di volo
* di un freccia lanciata contro un bersaglio in aria.
* Attrito viscoso.
*
* Input : modulo velocita' iniziale
* angolo di lancio in gradi
* coefficiente di attrito
* distanza e dimensioni del bersaglio
*
* Output : Scrive sul file traiettoria.dat t, x(t) e y(t) della traiettoria
* della freccia;
* Stampa sullo standard output:
* (a) la quota massima y_max nonche' t_max e x_max ad essa corrispondenti
* (b) il tempo di impatto sul bersaglio calcolato con il metodo della bisezione
* (c) l'intervallo dei valori della velocita' iniziale per cui il bersaglio
* viene colpito.
*/
#include
#include
#include

/* Macro */

#define ACC_G 9.81 /* acc. gravita' in m/s^2 */
#define GR_RD 0.0174532925199433 /* fattore di conversione gradi -> rad */
#define DELTA_T 0.001 /* risoluzione temporale traiettoria */
#define T_2 100.0 /* tempo iniziale t_2 per la bisezione */
#define SIZE 10000 /* dimensione massima vettori per la traiettoria */
#define GAMMA 0.5 /* coefficiente di attrito / massa */
#define L 26.0 /* dimensione del bersaglio */

/* Prototipi delle funzioni */

double Xt(double time, double V[2]);
double Yt(double time, double V[2]);
double FindImpact(double t_1, double t_2, double V[2]);

/* Dichiarazione stream */

FILE *fp_out;

int main(void)
{
register int i;
int N_dati;
double h = 2.0; /* altezza centro del bersaglio */
double r = 0.5; /* raggio del bersaglio */
double v_0=24.8, alpha = 45.0; /* velocita iniziale */
double t_1, t_2, t_star;
double t_max, x_max, y_max;
double x_coord[SIZE];
double y_coord[SIZE];
double V[2];
/* char line[41];*/

/* Modulo velocita', angolo di lancio e attrito */
/*printf("\n");
printf("Modulo velocita' (m/s): ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%lf", &v_0);*/

/* printf("Inserisci l'angolo (gradi) : ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%lf", &alpha);*/

/* Componenti velocita' */
alpha *= GR_RD; /* Gradi -> Radianti */
V[0] = v_0 * cos(alpha);
V[1] = v_0 * sin(alpha);

if (V[1] <= 0) {
printf("\n Lancio verso il basso!\n\n");
return 1;
}


/***************************************************************************
* Stampa su file dei dati t. x(t), y(t) della triettoria della freccia
* con risoluzione temporale DELTA_T. Riempimento dei vettori x_coord e y_coord
***************************************************************************/

if(!(fp_out=fopen("traiettoria.dat", "w"))){
fprintf(stderr,"il file da aprire non esiste nella destinazione specificata\n");
exit(1);
}

i=0;
while(1) {
if(Xt(DELTA_T*i, V) < L) {
fprintf(fp_out,"%f %f %f\n",DELTA_T*i, Xt(DELTA_T*i, V),Yt(DELTA_T*i, V));
/* riempimento dei vettori con i dati sulla triettoria */
x_coord[i]=Xt(DELTA_T*i, V);
y_coord[i]=Yt(DELTA_T*i, V);
}
else break;
++i;
}

N_dati = i; /* numero di punti della traiettoria */

fclose(fp_out);

/***************************************************************************
* Determinazione dell' intervallo iniziale [t_1, t_2] per la bisezione:
* t_1 < t^* < t_2
***************************************************************************/

/* Sappiamo che al tempo t=0 x(0) - L e' negativo. Dobbiamo dunque identificare un tempo
in cui x(t_2)- L sia positivo. Si fissa un t_2 iniziale pari ad un valore scelto
arbitrariamente T_2. Se verifica x(t_2) - L e' ancora minore di zero si raddoppia
t_2 finche' non sia verificata la condizione x(t_2) - L > 0. */

t_2 = T_2;
while ( (Xt(t_2, V) - L) < 0.0 ) t_2 *= 2.0;

/* Una volta identificato t_2 si cerca di fissare un tempo t_1 per cui
x(t_1) - L < 0. A tal fine si fissa progressivamente t_1 alla meta' di t_2.
Finche' x(t_1) -L e' ancora positivo si ridefinisce t_2 = t_1 e si dimezza t_1.
Alla fine della procedura si hanno due valori t_1 e t_2 tali che
* t_1 < t^* < t_2 */

t_1 = 0.5 * t_2;
while ( (Xt(t_1, V) - L) > 0.0 ) {
t_2 = t_1;
t_1 = 0.5 * t_2;
}

/***************************************************************************
* Determinazione del tempo di impatto: t^*: x(t^*) - L = 0
* con t_1 < t^* < t_2. I dati sono forniti in maniera tale che
* la freccia raggiunga il bersaglio. In generale si dovrebbe verificare
* che il tempo di impatto corrisponda a delle coordinate x(t^*) e y(t^*)
* all'interno del bersaglio. L'algoritmo e' contenuto nella funzione
* FindImpact.
***************************************************************************/

t_star = FindImpact(t_1, t_2, V);

printf("\n************************************************************************\n\n");
if(Yt(t_star, V) <= h +r && Yt(t_star, V) >= h-r )
printf("La freccia ha colpito il bersaglio alla quota di %.4f metri\n\n", Yt(t_star, V));
printf("Tempo di volo: %.8f secondi \n\n", t_star);
printf("************************************************************************\n");


/***************************************************************************
* Determinazione dell'intervallo di velocita' per cui la freccia raggiunge il
* bersaglio.
***************************************************************************/

return 0;
}
/* Fine main */

/* Funzioni */

/* Funzione coordinata x */
double Xt(double t, double V[2])
{
double coef;
coef = V[0] / GAMMA;

return coef * (1.0 - exp(-GAMMA * t));
}

/* Funzione coordinata y */
double Yt(double t, double V[2])
{
double coef;
double y;

coef = 1.0 / GAMMA;
y = coef * (1.0 - exp(-GAMMA *t)) * (V[1]+ ACC_G / GAMMA) - ACC_G / GAMMA * t;
return y;
}



/* Funzione che calcola il tempo di impatto
* FindImpact()
*
* tempo di impatto con il metodo della bisezione
*
* MAX_BIS: Numero massimo bisezioni
* EPSILON: Precisione richiesta
*/
#define MAX_BIS 40
#define EPSILON (1.e-8)
double FindImpact(double t_1, double t_2, double V[2])
{
int i;
double t_root, t_mid;
double diff_mid, dt;

dt = t_2 - t_1; /* intervallo iniziale */
/* t_root = t_2; */ /* assunzione iniziale */

for (i = 0; i < MAX_BIS; ++i) {
dt *= 0.5;
t_mid = t_2 - dt;
diff_mid = Xt(t_mid, V)-L;
if (diff_mid >= 0.0)
t_2 = t_mid;
else
t_1 = t_mid;


if (dt < EPSILON || diff_mid == 0.00) return (t_1+t_2)*0.5;
}

printf("\n Error!!! Precisione richiesta eccessiva \n");
exit (1);
}
#undef MAX_BIS
#undef EPSILON

Statistiche....passo dopo passo...

/*
* Descrizione : Programma che acquisisce una sequenza di numeri casuali
* da un file e scrive su due file l'istogramma in frequenza
* dei numeri stessi nonche' la loro sequenza ordinata in maniera
* decrescente.
*
* Input : dati_in.dat
*
* Output : histo_freq.dat, sort.dat
*
*/

#include
#include
#include

#define N 15000 /* numero max di dati: determinato da shell col comando "wc -l dati_in.dat" */
#define MAX_BIN 1000 /* numero max di bin */

int main(void) {

register int i,j;
int numero_dati; /* numero effettivo di dati letti */
char linea[128]; /* usata da fgets */
double tmp;
double max, min, media, media2, dev_std;
int n_bin_freq; /* numero di bin effettivi usati per l'istogramma */
double dx; /* larghezza bin */
double histo_freq[MAX_BIN];
double Dati[N]; /* dati da trattare */

FILE *fp_in, *fp_freq, *fp_sort; /* dichiarazione degli streams di input/output */

/* inizializzazione degli stream mediante associazione con un file */

if(!(fp_in = fopen("dati_in.dat", "r"))) {
fprintf(stderr,"Errore nella apertura input file di dati\n");
/* Messaggio di errore in accesso lettura (il file non esiste) */
exit(1);
}
if(!(fp_freq = fopen("histo_freq.dat", "w"))) {
fprintf(stderr,"Errore nella apertura file di output 1\n");
/* Messaggio di errore in accesso scrittura */
exit(1);
}
if(!(fp_sort = fopen("sort.dat", "w"))) {
fprintf(stderr,"Errore nella apertura file di output 2\n");
/* Messaggio di errore in accesso scrittura */
exit(1);
}


/********************************************************/
/* Lettura dati e immagazzinamento nel vettore Dati */

i=j=0;
while(1) { /* ciclo infinito da terminare con break */
++j; /* conteggio numero di linee lette */
fgets(linea, 128, fp_in);
if(feof(fp_in)) break;
/* interruzione del ciclo quando si e' raggiunta la fine del file */
if(sscanf(linea, "%lf", &Dati[i])==1) ++i;
/* i conta il numero di dati letti, saltando le linee vuote */
else printf("Attenzione: dato sospetto alla linea %d\n", j);
}

numero_dati = i; /* numero effettivo di dati letti */
printf("Numero totale di dati letti: %u\n", numero_dati);
/********************************************************/


/********************************************************/
/* determina max, min, media e deviazione standard */

media = max = min = Dati[0]; /* inizializzazione con il primo dato */
media2 = Dati[0] * Dati[0]; /* inizializzazione con il primo dato */
for(i=1;imax) max=tmp; /* determinazione del massimo */
if(tmp < min="tmp;"> */
media2 /= numero_dati; /* calcolo della media dei quadrati */
dev_std = sqrt(media2 - media*media); /* calcolo della deviazione standard sqrt( - ^2) */

printf("Media: %f Dev.Std.: %f Max: %f Min: %f\n",
media, dev_std, max, min); /* stampa dei risultati */

/********************************************************/


/********************************************************/
/* istogramma */
/* Lettura numero di bin dall'esterno */

do {
printf("Scegli il numero dei bin per l'istogramma in frequenza (<= %d):", MAX_BIN); fgets(linea, sizeof(linea), stdin); /* scelta del numero di bin da usare per l'istogramma */ sscanf(linea, "%d", &n_bin_freq); } while(n_bin_freq <1> MAX_BIN);

/* Inizializzazione istogrammi */

dx = 1.0001*(max - min) / n_bin_freq; /* Larghezza bin */
for (i = 0; i < x =" min" x =" max." x =" max" i="0;" normalizzazione="" con="" il="" numero="" dei="" dati="" i="0;">< i="0;" f="" n="" stampa="" risultati="" su="" due="" colonne="" che="" contengono="" la="" coordinata="" centro="" del="" bin="" dx="" il="" valore="" di="" ordinamento="" decrescente="" dei="" dati="" algoritmo="" for="" i="1;">< tmp =" Dati[i];" j =" i-1;">=0 && tmp>Dati[j]) {
Dati[j+1] = Dati[j];
--j;
}
Dati[j+1]=tmp;
}
/* scrittura dei dati ordinati sul file sort.dat */

for(i=0; i
fprintf(fp_sort, "%f\n",Dati[i]);
fclose(fp_sort);

/********************************************************/


return 0;
}

Da decimale a binario....

/* Questo programma determina la rappresentazione in complemento a due di un numero decimale di tipo signed con un numero di bits fissato*/

#include
#include

int main(void) {

int numero;
int i, n_bits,n_base=2, bit_segno=0,n_max;
char nome[3];

printf("Inserisci il numero decimale di tipo:\n");
scanf("%d",&numero);

/* printf("Inserisci la base della rappresentazione (2 per binaria, 3 per ternaria):\n");
scanf("%d",&n_base);

if (n_base == 2) sprintf(nome,"%s","b");;
if (n_base == 3) sprintf(nome,"%s","tr");*/


printf("Inserisci il numero di bits da utilizzare:\n");
scanf("%d",&n_bits);

/* range = -2^(n_bits-1), ..., 2^(n_bits-1) -1 */

n_max = pow(n_base,n_bits-1)-1;
printf("%d\n",n_max);
if ((numero < -n_max+1) || (numero > n_max)) {
printf("Non ci sono abbastanza bits!\n");
return 1;
}

printf("La rappresentazione binaria del numero %d e': ",numero);

if (numero < 0) {
numero += pow(2,n_bits);
bit_segno = 1;
}


for (i=-1; i < n_bits; i++)
printf(" ");

for (i=1; i < n_bits; i++) {
printf("%d\b\b",(numero % n_base));
numero /= n_base;
}

printf("\b%d",bit_segno);

printf("\n");
return 0;

}

Proprietà statistiche di una serie di lanci di dadi!

/*Proprieta' statistiche di una sequenza di lanci di dadi */
#include
#include
#include

int main(void) {
int i, N_lanci=1000,max=3,min=18,a,b,c,sum=0,sum_tot=0;
int hist[19];
double med=0.;


for(i = 0; i < 19; ++i) hist[i]=0;

for(i = 0; i < N_lanci; ++i){
a = 1+((double) rand () /( RAND_MAX + 1.))*6;
b = 1+((double) rand () /( RAND_MAX + 1.))*6;
c = 1+((double) rand () /( RAND_MAX + 1.))*6;

sum = a + b + c ;
sum_tot += sum;
if (sum > max ) max = sum;
if (sum < min ) min = sum;
hist[sum] +=1;
}

med = sum_tot / 1000.;
printf("media di %d lanci di 3 dadi= %f\n",N_lanci,med);
printf("massimo valore su tutti i lanci di 3 dadi: %d\n",max);
printf("minimo valore su tutti i lanci di 3 dadi: %d\n",min);
printf("*** Istogramma\n");
printf("Valore\tNumero di occorrenze\n");
for (i=0; i<19; i++){
if (hist[i] != 0) printf( "%d\t%d\n",i,hist[i] );
}
return 0;
}

Ho aperto questo blog con l'intento di condividere...

Ho aperto questo blog con l'intento di condividere basi, regole e segreti del linguaggio di programmazione C.
Qui di seguito posterò di tanto in tanto tutto quello che sto imparando con questo affascinante linguaggio, con la speranza di suscitare in voi curiosità e avere molte molte critiche e consigli...;)