Propagation d'ondes interface 2D, langage C

Voir le sujet précédent Voir le sujet suivant Aller en bas

Propagation d'ondes interface 2D, langage C

Message par Stef le Dim 18 Jan - 6:16

Bonjour,


Code:
/****************************************************************************/
/*
   PAR : Stéphane
   
   OBJET DU PROGRAMME : représentation de la propagation d'ondes sur une
   interface 2D.

   DATE :décembre 2008.


*/
/****************************************************************************/
#include stdlib.h
#include stdio.h
#include math.h
#include SDL/SDL.h



#define NOMBRE_SEGMENT      200
#define LARGEUR_SEGMENT    5
#define HAUTEUR_NULL        100
#define HAUTEUR_EAU        50
#define ANTI_DEBORDEMENT    1000
#define FROTTEMENT          0.01
#define LARGEUR_ONDE        20
#define COURBURE_POUSSE    65
#define PROFONDEUR_ONDE    30
#define TEMPS_PAUSE        30 /* en ms */
#define TEST_SEGMENT        300

 /* création du type Segment, qui défini la
nature d'une "colonne d'eau" en terme de hauteur, vitesse et accélération*/
typedef struct
{
    double hauteur;
    double vitesse;
    double acceleration;
}Segment;


/****************************************************************************/
/*                  PROTOTYPES DE FONCTIONS                         */
/****************************************************************************/
void calcul_acceleration(Segment rectangle[]);
void calcul_vitesse(Segment rectangle[]);
void calcul_hauteur(Segment rectangle[]);
void creer_segment(Segment rectangle[], int segmentChoisis);
void afficher_segment(SDL_Surface *ecran, Segment rectangle[]);
void action(SDL_Event *event, Segment rectangle[], int *continuer);


/****************************************************************************/
/*                  DECLARATIONS DE FONCTIONS                     */
/****************************************************************************/
int main(int argc, char *argv[])
{
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Surface *ecran = NULL;
    SDL_Event event;

    /*ANTI_DEBORDEMENT permet d'éviter les effets indésirables aux bords
    de la fenêtre. Initialisation du tableau rectangle de type segment.*/
    Segment rectangle[NOMBRE_SEGMENT + ANTI_DEBORDEMENT * 2] = {HAUTEUR_EAU, 0, 0};
    ecran = SDL_SetVideoMode(NOMBRE_SEGMENT * LARGEUR_SEGMENT, HAUTEUR_NULL * 2, 32,
                                SDL_HWSURFACE | SDL_DOUBLEBUF);

    /* On nomme ici la fenêtre de notre programme, "Ondes".*/
    SDL_WM_SetCaption("Ondes", NULL);

    int i;
    int continuer = 1;

    /* On définit ici la hauteur des rectangles composants notre liquide
    à HAUTEUR_EAU pixels.*/
    for (i = 0; i < NOMBRE_SEGMENT + ANTI_DEBORDEMENT * 2; i++)
    {
        rectangle[i].hauteur = HAUTEUR_EAU;
    }

    /*La variable continuer permet la gestion de l'événement fermer fenêtre
    par la fonction action*/
    while(continuer)
    {
        SDL_PollEvent(&event);
        action(&event, rectangle, &continuer);
        calcul_acceleration(rectangle);
        calcul_vitesse(rectangle);
        calcul_hauteur(rectangle);
        afficher_segment(ecran, rectangle);
        SDL_Delay(TEMPS_PAUSE);
    }

    SDL_Quit();

    return EXIT_SUCCESS;
}

/****************************************************************************/
/*                  DECLARATIONS DE FONCTIONS                     */
/****************************************************************************/
void calcul_acceleration(Segment rectangle[])
{
    int i;

    for (i = 1; i < NOMBRE_SEGMENT + ANTI_DEBORDEMENT*2; i++)
    {
        rectangle[i].acceleration = (rectangle[i-1].hauteur + rectangle[i+1].hauteur
        - rectangle[i].hauteur * 2) - (FROTTEMENT * rectangle[i].vitesse);
    }
}





