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

VB.NET Discussion :

Simulation de colision de cercles


Sujet :

VB.NET

  1. #1
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Janvier 2013
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Janvier 2013
    Messages : 57
    Points : 44
    Points
    44
    Par défaut Simulation de colision de cercles
    Bonjour

    Depuis plus d'une semaine j'essaye d'écrire une petite application simulant des collisions entres des boules(représentées par des cercles).J'ai déjà pus écrire une petite partie du code mais il est tellement beugé que je craint devoir le réécrire une 5eme fois.

    c'est une application en 2D qui devras se contenter de trouver les nouveaux "vecteurs direction" de chaque sphères (un nombre variable, j'utilise une liste) après la collision, de la manière la plus réaliste possible.Les boules ont un rayon et une masse différentes et peuvent se rencontrer de n’importe quelle façon.Les frottements et la gravité sont ignorées.

    Au vu de mon niveau en math ( ) se serais bien de faire simple, clair et détaillé (je n'ai pas encore vu les vecteurs alors je me débrouille comme je peut(même si je n'ai rien compris au code que j'ai écrit))

    Me = la boule en cour de traitement ; Jeu.Boulles(i) = la boule avec laquelle on teste et traite si nécessaire la collision ; .PosY et .PosX = position ; .VectX et .VectY = composants des vecteurs vitesse
    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
     
    If GetDistance(Me.PosX, Me.PosY, Jeu.Boulles(i).PosX, Jeu.Boulles(i).PosY) - Me.rayon - Jeu.Boulles(i).rayon <= 0 And Me.TheI <> i Then  'ca, ca marche
     
                        Dim CDT As Integer = -1 / ((Me.PosY - Jeu.Boulles(i).PosY) / (Me.PosX - Jeu.Boulles(i).PosX) + 0.02) ' recherche du coef-directeur de la droite tangente passant par le point d'intersection des cercles
     
                        Dim d As New Point(1, CDT) ' j'ai oublié c'est quoi :( , je crois que j'ai voulu faire un truc qui s'appelle vecteur unitaire
                        Dim a As New Point(Me.VectX + CDT * Me.VectY, Me.VectX * CDT + CDT * CDT * Me.VectY) 'je sais pas c'est quoi mais je le guarde au cas ou c'est important
     
                        Dim up As New Point(2 * (Me.VectX + Me.VectY * CDT) - Me.VectX, 2 * (CDT * Me.VectX + CDT * CDT * Me.VectY) - Me.VectY) 'ca c'est le nouveau vecteur
     
                        If boo = True Then ' boo sert a éviter d' executer le code 3000 fois
                            Jeu.Boulles(i).colision(False)'je teste tout de suite pour l'autre boulle avant de faire les changement car sino elle croit qu'elle n'est plus en collision a cause du recul (mais ca marche pas :( )
                            While GetDistance(Me.PosX, Me.PosY, Jeu.Boulles(i).PosX, Jeu.Boulles(i).PosY) - Me.rayon - Jeu.Boulles(i).rayon <= 0 'on regarde si les boulles sont imbriquées les unes dans les autre et on les recule si oui pour éviter qu'elles restent collées enssemble (bug),mais ca marche toujour pas :ouin:
                                Me.PosX = Me.PosX - Me.VectX  'recul
                                Me.PosY = Me.PosY - Me.VectY 'recul
                            End While
                        End If
     
     
     
                        'la, j'enregistre les nouveaux vecteurs
                        Me.VectX = up.X 
                        Me.VectY = up.Y
     
                    End If
    bug:
    parfois,une seule des deux boules concernées rebondit
    des boules se greffent ensemble et ralentissent


    et au final ça marche pas, voir quarement pas, et moi et aussi et

    alors si vous pouvez m'aider ce serais vraiment sympas.
    merci d'avance

    PS:

    désolé pour la présentation (et pour les (nombreuses?) victimes qui devront le lire) de ce post mais je suis vraiment pas doué pour ça.

  2. #2
    Membre du Club Avatar de gaetan13
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2010
    Messages : 90
    Points : 56
    Points
    56
    Par défaut
    Bonjour,
    Pour détecter les collisions je pense qu'il serait pratique d'utiliser des équations de cercle : http://fr.wikipedia.org/wiki/%C3%89q...rt%C3%A9sienne.

    Je comprends pas pourquoi tu veux les reculer :
    'on regarde si les boulles sont imbriquées les unes dans les autre et on les recule si oui pour éviter qu'elles restent collées enssemble (bug),mais ca marche toujour pas
    Pourquoi quand on détecte une collision pourquoi on ne met pas directement à jours les nouveaux vecteurs avec la loi physique qui semble la mieux adaptée ici, celle des chocs élastiques... http://fr.wikipedia.org/wiki/Choc_%C3%A9lastique
    Tu as un algo qui te montre comment les mettre à jour en suivant cette loi.

  3. #3
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Janvier 2013
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Janvier 2013
    Messages : 57
    Points : 44
    Points
    44
    Par défaut
    Le problème, justement, c'est que je croyais avoir utilisé la méthode du wiki (mais je n'ai pas réussi a le mettre sous forme d'algorithme)

    ensuite si je les déplace au lieu de les reculer cela résout le problème des imbrication mais en pose 2 nouveaux:
    - a la place des imbrications, des boules font des "bonds" gigantesques donnant l'impression qu'elles se téléportent
    - message d'erreur au bout d'un certain temps : l'opération arithmétique a provoqué un dépassement de capacité dans :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Public Function GetDistance(ByVal x1 As Integer, ByVal y1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer)
                Return (Sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2))))
            End Function
    x1=-1054
    x2=1003
    y1=-153254
    y2=94

    ps : je sais pas pourquoi les valeurs sont tant élevées car la zone ou se déplacent les boules est fermée(2000x2000) et leurs vecteurs extremums sont (25,25) et (-25;-25)

  4. #4
    Membre du Club Avatar de gaetan13
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2010
    Messages : 90
    Points : 56
    Points
    56
    Par défaut
    Je pense que c'est tout l'algo qui est mal organisé. En le voyant comme ça c’est pas facile à comprendre la logique. Je te dis comment je ferai moi.

    Tu as à chaque boule son vecteur qui est associé, sa masse, sa vitesse, le point d'applications.... Bref

    Première étape
    On calcule le déplacement de la boule. En gros on regarde le temps écoulé depuis la dernière génération de la simulation,
    on en déduit la distance parcourue... Ensuite on met à jour les point d'application (centre de la boule)

    Deuxième étape

    On cherche une éventuelle collision que la MAJ des positions aurait entrainée. La résolution d'équation cartésienne
    est mieux car tu auras les points de collision, ta simulation n'en sera que plus complète.
    Si on a une collision entre deux boules tu peux appliquer la formule du wiki, tu mets a jour le vecteurs....

    Ensuite on retourne à l'étape 1 et les boules changeront de directions sans problème.

    Si il te parle de dépassement de capacité c'est certainement que le type integer n'est pas capable de stocker la valeur trop grande. Vu que les valeurs sont petites
    il s'agit certainement d'une erreur dans la formule.

    Edit : ta formule de calcul des distances me semble fausse : http://fr.wikipedia.org/wiki/Distanc...%A9matiques%29 Regarde la distance euclidienne pas les autres

  5. #5
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Janvier 2013
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Janvier 2013
    Messages : 57
    Points : 44
    Points
    44
    Par défaut
    Je n'ai surement pas le niveau pour ces équations...
    Je ne sais ce qu'est un vecteur que depuis moins de 2 semaines et j'ai galérer pour essayer de faire un algorithme qui fonctionne sans succès.
    a chaque fois que je recommence j'ai l'impression de faire pareil et qu'il n'y a aucun progrès

    j'ai déja utilisé les formules du wiki et cela ne donnait pas des choses très réaliste car cela ne fessais qu’inter-changer les vecteurs 'y' composant les vecteurs vitesses des cercles.(ou alors j'ai rien compris)

  6. #6
    Membre du Club Avatar de gaetan13
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2010
    Messages : 90
    Points : 56
    Points
    56
    Par défaut
    Mis à part les chocs élastiques je ne vois pas trop comment modéliser ton problème. Le wiki se base sur un repère par rapport au point de collision donc c'est pas trop la même chose pour toi, faut comprendre les formules et adapter à la situation.
    C'est important je pense de bien comprendre ce qu'est un vecteur pour que tu aies un résultat correct.

    Essaie déjà de simplifier ton problème pour commencer. Au lieu d'appliquer ces formules, quand tu détecte une collision inverse simplement le signe des coordonnées de vitesse en x et en y... Ça ne sera pas du tout réaliste mais si ca fonctionne il ne reste plus qu'a modifier quelques trucs pour utiliser les chocs élastiques.

    Un exemple basique :
    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
     
    Public Class Main
        Public Sub main()
     
            Dim n As New Ball
            n.vX = 10
            n.vY = 10
     
            Dim n2 As New Ball
            n2.posX = 100
            n2.posY = 100
            n2.vX = -10
            n2.vY = -10
     
     
            ''On lance les calculs de position en boucle ici....
        End Sub
        ''' <summary>
        ''' On calcule la nouvelle position après un certain temps
        ''' </summary>
        Public Sub calcNewPos(b As Ball, time As Integer)
            b.posX = b.posX + vX * time
            b.posY = b.posY + vY * time
        End Sub
    End Class
    Public Structure Ball
        Public posX As Integer = 0
        Public posY As Integer = 0
        Public vX As Integer = 0
        Public vY As Integer = 0
        Public diameter As Integer = 0
    End Structure

  7. #7
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Janvier 2013
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Janvier 2013
    Messages : 57
    Points : 44
    Points
    44
    Par défaut
    Merci pour cet exemple mais moi je cherche quelque chose de plus réaliste.
    Je suis reparti sur une autre piste qui a l'air prometteuse mais qu' ébauché, alors je vais la continuer pendant un certain temps...
    j'en donnerais des nouvelles une fois terminée...

  8. #8
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Janvier 2013
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Janvier 2013
    Messages : 57
    Points : 44
    Points
    44
    Par défaut
    Je n'arive pas a trouver la source de l'erreur la dedans qui provoque 1/10 fois un dépassement de capacités :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
                       'recherche de l'angle
                        Dim QA As Long = (Asin(((Jeu.Boulles(i).PosX) - (Me.PosX)) / GetDistance(Me.PosX, Me.PosY, Jeu.Boulles(i).PosX, Jeu.Boulles(i).PosY)) / (2 * PI)) * 360 
                        If Me.PosY >= Jeu.Boulles(i).PosY Then QA = 180 - QA
                       'convertion de l'angle pour éviter qu'il soit égal a -165° ou 345685436°, mais bien compris entre 0 et 360 
                        While QA > 360
                            QA = QA - 360
                        End While
                        While QA < 0
                            QA = QA + 360
                        End While
    ce bout de code donne des angles
    EDITrobleme résolu en ajoutant au début
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    If Me.PosX = Jeu.Boulles(i).PosX Then Me.PosX = Me.PosX + 1
    ensuite je suis amené a calculer la différence entre les deux angle, est-ce que je m'y prend bien ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Public Function DGetDif(ByVal a1 As Single, ByVal a2 As Single) As Integer
                If (a1 - a2) * (a1 - a2) > 32400 Then
                    If (a1 - (a2 - 360)) * (a1 - (a2 - 360)) > 32400 Then
                        Return (Sqrt((a2 - (a1 - 360)) * (a2 - (a1 - 360))))
                    Else
                        Return (Sqrt((a1 - (a2 - 360)) * (a1 - (a2 - 360))))
                    End If
                Else
                    Return (Sqrt((a1 - a2) * (a1 - a2)))
                End If
            End Function

  9. #9
    Membre du Club Avatar de gaetan13
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2010
    Messages : 90
    Points : 56
    Points
    56
    Par défaut
    As-tu corrigé l'erreur dans la fonction GetDistance ? Parce que avec les valeurs exemple de tout à l'heure c'est normal qu'il y ai un dépassement...

    x1=-1054
    x2=1003
    y1=-153254
    y2=94

    ....

    Et puis c'est pas vraiment un problème de programmation qu’il y a mais plutôt algorithmique. Les erreurs ont l'air de commencer avant tous les codes que tu as envoyé.... GetDistance reçoit déjà n'importe quoi

  10. #10
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Janvier 2013
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Janvier 2013
    Messages : 57
    Points : 44
    Points
    44
    Par défaut
    Ce bout de code la fonctionne mieux, quoi qu'avec des nombreux bug dont je ne trouve pas comment les résoudre, mais pour un début, c'est déjà bien. N’empêche que j'aimerais quand même bien trouver(ou obtenir) mieux

    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
     
    If Me.PosX > 2000 Then Me.VectX = -Me.VectX
                If Me.PosY > 2000 Then Me.VectY = -Me.VectY
                If Me.PosX < 0 Then Me.VectX = -Me.VectX
                If Me.PosY < 0 Then Me.VectY = -Me.VectY
     
                If Me.PosX > 2000 Then Me.PosX = 1999
                If Me.PosY > 2000 Then Me.PosY = 1999
                If Me.PosX < 0 Then Me.PosX = 1
                If Me.PosY < 0 Then Me.PosY = 1
     
                For i = 0 To Jeu.Boulles.Count - 1
                    If GetDistance(Me.PosX, Me.PosY, Jeu.Boulles(i).PosX, Jeu.Boulles(i).PosY) - Me.rayon - Jeu.Boulles(i).rayon <= 0 And Me.TheI <> i Then
     
                        If Me.PosX = Jeu.Boulles(i).PosX Then Me.PosX = Me.PosX + 1
                        If Me.PosY = Jeu.Boulles(i).PosY Then Me.PosY = Me.PosY + 1
     
                        Dim QA As Long = (Asin(((Jeu.Boulles(i).PosX) - (Me.PosX)) / GetDistance(Me.PosX, Me.PosY, Jeu.Boulles(i).PosX, Jeu.Boulles(i).PosY)) / (2 * PI)) * 360
                        If Me.PosY >= Jeu.Boulles(i).PosY Then QA = 180 - QA
                        While QA > 360
                            QA = QA - 360
                        End While
                        While QA < 0
                            QA = QA + 360
                        End While
                        Dim RA As Long = (Asin(((Me.VectX + IIf(Me.VectX = 0, 1, 0) + Me.PosX) - (Me.PosX)) / GetDistance(Me.PosX, Me.PosY, Me.VectX + IIf(Me.VectX = 0, 1, 0) + Me.PosX, Me.VectY + IIf(Me.VectY = 0, 1, 0) + Me.PosY)) / (2 * PI)) * 360
                        If Me.PosY >= Jeu.Boulles(i).PosY Then QA = 180 - QA
                        While RA > 360
                            RA = RA - 360
                        End While
                        While RA < 0
                            RA = RA + 360
                        End While
     
                        Dim difAngles As Integer = DGetDif_Max90(QA, RA)
                        Dim Ivitesse As Integer = GetDistance(Me.PosX, Me.PosY, Me.PosX + Me.VectX, Me.PosY + Me.VectY)
                        Dim Tvitesse As Integer = (Sqrt(((180 - difAngles) / 180) * ((Me.Poid / Jeu.Boulles(i).Poid)))) * Ivitesse
                        Jeu.Text = Ivitesse.ToString & "   " & Tvitesse.ToString
     
                        Dim futurVectX = -Math.Round(Math.Sin(1 * PI * QA / 360) * GetDistance(Jeu.Boulles(i).PosX, Jeu.Boulles(i).PosY, Jeu.Boulles(i).PosX + Jeu.Boulles(i).VectX, Jeu.Boulles(i).PosY + Jeu.Boulles(i).VectY))
                        Dim futurVectY = -Math.Round(Math.Cos(1 * PI * QA / 360) * GetDistance(Jeu.Boulles(i).PosX, Jeu.Boulles(i).PosY, Jeu.Boulles(i).PosX + Jeu.Boulles(i).VectX, Jeu.Boulles(i).PosY + Jeu.Boulles(i).VectY))
     
                        Jeu.Boulles(i).VectX = Math.Round(Math.Sin(1 * PI * QA / 360) * GetDistance(Me.PosX, Me.PosY, Me.PosX + Me.VectX, Me.PosY + Me.VectY))
                        Jeu.Boulles(i).VectY = Math.Round(Math.Cos(1 * PI * QA / 360) * GetDistance(Me.PosX, Me.PosY, Me.PosX + Me.VectX, Me.PosY + Me.VectY))
     
                        Me.VectY = futurVectY
                        Me.VectY = futurVectY
     
                    End If
                Next
    Bug:
    les boules foncent vers le pas lorsqu’elles se percutent avec l'une en dessous de l'autre
    des boules ne prennent pas le bon angle mais rarement
    des boules rentrent les unes dans les autres avant de rebondir, mais correctement (juste gainant graphiquement)

    J'ai conscience de ne pas être allé au plus court, mais c'est tout ce que j'ai trouvé

    En fait ce dont j'aurais besoin ce serais d’égalités du genre :
    << lavaleurquejerecherche = (machin * truc + bidule) / jenesaisquoi >>
    avec la valeur que je recherche d'un coté et les valeurs que je connais (toutes) de l'autre, voir d'un algorithme que je pourrais facilement adapter a ma situation.

    J'ai bien conscience que ce serais me mâcher le travail mais de toute façon, avec les formules du wiki et autres sites, pour moi c'est du << abracadabra >>, et cela me bloque pour le reste de mon application, que je souhaitait ensuite prendre pour modèle afin de fabriquer un petit jeu façon billard pour m’habituer justement a ces formules... Mais je vois désormais que cela risque d’être beaucoup plus long...

    PS:J'ai demandé a un de mes anciens profs de math, ainsi qu'a un prof de science dans mon lycée : pour l'instant, aucun d'eux n'a pus m'aider...

  11. #11
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Hello,

    Je pense que ceci pourrait t'intéresser. Ce n'est pas du VB.NET mais bon. La théorie y est.

    Après, j'avoue avoir lu la discussion en diagonale. P-e le problème est de savoir vers où renvoyer la bulle après la collision ^^.

    D'instinct, j'utiliserais les réminiscences de mon cour d'optique (angle d’incidence = angle de réflexion) à la manière d'un jeu de billard. Après, tu parles de poids et de vitesse. J'imagine que ça doit entrer compte...
    Kropernic

  12. #12
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Les boules peuvent-elles tourner sur elles-mêmes ? Si oui, alors il faut aussi prendre en compte une énergie de rotation.

  13. #13
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour
    A mort les chocs elastiques.Bref je ne connais pas tout ton code mais ton problem est un probleme "basique" de simulation de collisions
    Comme deja signale par Gaetan13 l'article WKI est point depart mais je trouve cet artice (comme beaucoup de lecteurs wiki -tape collision elastique pour voir les protestataires- ,je le trouves "absconse et obscur")...car pour comprendre la modelisation de cet article il faut lire un autre article
    (coefficient de restitution lien Wiki : http://www.google.fr/url?q=http://fr.wikipedia.org/wiki/Coefficient_de_restitution&sa=U&ei=0VpYU-zhEuOt7QaC8YHwDA&ved=0CCEQFjAA&usg=AFQjCNGefToBwIXScBSjtHmXd0XLI2ag)....

    Rappel :
    1/Un choc elastique parfait => choc sans dissipation d'energie cinetque (c.à.d sans "ecrasement,deformation suivi de diminution progressive de vitesses avec le temps ou ralentissement...)

    2/Pour 2 corps m1 et m2 ,avec vitesse initiales v1i,v2i & vitesses finales v1f t v2f le choc est regie par 2 equations :
    - a) conservation quantite de mouvement :m1*v1i + m2*v2i = m1*v1f + m2*vf
    - b) equation coefficient de restitution :
    v1f - v2f = -e(v1i -v2i) avec 0<= e <=1
    si e = 1 => choc dit "elastique parfait" (billard)et l'equation du coefficient de restitution devient heureusement pour toi et moi:
    v1f - v2f = -(v1i -v2i)
    si e est < 1 => choc "inelastique" (balle de caatchouc,tennis etc...)

    3/Un lecteur averti en vaut 2 & il resout ce systeme à 2 inconnues(v1f & v2f) et 2 equations par substitution...

    En le resolvant on retombe sur les formules du wiki avec les masses (paragraphe choc direct) mais ou la "sale equation avec les vitesses au carre" est remplace par notre bonne equation du coeffecient de restitution....
    On trouve les 2 vitesses finales apres le choc dans leur propre repere(vu que toutes nos vitesses de l'algo qui suit sont definis comme des vecteurs par leurs 2 coordonnees dans notre repere 2D)..
    Leur direction (& module) sont connus...

    4/Qu'en est -il des limites de fenetre ? Elles seront assimiles à des parois fixes :
    -verticales fixes (left et right)
    -horizontales (top et bottom).
    Dans ce cas les parois etant planes le rebon "ressemble" à une reflexion optique" :
    - le vecteur vitesse final apres rebond est symetrique par rapport à la perpendicule au plan de la paroi ...
    Paroi horizontale :on change VelocityX en -VelocityX et on conserve VelocityY
    Paroi vertcale :on change VelocityY en -VelocityY et on conserve VelocityX

    4/ Test de collision: beti beta des "games" .pour tester la collision de 2 cercles (2D) ou Sphere (3D) on verifie :
    -distance au carre des centres < = somme au carre des 2 rayons
    On utilise distance au carre pour eviter d'appeler Math.Sqrt car il ralentit l'execution au run-time...

    Bref code .vb du class SpriteConst qui dessine des bitmaps avec :
    -position,centre,diametre et masse ....& test 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
     
    Public Class SpriteConst
        Public Property SpriteImage As Bitmap
        'coordonnees
        Public Property X As Integer
        Public Property Y As Integer
     
        'centre de la boule
        Public ReadOnly Property CX As Double
            Get
                Return X + Diameter / 2
            End Get
        End Property
        Public ReadOnly Property CY As Double
            Get
                Return Y + Diameter / 2
            End Get
        End Property
        'vitesse
        Public VelocityX As Integer
        Public VelocityY As Integer
        'masse
        Public Property Masse As Double
        'diametre
        Public Property Diameter As Integer
        Public Sub UpdatePos()
     
     
     
        End Sub
        Public Sub Draw(ByVal g As Graphics)
            ' ----- Update the location.
            X += VelocityX
            Y += VelocityY
            ' ----- Draw the sprite.
            g.DrawImage(SpriteImage, X, Y)
        End Sub
     
        Public Function CollisionRayon(ByVal targetSprite As SpriteConst) _
            As Boolean
            ' ----- See if two sprites overlap each other.
     
            Dim distCentre As Double = (targetSprite.CX - Me.CX) * (targetSprite.CX - Me.CX) +
            (targetSprite.CY - Me.CY) * (targetSprite.CY - Me.CY)
     
     
            Dim radius1 As Double = Me.Diameter / 2
            Dim radius2 As Double = targetSprite.Diameter / 2
            Dim distCollision As Double = (radius1 + radius2) * (radius1 + radius2)
     
            ' ----- Compare the distances.
            If (distCentre > distCollision) Then Return False
     
     
            ' -----  collision.
            Return True
        End Function
     
    End Class
    code .vb du form d'utilisation:

    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
     
     
    Public Class frmSpriteConst
        Private MySprites(10) As SpriteConst
        Private rnd As Random = New Random
        Public Sub New()
     
            ' Cet appel est requis par le concepteur.
            InitializeComponent()
     
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            Me.DoubleBuffered = True
        End Sub
     
     
        Private Sub frmSpriteConst_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            ' ----- Prepare the sprites.
            Dim canvas As Graphics
     
            ' ----- Create  sprites.
            For i As Integer = 0 To MySprites.Length - 1
                MySprites(i) = New SpriteConst
     
                MySprites(i).X = rnd.Next(Me.Left, Me.Right)
                MySprites(i).Y = rnd.Next(Me.Top, Me.Bottom)
                MySprites(i).Diameter = rnd.Next(30, 60)
                MySprites(i).Masse = MySprites(i).Diameter   'on fait masse proportionnelle au diametre
     
     
                If i Mod 2 Then
                    MySprites(i).VelocityX = 8
                    MySprites(i).VelocityY = 4
                Else
                    MySprites(i).VelocityX = 4
                    MySprites(i).VelocityY = -8
                End If
                MySprites(i).SpriteImage = New Bitmap(MySprites(i).Diameter, MySprites(i).Diameter)
                canvas = Graphics.FromImage(MySprites(i).SpriteImage)
                canvas.Clear(Color.FromArgb(0, 0, 0, 0))
                canvas.FillEllipse(RandomBrush, 0, 0, MySprites(i).Diameter, MySprites(i).Diameter)
                canvas.Dispose()
            Next
     
     
            ' ----- Start the action.
            Timer1.Interval = 50
            Timer1.Enabled = True
        End Sub
     
        Private Sub frmSpriteConst_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            ' ----- Draw the sprites on a background.
     
            ' ----- un background  barre---------------------
            For counter As Integer = 0 To Me.ClientSize.Width * 2 Step 20
                e.Graphics.DrawLine(New Pen(Color.LightBlue, 5), _
                   counter, -5, counter - Me.ClientSize.Height - 10, _
                   Me.ClientSize.Height + 5)
            Next
     
            ' ----- Draw each  sprites.
     
            For i As Integer = 0 To MySprites.Length - 1
                MySprites(i).Draw(e.Graphics)
                For j As Integer = 0 To MySprites.Length - 1
                    ' ----- See if the  sprites have hit each other.
     
                    If MySprites(i).CollisionRayon(MySprites(j)) Then
                        Dim m1 As Integer = MySprites(i).Masse
                        Dim m2 As Integer = MySprites(j).Masse
                        Dim numerator As Integer = m1 - m2
                        Dim denom As Integer = m1 + m2
                        Dim v1x As Integer = MySprites(i).VelocityX
                        Dim v1y As Integer = MySprites(i).VelocityY
                        Dim v2x As Integer = MySprites(j).VelocityX
                        Dim v2y As Integer = MySprites(j).VelocityY
                        MySprites(i).VelocityX =
                            (numerator / denom) * v1x + (2 * m2 / denom) * v2x
                        MySprites(i).VelocityY =
                            (numerator / denom) * v1y + (2 * m2 / denom) * v2y
     
                        MySprites(j).VelocityX =
                            (2 * m1 / denom) * v1x + (-numerator / denom) * v2x
                        MySprites(j).VelocityY =
                            (2 * m1 / denom) * v1y + (-numerator / denom) * v2y
                    End If
                Next
     
            Next
     
     
     
            ' ----- Move the sprites for the next update.
            For i As Integer = 0 To MySprites.Length - 1
     
                If (MySprites(i).X < 0) Then
                    MySprites(i).VelocityX = _
                      -MySprites(i).VelocityX
                End If
                If (MySprites(i).Y) < 0 Then
                    MySprites(i).VelocityY = _
                        -MySprites(i).VelocityY
                End If
                If (MySprites(i).X > _
                      (Me.ClientSize.Width - 30)) Then
                    MySprites(i).VelocityX = _
                      -MySprites(i).VelocityX
                End If
                If (MySprites(i).Y > _
                      (Me.ClientSize.Height - 30)) Then
                    MySprites(i).VelocityY = _
                      -MySprites(i).VelocityY
                End If
     
     
            Next
        End Sub
     
        Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            ' ----- Trigger a redraw of the form.
            Me.Refresh()
        End Sub
        'on randomize le brush pour le plaisir des yeux
        Private rndColor As New Random
        Private Function RandomBrush() As SolidBrush
            Dim red As Integer = rndColor.Next(0, 255)
            Dim green As Integer = rndColor.Next(0, 255)
            Dim blue As Integer = rndColor.Next(0, 255)
            Dim br As New SolidBrush(Color.FromArgb(255, red, green, blue))
            Return br
        End Function
    End Class
    Remarque auss que vb.net ne dispose pas d'un class Vector mais on peut s'rn sortir quand meme avec des props en allongeant le code...
    En esperant que cela fera ton bonheur.....

    Cette histoire de wiki me rappele une belle blague radiophonique sur la table de multiplication par 9 de Martin interroge par un grincheux inspecteur primaire...
    bon code...

  14. #14
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Janvier 2013
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Janvier 2013
    Messages : 57
    Points : 44
    Points
    44
    Par défaut
    Merci MABROUKI, pour cette réponse plus que complète, j'ai lu la moitié et je m'apprètte a lire l'autre,j’éditerais mon post après.
    Mais avant je te remercie beaucoup pour la clarté/simplicité/efficacité/pilecequelevoulaitité/etc. de ton post...

    ÉDIT:

    Le code du deuxième exemple fonctionne asse bien.
    Cependant il persiste quelques bugs gainant niveau réalisme de certaines collisions:
    boules qui repartent simplement d’où elles son venus
    boules qui prennent de direction bizard

    mais ils sont assé rares, je vais m'en contenter pour l'instant

    + pour toi, vraiment merci

    je mettrait résolu si je ne trouve pas mieux dans moins d'une semaine

Discussions similaires

  1. Probleme Voyageur de Commerce - Recuit Simulé
    Par dinver dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 21/06/2009, 22h26
  2. [VB6] [Graphisme] Tracer un cercle avec pset
    Par bleuerouge dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 09/12/2002, 17h12
  3. [VB6] [Graphisme] Arc de cercle dans un picturebox
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 04/11/2002, 17h55
  4. Simulation de transmission de paquet entre différent réseaux
    Par MelloW dans le forum Développement
    Réponses: 2
    Dernier message: 12/07/2002, 19h51
  5. savoir si 1 point est a l'intérieur d'un cercle ...
    Par skarladevobsy dans le forum Algorithmes et structures de données
    Réponses: 15
    Dernier message: 23/05/2002, 18h14

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