HELLLLPPPP !!! problème de collision
Répondre à la discussion
Affichage des résultats 1 à 3 sur 3

HELLLLPPPP !!! problème de collision



  1. #1
    invitecbc313ea

    HELLLLPPPP !!! problème de collision


    ------

    Bien le bonjour ,
    je rencontre un problème de collision entre une particule (la balle ) et un carré , mon programme marche , or je n'arrive pas à créer cette collision j'aimerais que la particule ne traverse pas le carré mais le touche juste et retombe .
    voici mon programme officiel en c++:

    Code:
    #include <Grapic.h>
    #include <cmath>
    #include <ctime>
    #include <time.h>
    
    using namespace grapic;
    
    const int DIMW = 500;
    const int MAXPART = 100;
    const float FRICTION = 0.9;
    
    struct Vec2 {
        float a;
        float b;
    };
    
    Vec2 operator+(Vec2 a, Vec2 b) {
        Vec2 c {a.a+b.a, a.b+b.b};
        return c;
    }
    
    Vec2 operator*(Vec2 a, Vec2 b) {
        Vec2 c {a.a * b.a - a.b * b.b, a.a * b.b + a.b * b.a };
        return c;
    }
    
    Vec2 operator*(float a, Vec2 b) {
        Vec2 c {a*b.a, a*b.b};
        return c;
    }
    
    Vec2 operator-(Vec2 a, Vec2 b) {
        Vec2 c {a.a - b.a, a.b - b.b };
        return c;
    }
    
    Vec2 operator/(float a, Vec2 b) {
        Vec2 c {a/b.a, a/b.b};
        return c;
    }
    
    struct particle {
        Vec2 pos;
        Vec2 speed;
        Vec2 force;
        float mass;
    };
    
    struct World {
        particle parts[MAXPART];
        int n;
    };
    
    
    
    
    void partAddForce(particle &p, Vec2 f) {
        p.force = p.force + f;
    }
    
    void partUpdatePV(particle &p)
    {
        if(p.pos.a < 10)
        {
            p.pos.a += 2*(10-p.pos.a);
            p.speed.a = - FRICTION * FRICTION * p.speed.a;
            p.speed.b = FRICTION * p.speed.b;
        }
        else if(p.pos.a > DIMW - 10)
        {
            p.pos.a += 2*(DIMW-10 - p.pos.a);
            p.speed.a = -FRICTION * FRICTION * p.speed.a;
            p.speed.b = FRICTION * p.speed.b;
    
        }
        if(p.pos.b < 10)
        {
            p.pos.b += 2*(10-p.pos.b);
            p.speed.b = -FRICTION * FRICTION * p.speed.b;
            p.speed.a = FRICTION * p.speed.a;
    
        }
        else if(p.pos.b > DIMW - 10)
        {
            p.pos.b += 2*(DIMW-10 - p.pos.b);
            p.speed.b = -FRICTION * FRICTION * p.speed.b;
            p.speed.a = FRICTION * p.speed.a;
        }
    
        p.pos = p.pos + p.speed;
        p.speed = p.speed + ( (1 / p.mass) * p.force);
    }
    
    struct carre
    {
        Vec2 VV;
        int score;
    };
    
    void draw(World a, carre C) {
    
        color(200, 0, 0, 200);
    
        for(int i =0; i < a.n; i++)
        {
            color(rand()%255 , rand()%255,rand()%255 ,255); // qui va permettre de générer aléatoirement des couleurs
            circleFill(a.parts[i].pos.a, a.parts[i].pos.b, 15);//15 = taille des boules
        }
        color(38,196,236);
    }
    
    void initcarre(carre& C)
    {
        C.VV.a = 50;
        C.VV.b = DIMW - 20;
        C.score = 0;
    }
    
    void draw2(carre& C)
    {
        float dt = 0.01;
        if(C.VV.a < DIMW-20)
        {
            C.VV.a = C.VV.a+2*dt;
        }
        else
        {
            initcarre(C);
        }
        color(38,196,236);
        rectangleFill(C.VV.a-20,C.VV.b-10,C.VV.a+20,C.VV.b+10);
    
        fontSize(50);
        print(50,50,C.score);
    }
    
    
    
    void update(World &a, carre& C) {
        for(int i = 0; i < a.n; i++)
        {
            partUpdatePV(a.parts[i]);
            if(abs(a.parts[i].pos.b-C.VV.b)<1 && abs(a.parts[i].pos.a-C.VV.a)<9)
            {
                C.score= C.score+1;
            }
        }
    
    }
    
    
    void init(World &a) {
        srand(time(NULL));
        a.n = 1;
        for(int i = 0; i < a.n; i++) {
            a.parts[i].pos.a = DIMW/2;  //j'ai diviser la taille de la fenetre en abscisse par deux pour que la balle s'affiche au milieu dès le lancement du programme
            a.parts[i].pos.b = 0;   //j'ai mis 0 pour que la balle soit tout en bat (en gros 0 en ordonné)
            a.parts[i].speed.a = 0;
            a.parts[i].speed.b = 0;
            a.parts[i].force.a = 0;
            a.parts[i].force.b = 0;//a 0 le balle de rebondi plus à chaque depp ,lacement
            a.parts[i].mass = 1;
        }
    }
    
    void CollisionPartETCarre(particle& part, carre c)
    {
        
    }
    
    
    void jump(World &a)
    
    
        {
            int i;
            if (isKeyPressed(SDLK_SPACE))
            {
                a.parts[i].speed.b = frand(0,8);
            }
            if (isKeyPressed(SDLK_LEFT))
            {
                a.parts[i].pos.a=a.parts[i].pos.a - 10;
                a.parts[i].pos.b=0;
               // a.parts[i].speed.a = - 0.5; //permet de faire bouger la boule a gauche fluidement au lieu qu'elle ne saute
               // a.parts[i].speed.b = 1; //ca le fais  sauter
            }
            if (isKeyPressed(SDLK_RIGHT))
    
    
            {
                 a.parts[i].pos.a=a.parts[i].pos.a + 10;
                a.parts[i].pos.b=0;
                //a.parts[i].speed.a = 0.5;//permet de faire bouger la boule a droite fluidement au lieu qu'elle ne saute
               // a.parts[i].speed.b = 1; //ca le fais  sauter
            }
        }
    
    
    
    
    int main(int , char ** )
    {
        World dat;
        carre C;
        bool stop=false;
        winInit("Particles", DIMW, DIMW);
        backgroundColor( 255, 255, 255 );
        init(dat);
        initcarre(C);
    
    
          while( !stop )
        {
            winClear();
    
            update(dat,C);
            draw(dat,C);
            draw2(C);
            jump(dat);
            stop = winDisplay();
        }
    
        winQuit();
        return 0;
        }
    MERCIIII

    -----

  2. #2
    invite6486d7bd

    Re : HELLLLPPPP !!! problème de collision

    Une méthode qui fonctionne pas mal :

    On calcule les point d'intersection de la droite, définie par le vecteur déplacement et l'ancienne position de la balle (droite directionnelle), avec les droites définissant les bords du carré.

    Par exemple, on cherche à calculer le point d'intersection de la droite du bord haut du carré avec la droite directionnelle.
    Si le calcul échoue (droites parallèles ou quasi parallèles), on continue avec la droite du bord suivant (bas du carré par exemple),
    sinon, on vérifie que la distance ancienne position/point d'intersection est plus faible ou égale à la "vitesse" (déplacement pour un pas), on vérifie alors si le point d'intersection est dans le carré (limite du carré inclus) ou plus simplement se trouve sur le segment du bord (*, voir à créer une fonction 2 ou pas).
    Si le point d'intersection n'est pas dans ou sur le carré, continuer avec le bord suivant, sinon, si la valeur de la position d'intersection n'a pas encore été définie, la stocker, sinon, conserver la valeur de la position d'intersection qui correspond à la distance [ancienne position/position d'intersection] la plus faible.
    Passer au bord suivant le cas échéant.

    Il vous faut donc 2 ou 3 fonctions, simples :
    1) Calcul de la distance entre deux points.
    2) Vérification qu'un point se trouve dans un carré, plus lent mais plus simple (ou alors vous faites un test customisé en *).
    3) Calcul du point d'intersection entre 2 droites.

  3. #3
    invite6486d7bd

    Re : HELLLLPPPP !!! problème de collision

    Pour aller plus loin.

    Comme on le constate, l'ensemble des tests à effectuer va rendre le programme peu lisible (et rend les modifications éventuelles ou corrections à effectuer à la mise au point plus difficiles).
    On parcours les 4 bords du carré (qui pourrait être rectangle), et on doit réécrire les mêmes tests à peu de choses près.
    Il peut être alors judicieux de généraliser le test d'un bord à tous les bords pour faire le test au sein d'une boucle de 4 itérations.

    Pour ce faire, il faut préparer les données nécessaires aux tests de la boucle et étendre la structure qui défini le type "carre" pour les stocker.
    Le carré doit donc contenir les équations des droites (les valeurs paramétriques ou autre, selon le choix de représentation de la droite), stockées dans un tableau de dimension 4 (4 bords).
    On peut alors parcourir le tableau lors du test du carré et employer ces valeurs pour le test d'intersection.

    De la même manière, il peut être intéressant de stocker les valeurs employées lors du test d'inclusion d'un point dans le carré, à savoir les coordonnes du point gauche/bas et du point droite/haut (ce sont en effet des valeurs qui seront réutilisées à chaque cycle du programme).

Discussions similaires

  1. [Problème] Collision Élastique !
    Par invited86e31d3 dans le forum Physique
    Réponses: 7
    Dernier message: 11/04/2018, 15h06
  2. [RF/Radioelec] Probléme de collision entre un recepteur et plusieurs emetteur
    Par dje8269 dans le forum Électronique
    Réponses: 22
    Dernier message: 17/04/2017, 21h17
  3. [Problème] Collision parfaitement inélastique.
    Par inviteef250368 dans le forum Physique
    Réponses: 1
    Dernier message: 27/12/2015, 15h42
  4. Problème en RR : collision élastique entre neutron et proton
    Par invite118bd558 dans le forum Physique
    Réponses: 0
    Dernier message: 11/10/2010, 12h30
  5. Problème de collision
    Par invited876642b dans le forum Physique
    Réponses: 0
    Dernier message: 05/12/2006, 21h48