IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Physique Discussion :

rebond entre deux balles


Sujet :

Physique

  1. #1
    Membre très actif Avatar de fifafou
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2016
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 173
    Par défaut rebond entre deux balles
    Après avoir réussi a gérer des rebonds avec une balle fixe et un balle libre,J'ai cherché a gérer un rebond entre deux balles libres.
    Mais pour trouver la vitesse de chaque balles après la collision,je bloque.
    voici mon code Python
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    from Tkinter import *
    from math import *
    fen=Tk()
    fen.title("boules")
    fon=Canvas(fen,height=400,width=400,bg="white")
    fon.pack()
    fen.geometry("400x400")
    y,x=0,-200.0
    y1,x1=0.0,0.0
    no=fon.create_oval(150,150,250,250,fill="black")
    ro=fon.create_oval(x+150,y+150,x+200,y+200,fill="red")
    vr,vo=3.0,(input("angle")/180.0)*pi
    vr1,vo1=0.0,0
    def running():
        global x,y,vr,vo,x1,y1,vr1,vo1
        fon.coords(ro,x+150,y+150,x+250,y+250)
        fon.coords(no,x1+150,y1+150,x1+250,y1+250)
        x+=vr*cos(vo)
        y+=vr*sin(vo)
        x1+=vr1*cos(vo1)
        y1+=vr1*sin(vo1)
        if x>200 or x<-200:
            vo=pi-vo
        if y>200 or y<-200:
            vo=-vo
        if x1>200 or x1<-200:
            vo1=pi-vo1
        if y1>200 or y1<-200:
            vo1=-vo1
        if (x1-x)**2+(y1-y)**2<10000:
            vo=2*(atan2(y-y1,x-x1)+(pi/2.0))-vo
            vo1=vo-pi
    ##        vr=        Je ne trouve rien
    ##        vr1=
        fen.after(15,running)
    running()
    fen.mainloop()

  2. #2
    Membre très actif Avatar de fifafou
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2016
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 173
    Par défaut
    Desolé,mon code avait une petit defaut
    le voici corrigé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    from Tkinter import *
    from math import *
    fen=Tk()
    fen.title("boules")
    fon=Canvas(fen,height=400,width=400,bg="white")
    fon.pack()
    fen.geometry("400x400")
    y,x=0,-200.0
    y1,x1=0.0,0.0
    no=fon.create_oval(150,150,250,250,fill="black")
    ro=fon.create_oval(x+150,y+150,x+200,y+200,fill="red")
    vr,vo=3.0,(input("angle")/180.0)*pi
    vr1,vo1=3.0,0
    def running():
        global x,y,vr,vo,x1,y1,vr1,vo1
        fon.coords(ro,x+150,y+150,x+250,y+250)
        fon.coords(no,x1+150,y1+150,x1+250,y1+250)
        x+=vr*cos(vo)
        y+=vr*sin(vo)
        x1+=vr1*cos(vo1)
        y1+=vr1*sin(vo1)
        if x>200 or x<-200:
            vo=pi-vo
        if y>200 or y<-200:
            vo=-vo
        if x1>200 or x1<-200:
            vo1=pi-vo1
        if y1>200 or y1<-200:
            vo1=-vo1
        if (x1-x)**2+(y1-y)**2<10000:
            vo=2*(atan2(y-y1,x-x1)+(pi/2.0))-vo
            vo1=2*(atan2(y1-y,x1-x)+(pi/2.0))-vo1
    ##        vr=
    ##        vr1=
        fen.after(5,running)
    running()
    fen.mainloop()

  3. #3
    Membre très actif Avatar de fifafou
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2016
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 173
    Par défaut
    Je cherche toujours

  4. #4
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Salut,

    un petit copier/coller de code en C++ qui pourrait t'inspirer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    bool Plateau::manageCollision(Balle& a, Balle& b) {
        double vitessesX, vitessesY, positionsX, positionsY, scalaireAB, Vabx, Vaby, vabLength, VabNormalizedX, VabNormalizedY;
        double VabNormalizedScalaireA, VabNormalizedScalaireB, VaScalairizedX, VaScalairizedY, VbScalairizedX, VbScalairizedY;
        double resX, resY;
     
        vitessesX = a.vitesse.x - b.vitesse.x;
        vitessesY = a.vitesse.y - b.vitesse.y;
     
        positionsX = a.position.x - b.position.x;
        positionsY = a.position.y - b.position.y;
     
        scalaireAB = (vitessesX * positionsX) + (vitessesY * positionsY);
        if (scalaireAB > 0) {
            // pas une 'vraie' collision, les balles s'éloignent
            return false; 
        }
     
        Vabx = b.position.x - a.position.x;
        Vaby = b.position.y - a.position.y;
     
        vabLength = sqrt((Vabx * Vabx) + (Vaby * Vaby));
     
        VabNormalizedX = Vabx / vabLength;
        VabNormalizedY = Vaby / vabLength;
     
        VabNormalizedScalaireA = VabNormalizedX * a.vitesse.x + VabNormalizedY * a.vitesse.y;
        VabNormalizedScalaireB = VabNormalizedX * b.vitesse.x + VabNormalizedY * b.vitesse.y;
     
        VaScalairizedX = (VabNormalizedX * VabNormalizedScalaireA);
        VaScalairizedY = (VabNormalizedY * VabNormalizedScalaireA);
        VbScalairizedX = (VabNormalizedX * VabNormalizedScalaireB);
        VbScalairizedY = (VabNormalizedY * VabNormalizedScalaireB);
     
        resX = VbScalairizedX - VaScalairizedX;
        resY = VbScalairizedY - VaScalairizedY;
     
        if (resX == 0 && resY == 0) {
            // pas une 'vraie' collision
            return false;
        }
     
        double coefMolesse = (a.molesse + b.molesse) / 2;
     
        a.vitesse.x = (a.vitesse.x + resX) / coefMolesse;
        a.vitesse.y = (a.vitesse.y + resY) / coefMolesse;
     
        b.vitesse.x = (b.vitesse.x - resX) / coefMolesse;
        b.vitesse.y = (b.vitesse.y - resY) / coefMolesse;
     
        return true;
    }

  5. #5
    Membre très actif Avatar de fifafou
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2016
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 173
    Par défaut
    merci beaucoup mais je n'ai pas réussi à adapter ce code au mien,surtout que j'utilise des coordonné polaires pour mon vecteur
    Merci quand même

  6. #6
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 052
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 052
    Billets dans le blog
    141
    Par défaut
    Bonjour,

    D'après ce que je remarque, il faut avoir une struture pour chaque balle. Ainsi, à chaque collision, vous allez pouvoir impacter facilement, la direction de chaque balle.
    Sinon, en soit, je ne vois pas trop de problème. Les rebonds me semble correct, sauf qu'une fois sur deux, la balle est non impactée par la collision avec l'autre.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  7. #7
    Membre très actif Avatar de fifafou
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2016
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 173
    Par défaut
    le probleme est que dans mon code, les boules gardent une vitesse constante
    exemple:si on met vr1,vo1=0.0,0 vers le début de mon code,la balle noire gardera une vitesse nulle tous le temps
    PS:je vais essayer avec des classes,ce sera plus pratique

  8. #8
    Membre très actif Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 728
    Par défaut
    Bonjour fifafou,

    Voici 2 fonctions (C++) qui mettent respectivement à jour les positions et les vélocités de chaques balles juste après collision :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    void updatePositions(Ball* a, Ball* b){//une fois hitTest détecté on place les balles qui se chevauchent, en bordure de tangeante au point de collision
     
        float collision_angle, angle_pos_a, angle_pos_b, a_norm_pos, b_norm_pos, a_ccs_x, a_ccs_y, b_ccs_x, b_ccs_y;
     
        collision_angle = atan2(static_cast<float>(a->m_y - b->m_y), static_cast<float>(a->m_x - b->m_x));
     
        angle_pos_a = atan2(static_cast<float>(a->m_y), static_cast<float>(a->m_x));
        angle_pos_b = atan2(static_cast<float>(b->m_y), static_cast<float>(b->m_x));
        a_norm_pos = sqrt(static_cast<float>(a->m_x*a->m_x + a->m_y*a->m_y));
        b_norm_pos = sqrt(static_cast<float>(b->m_x*b->m_x + b->m_y*b->m_y));
     
        a_ccs_x = a_norm_pos*cos(angle_pos_a - collision_angle);
        a_ccs_y = a_norm_pos*sin(angle_pos_a - collision_angle);
        b_ccs_x = b_norm_pos*cos(angle_pos_b - collision_angle);
        b_ccs_y = b_norm_pos*sin(angle_pos_b - collision_angle);
     
        if(a_ccs_x > b_ccs_x){
            a_ccs_x = (a_ccs_x + b_ccs_x)/2.0 + a->m_radius; // on positionne les boules de façon tangeante au point de collision dans le nouveau système de coordonnées
            b_ccs_x = a_ccs_x - a->m_radius - b->m_radius;
        }else{
            a_ccs_x = (a_ccs_x + b_ccs_x)/2.0 - a->m_radius; // on positionne les boules de façon tangeante au point de collision dans le nouveau système de coordonnées
            b_ccs_x = a_ccs_x + a->m_radius + b->m_radius;
        }
     
        a->m_x = cos(collision_angle)*a_ccs_x - sin(collision_angle)*a_ccs_y; // On rote les vecteurs position dans le bon système de coordonnées en utilisant une matrice de rotation 2D
        a->m_y = sin(collision_angle)*a_ccs_x + cos(collision_angle)*a_ccs_y;
        b->m_x = cos(collision_angle)*b_ccs_x - sin(collision_angle)*b_ccs_y;
        b->m_y = sin(collision_angle)*b_ccs_x + cos(collision_angle)*b_ccs_y;
     
    }
     
    void updateVelocities(Ball* a, Ball* b){ //une fois hitTest détecté on on réinitialise les vecteurs vitesses respectifs des 2 balles
     
        float collision_angle, angle_velocity_a, angle_velocity_b, a_norm_velocity, b_norm_velocity, a_ccs_velocity_x, a_ccs_velocity_y, b_ccs_velocity_x, b_ccs_velocity_y;
        float a_new_ccs_velocity_x, b_new_ccs_velocity_x, a_mass, b_mass;
     
     
        collision_angle = atan2(static_cast<float>(a->m_y - b->m_y), static_cast<float>(a->m_x - b->m_x));
        angle_velocity_a = atan2(static_cast<float>(a->m_velocity_y), static_cast<float>(a->m_velocity_x));
        angle_velocity_b = atan2(static_cast<float>(b->m_velocity_y), static_cast<float>(b->m_velocity_x));
     
        a_norm_velocity = sqrt(static_cast<float>(a->m_velocity_x*a->m_velocity_x + a->m_velocity_y*a->m_velocity_y));
        b_norm_velocity = sqrt(static_cast<float>(b->m_velocity_x*b->m_velocity_x + b->m_velocity_y*b->m_velocity_y));
     
        a_ccs_velocity_x = a_norm_velocity*cos(angle_velocity_a - collision_angle); //ccs = changed coordinate system. la tangeante au point de collision devient perpendiculaire à l'axe des absisses, ce qui simplifie le calcul
        a_ccs_velocity_y = a_norm_velocity*sin(angle_velocity_a - collision_angle);
        b_ccs_velocity_x = b_norm_velocity*cos(angle_velocity_b - collision_angle);
        b_ccs_velocity_y = b_norm_velocity*sin(angle_velocity_b - collision_angle);
     
        a_mass = (static_cast<float>(4/3)*MATH_PI*powf(static_cast<float>(a->m_radius), 3.0))/50;
        b_mass = (static_cast<float>(4/3)*MATH_PI*powf(static_cast<float>(b->m_radius), 3.0))/50;
        a_new_ccs_velocity_x = (a_ccs_velocity_x*(a_mass - b_mass) + 2*b_mass*b_ccs_velocity_x)/(a_mass + b_mass);// on peut se contenter de faire à présent une collision 1D sur l'axe des x
        b_new_ccs_velocity_x = (b_ccs_velocity_x*(a_mass - b_mass) + 2*b_mass*a_ccs_velocity_x)/(a_mass + b_mass);
     
        a->m_velocity_x = cos(collision_angle)*a_new_ccs_velocity_x - sin(collision_angle)*a_ccs_velocity_y; // On rote les vecteurs vitesse dans le bon système de coordonnées en utilisant une matrice de rotation 2D
        a->m_velocity_y = sin(collision_angle)*a_new_ccs_velocity_x + cos(collision_angle)*a_ccs_velocity_y;
        b->m_velocity_x = cos(collision_angle)*b_new_ccs_velocity_x - sin(collision_angle)*b_ccs_velocity_y;
        b->m_velocity_y = sin(collision_angle)*b_new_ccs_velocity_x + cos(collision_angle)*b_ccs_velocity_y;
     
    }
    Je te considère comme un frère

Discussions similaires

  1. Collision entre deux boules (glissade et non rebonds)
    Par Ephysio dans le forum Physique
    Réponses: 6
    Dernier message: 19/10/2015, 15h51
  2. [.NET VC++] ou exclusif entre deux String
    Par benoitB dans le forum MFC
    Réponses: 7
    Dernier message: 25/11/2003, 11h20
  3. Temps de réponse entre deux sites
    Par coup dur dans le forum Décisions SGBD
    Réponses: 6
    Dernier message: 16/10/2003, 15h26
  4. Connexion entre deux ordi [Débutant]
    Par Ryadus dans le forum Développement
    Réponses: 2
    Dernier message: 12/06/2003, 21h47
  5. Réponses: 5
    Dernier message: 25/03/2003, 19h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo