Esercizio in C sulle funzioni

di il
6 risposte

Esercizio in C sulle funzioni

TESTO:
Quando una particella colpisce un bersaglio, interagisce con una certa probabilità con gli atomi di cui
questo è composto. Per simulare questo fenomeno si possono immaginare gli atomi del bersaglio
come una serie di punti distribuiti a caso su una superficie alle coordinate. Una particella che incide
sul bersaglio alle coordinate (xp,yp) ha una probabilità di 70% di interagire con un atomo che si
trova a una distanza R=0.1 da essa.
Scrivete un programma che simuli l’interazione su un bersaglio di un fascio di N particelle ellittico con il semiasse maggiore A
lungo l’asse X e il semiasse minore B lungo l’asse Y, nel quale sono contenuti M atomi:
1. Scrivere una funzione ellisse di tipo void che generi in modo uniforme le coordinate di un
punto all’interno di un’ellisse i cui semiassi sono passati come argomenti della funzione. A tal fine
generare x tra -A e A e y tra -B e B, accettandole solo se sqrt((x/A)^2 + (y/B)^2) < 1, ritirando ad oltranza altrimenti.
2. Chiedere all’utente di indicare i valori di N, M, A, e B, scegliendo variabili di tipo opportuno,
ed assicurandosi che sia B < A < 10, ed N < M < 10000.
3. Attraverso una funzione atomi, generare le coordinate di M atomi contenuti all’interno
dell’ellisse e memorizzare tali coordinate in un array bidimensionale bersaglio. Chiaramente
in questa funzione dovete fare uso della funzione ellisse implementata in precedenza.
4. Con un ciclo, sempre utilizzando la funzione ellisse , generare le coordinate di N particelle
incidenti all’interno del bersaglio e per ciascuna verificare se esiste almeno un atomo a distanza
R da essa, e tenendo conto della probabilità di 70% di interazione, contare il numero Nint di
particelle del fascio che interagiscono con il bersaglio.
5. Al termine del ciclo, scrivere sullo schermo la frazione (Nint/N) di particelle del fascio che
interagiscono
mio codice:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
void ellisse (double A, double B, double *x, double *y);
void atomi (double A, double B, double vector[][2], int M);
int main () {
    double A, B, R = 0.1;
    int N, M;
    srand(time(NULL));
    
    /* Fa inserire all'utente il valore del semiasse maggiore */
    do {
        printf("Inserire il valore del semiasse maggiore ");
        printf("N.B non deve essere maggiore di 10\n");
        scanf("%lf", &A);
    } while (A > 10);        /* Accetta il dato solo se se A < 10 */
    
    /* Fa inserire all'utente il valore del semiasse minore */
    do {
        printf("Inserire il valore del semiasse minore ");
        printf("N.B non deve essere maggiore del semiasse maggiore\n");
        scanf("%lf", &B);
    } while (B > A);        /* Accetta il dato solo se B < A */
    
    /* Fa inserire all'utente il numero di atomi */
    do {
        printf("Inserire il numero di atomi ");
        printf("N.B non deve essere maggiore di 10000\n");
        scanf("%d", &M);
    } while (M > 10000);         /* Accetta il dato solo se M < 10000 */
    
    /* Fa inserire all'utente il numero di particelle del fascio */
    do {
        printf("Inserire il numero di particelle del fascio ");
        printf("N.B non deve essere maggiore di %d\n", M);
        scanf("%d", &N);
    } while (N > M);             /* Accetta il dato solo se N < M */
    double bersaglio[M][2], x, y;
    int i, j;
     /* Inserisce le posizione degli atomi nell'array bersaglio */
    atomi(A, B, bersaglio, M);
    /* Conta quante sono le particelle che si trovano a distanza <= 0.1 e tiene conto del fatto che solo il 70% di esse interagisce */
    int Nint = 0;
    for (i = 0; i <  N; i++) {
        ellisse (A, B, &x, &y);
        for (j = 0; j < M ; j++) {
            if (pow(x-bersaglio[j][0],2) + pow(y-bersaglio[j][1],2) <= R*R && ((double)rand()/RAND_MAX >= 0.7)) {
                Nint++;
                break;
            }
        }  
    }
    printf("Il numero di particelle che interagiscono e': %d\n",Nint);
    printf("La frazione di particelle del fascio che interagiscono e': %lf\n",(Nint*1.0)/N);
}

void ellisse (double A, double B, double *x, double *y) {
    double a, b;
    do {
        a = -A + (rand()/(double)RAND_MAX)*(2*A);
        b = -B + (rand()/(double)RAND_MAX)*(2*B);
    } while (((a/A)*(a/A) + (b/B)*(b/B)) < 1);
    *x = a;
    *y = b;
}

void atomi (double A, double B, double vector[][2], int M) {
    double x, y;  
    int i;
    for (i = 0; i < M; i++) {
        ellisse (A, B, &x, &y);
        vector[i][0] = x;
        vector[i][1] = y;
    }
}
Vi sembra giusta questa mia interpretazione del punto 4?

6 Risposte

  • Re: Esercizio in C sulle funzioni

    Se i punti devono stare all'interno dell'ellisse, hai fatto lo stesso errore dell'altra volta...
  • Re: Esercizio in C sulle funzioni

    E' vero...
    Per il resto?
  • Re: Esercizio in C sulle funzioni

    1) Devi controllare che gli A, B e N immessi siano > 0, M invece > 1
    2) stai calcolando la probabilità che le particelle interagiscano, quindi la condizione deve essere <= 0.7
    3) pow e sqrt non si devono mai usare quando esiste un'alternativa
  • Re: Esercizio in C sulle funzioni

    Con queste modifiche sembra andare.
    Però ho una domanda, come mai non bisogna usare pow e sqrt quando esiste un'alternativa?
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <math.h>
    void ellisse (double A, double B, double *x, double *y);
    void atomi (double A, double B, double vector[][2], int M);
    int main () {
        double A, B, R = 0.1;
        int N, M;
        srand(time(NULL));
        
        /* Fa inserire all'utente i valori del semiasse maggiore */
        do {
            printf("Inserire il valore del semiasse maggiore ");
            printf("N.B non deve essere maggiore di 10\n");
            scanf("%lf", &A);
        } while (A <= 0 || A > 10);        /* Accetta il dato solo se se A < 10 e A > 0*/
        
        /* Fa inserire all'utente i valori del semiasse minore */
        do {
            printf("Inserire il valore del semiasse minore ");
            printf("N.B non deve essere maggiore del semiasse maggiore\n");
            scanf("%lf", &B);
        } while (B <= 0 || B > A);        /* Accetta il dato solo se B < A e B > 0 */
        
        /* Fa inserire all'utente il numero di atomi */
        do {
            printf("Inserire il numero di atomi ");
            printf("N.B non deve essere maggiore di 10000\n");
            scanf("%d", &M);
        } while (M <= 1 || M > 10000);         /* Accetta il dato solo se M < 10000 e M > 1 */
        
        /* Fa inserire all'utente il numero di particelle del fascio */
        do {
            printf("Inserire il numero di particelle del fascio ");
            printf("N.B non deve essere maggiore di %d\n", M);
            scanf("%d", &N);
        } while (N <= 0 || N > M);             /* Accetta il dato solo se N < M e N > 0 */
        double bersaglio[M][2], x, y;
        int i, j;
         /* Inserisce le posizione degli atomi nell'array bersaglio */
        atomi(A, B, bersaglio, M);
        /* Conta quante sono le particelle che si trovano a distanza <= 0.1 e tiene conto del fatto che solo il 70% di esse interagisce */
        int Nint = 0;
        for (i = 0; i <  N; i++) {
            ellisse (A, B, &x, &y);
            for (j = 0; j < M ; j++) {
                if ((((x-bersaglio[j][0])*(x-bersaglio[j][0]) + (y-bersaglio[j][1])*(y-bersaglio[j][1])) <= R*R) && ((double)rand()/RAND_MAX <= 0.7)) {
                    Nint++;
                    break;
                }
            }  
        }
        printf("Il numero di particelle che interagiscono e': %d\n",Nint);
        printf("La frazione di particelle del fascio che interagiscono e': %lf\n",(Nint*1.0)/N);
    }
    
    void ellisse (double A, double B, double *x, double *y) {
        double a, b;
        do {
            a = -A + (rand()/(double)RAND_MAX)*(2*A);
            b = -B + (rand()/(double)RAND_MAX)*(2*B);
        } while (((a/A)*(a/A) + (b/B)*(b/B)) > 1);
        *x = a;
        *y = b;
    }
    
    void atomi (double A, double B, double vector[][2], int M) {
        double x, y;  
        int i;
        for (i = 0; i < M; i++) {
            ellisse (A, B, &x, &y);
            vector[i][0] = x;
            vector[i][1] = y;
        }
    }
    
  • Re: Esercizio in C sulle funzioni

    come mai non bisogna usare pow e sqrt quando esiste un'alternativa?
    Ah! Ho capito! :-0
  • Re: Esercizio in C sulle funzioni

    Per i tempi di calcolo. Tipicamente quegli N sono molti grandi
Devi accedere o registrarti per scrivere nel forum
6 risposte