void calcul_vitesse(Segment rectangle[])
{
    int i;

    for (i = 1; i < NOMBRE_SEGMENT + ANTI_DEBORDEMENT*2; i++)
    {
        rectangle[i].vitesse = rectangle[i].vitesse + rectangle[i].acceleration / 2;
    }
}





void calcul_hauteur(Segment rectangle[])
{
    int i;

    for (i = 1; i < NOMBRE_SEGMENT + ANTI_DEBORDEMENT * 2; i++)
    {
        rectangle[i].hauteur = rectangle[i].hauteur + rectangle[i].vitesse;
    }
}





void creer_segment(Segment rectangle[], int segmentChoisis)
{
    int i;

    for (i = segmentChoisis - LARGEUR_ONDE; i < segmentChoisis + LARGEUR_ONDE; i++)
    {
        if (i  > 0 && i < NOMBRE_SEGMENT + ANTI_DEBORDEMENT * 2)
        {
            rectangle[i].hauteur = rectangle[i].hauteur + COURBURE_POUSSE *
            PROFONDEUR_ONDE * exp(-pow((i-segmentChoisis),2)/COURBURE_POUSSE) *
            (-2 / COURBURE_POUSSE + 4 * (pow(i - segmentChoisis,2)/pow(COURBURE_POUSSE,2)));
        }
    }
}





void action(SDL_Event *event, Segment rectangle[], int *continuer)
{
    /* si clic sur l'écran, création de l'onde */
    if (event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_LEFT)
    {
        creer_segment(rectangle, event->button.x / LARGEUR_SEGMENT + ANTI_DEBORDEMENT);
        event->type = 0;
    }
    /* si clic sur la croix, on ferme */
    if (event->type == SDL_QUIT)
        *continuer = 0;
}





void afficher_segment(SDL_Surface *ecran, Segment rectangle[])
{
    SDL_Surface *Rectangle = NULL;
    SDL_Rect position;
    SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format,255, 255, 255));

    int i;

    for (i = ANTI_DEBORDEMENT; i < NOMBRE_SEGMENT + ANTI_DEBORDEMENT; i++)
    {
        position.x = (i - ANTI_DEBORDEMENT) * LARGEUR_SEGMENT;
        position.y = HAUTEUR_NULL * 2 - rectangle[i].hauteur + 2;

        Rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, LARGEUR_SEGMENT,
        rectangle[i].hauteur, 32, 0, 0, 0, 0);

        if(Rectangle != NULL)
        {
            SDL_FillRect(Rectangle, NULL, SDL_MapRGB(Rectangle->format, 0, 0, 255));
        }

        SDL_BlitSurface(Rectangle, NULL, ecran, &position);

        if(Rectangle != NULL)
        {
            SDL_FreeSurface(Rectangle);
        }

    }
    SDL_Flip(ecran);

}


Voilà un petit programme sympa que je me suis amusé à faire parallèlement à mon cours de C de la dernière session. La librairie graphique est la SDL.

Où la physique rejoint l'info...

Si ça intéresse quelqu'un, je peux lui envoyer le .exe ou mieux l'énoncé du problème! Very Happy

En gros, le programme simule une étendue d'eau vue de côté, en juxtaposant un certain nombre de rectangles. L'utilisateur peut cliquer autant de fois qu'il le désir sur la fenêtre, ce qui aura pour effet de propager une onde à gauche et à droite du point d'impact.

L'intérêt principal de l'exercice est d'implementer des équations physiques en C. Un autre intérêt est de jouer avec la SDL.

Désolé pour le manque de commentaire du code, comme je l'ai dis j'ai fait ce boulot pour moi j'ai donc été moins vigilant que lors des remises au bourreau (comprendre le prof). Si quelqu'un souhaite des clarifications... n'hésitez pas.

@+

Stef
avatar
Stef

Nombre de messages : 30
Age : 36
Localisation : Montréal
Date d'inscription : 22/10/2008

http://citizenstefjournal.blogspot.com/

Revenir en haut Aller en bas

Voir le sujet précédent Voir le sujet suivant Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum