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

Calcul scientifique Python Discussion :

Simulation trajectoire d'une particule ponctuelle


Sujet :

Calcul scientifique Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2018
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2018
    Messages : 2
    Par défaut Simulation trajectoire d'une particule ponctuelle
    Bonjour,

    Mon code compile ne se réalise pas corectement, mon but est de simuler la trajectoire d'une particule ponctuelle dans un espace fermé.
    La difficulté se situe au niveau de la réflexion de la particule (si vous lancez le code vous verrez).
    Pouvez-vous m'aider à le corriger ou m'indiquer un code existant similaire?

    Merci de votre aide
    Fichiers attachés Fichiers attachés

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Plusieurs remarques :

    1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Droite :
        """Définition d'une droite par :
        - un triplet (cx, cy, cste) représentant les coefficients de l'équation cartésienne cx*x + cy*y + cste = 0"""
     
        def __init__(self) :
            """Constructeur de la classe avec les valeurs par défaut"""
            self.cx = 0.0
            self.cy = 0.0
            self.cste = 0.0
     
    x=Droite()
    x.cy = 1
    La dernère ligne montre clairement un défaut d'implémentation de votre classe ! Si votre classe a besoin d'un paramètre cx ou cy à sa construction, alors son constructeur doit prendre en compte ses paramètres :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Droite :
        """Définition d'une droite par :
        - un triplet (cx, cy, cste) représentant les coefficients de l'équation cartésienne cx*x + cy*y + cste = 0"""
     
        def __init__(self, cx, cy, cste) :
            """Constructeur de la classe avec les valeurs par défaut"""
            self.cx = cx
            self.cy = cy
            self.cste = cste
     
    x=Droite(0.0,1.0,0.0)
    où éventuellement avec des valeurs par défaut


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Droite :
        """Définition d'une droite par :
        - un triplet (cx, cy, cste) représentant les coefficients de l'équation cartésienne cx*x + cy*y + cste = 0"""
     
        def __init__(self, cx=0.0, cy=0.0, cste=0.0) :
            """Constructeur de la classe avec les valeurs par défaut"""
            self.cx = cx
            self.cy = cy
            self.cste = cste
     
    x=Droite(cy=1.0)
    2) Si vous voulez obtenir le coefficient directeur d'une droite sous forme d'un vecteur, ce n'est pas a une fonction VecteurDir(droite) de le faire. C'est une méthode qui doit faire partie intégrante de la classe Droite

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Droite():
        def VecteurDir(self) :
            return Vecteur(self.cx, -self.cy)
    Et voyez que d'ailleurs c'est naturellement plus concis ...

    Et même on peut envisager un flag qui dira si le résultat doit être un vecteur unitaire ou non :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Droite():
        def VecteurDir(self, unitary=False) :
            u=Vecteur(self.cx, -self.cy)
            if unitary :
                u.MakeUnitary()
            return u
    où MakeUnitary serait une méthode de la classe Vecteur, et transformerait le vecteur en un vecteur unitaire en le divisant par sa norme.

    Même chose pour VecteurOrtho, norme, intersection, perpendiculaire, appartient_droite, appartient_segment, les fonctions de conversions d'un type à un autre, etc ...


    Tout ceci fait que l'on ne comprend pas votre code. Il y a l'air d'avoir de la sémantique au premier abord mais quand on regarde de plus près les choses ne sont pas là où elle devrait l'être.

    Ensuite votre problème est dans le rebond donc (l'angle de réfléchissement n'est pas le bon). Donc je dirais d'inspecter la fonction rebondBillardConvexe, voire meme symetrieVectorielle car là je ne comprends pas ce que vous y faites (faute en partie à la structure de votre code que j'ai commenté). Un rebond c'est une symétrie axiale par rapport à la normale au plan sur lequel on rebondit. C'est ca que vous faites ?

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2018
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2018
    Messages : 2
    Par défaut
    Merci pour votre aide néanmoins je n'arrive toujours pas à obtenir le résultat recherché.
    Fichiers attachés Fichiers attachés

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    On y voit déjà un peu plus clair.

    Utilise à fond ce que je t'ai donné , i.e :

    1) Faire en sorte que tu n'es jamais à écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monobjet.tel_attribut = qqch
    . Ces assignations doivent se faire dans la construction de l'objet.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class BoulePonctuelle :
        def toDroite(self) :
            cx, cy = sin(self.theta), -cos(self.theta)
            return Droite(cx, cy, -(self.absci*cy + self.ordo*cx) )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Vecteur :
        def __mul__(self, facteur) :
            """Retourne le produit d'un vecteur et d'un scalaire, (opération commutative)"""
            return Vecteur(self.absci*facteur, self.ordo*facteur)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bp = BoulePonctuelle(0, 0, (-pi/10 + 2*pi) % (2*pi))
    et j'en vois d'autre, mais je vais arrêter là l'énumération ...

    2) Lier tes méthodes aux classe auquelles elle rapportent.
    VandPtoD doit etre inclus dans vecteur (ou Point, ou les deux éventuellements)
    PandPtoV et PandPtoD doivent etre inclus dans Point
    intersections dans Droites, est_colinéaire, coefcol, produiScal, projectionOrtho, angle dans vecteur

    Ce n'est pas parcequ'il y a 2 paramètres que cela change vraiment la donne. Par exemple pour coefcol :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def coefcol (u, v) :
        if v.absci==0 : return round(u.ordo/v.ordo, 10)
        else : return round(u.absci/v.absci, 10)
    devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Vecteur :
         def coefcol (self, other) :
             if other.absci==0 : return round(self.ordo/other.ordo, 10)
             else : return round(self.absci/other.absci, 10)
    Et au lieu de l'appeler comme ça :
    On l'appelle comme ça :
    (fonction qui est d'ailleurs très bizarre au passage, car elle présuppose que les vecteurs sont colinéaires. Et s'il ne le sont pas, on ne le sait pas et ca fait n'importe quoi. Ca pourrait etre bien de le vérifier dans la fonction avant d'entamer les calculs)

    Et on pourrait faire mieux encore ensuite en créant une classe Polygone et une classe Trajectoire, voire également une classe MatriceRotation ou ChangementBON.



    Maintenant que j'y vois un peu plus clair, j'ai voulu changer quelque paramètre pour avoir des pistes sur l'endroit où cela merde. Mais dès que j'en change un, je me retrouve avec une erreur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      File "C:/Users/GLE7/Desktop/Rebond_Particule_ponctuelle.py", line 300, in rebondBillardConvexe
        inter, i = intersection_Billard(bp, BORD)
     
    TypeError: 'NoneType' object is not iterable
    Parce que ta fonction intersection_Billard retourne None. Et c'est d'ailleurs très bizarre qu'elle retourne None, car quelque soit la trajectoire de ta boule, elle va finir par taper l'un des bords ! Donc ici ca ne devrait jamais etre None qui est retourner ... Mathématiquement une droite, dont l'un des points est à l'intérieur dans polygone fermé, va forcément intersecter ce polygone

    En gros, quand je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TRAJ = trajBillardConvexe(bp, BORD, n)
    ça devrait fonctionner quelque soit n (n étant le nombre de rebond après lesquels j'arrete de calculer si j'ai bien compris).

    Ensuite je ne sais pas pourquoi tu t'embêtes à disséquer des cas de figures en fonction de l'angle et du bord. Dans mes souvenirs d'algèbre linéaire, si tu fais un changement de base, tu te ramènes au cas où le plan réfléchissant devient l'axe x, et la normale l'axe y. Dans cette base, il suffit simplement de transformer un vecteur u=(u0,u1) en v=(u0,-u1) pour avoir son réfléchit. Et la matrice de changement de base est simplement la concaténation du vecteur directeur unitaire du plan incident avec celui normal unitaire à ce même plan ...

    Je m'explique par un exemple.
    Considérons un carré reliant les points (0;0); (3;4); (-1;7); (-4;3).
    Je prends le 1er bord. Son vecteur directeur unitaire est (3;4) divisé par sa norme qui est 5, c'est à dire u=(0.6;0.8).
    Son vecteur normal unitaire est v=(-0.8,0.6).
    Donc la matrice de passage de la base (u,v) à la base canonique (où dans l'autre sens, à inverse près) est donc :
    [u;v] (u et v étant écrit en colonne) c'est à dire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [[0.6  -0.8],
     [0.8   0.6]]
    Alors oui après cette matrice peut s'écrire comme une matrice de rotation en fonction du sin et du cos d'un angle... Mais as t'on besoin de tomber là dedans qui force des distinctions de cas, distinction de cas qui posent des problèmes numérique puisque vos rebonds ne semble pas être calculé de la même manière en fonction du bord sur lequel on atterit ...
    Reprenez vous papier crayon, un peu de calcul s'impose je crois !

    PS : Autre piste d'amélioration de la lisibilité du code :
    1) .absci et .ordo partout c'est un peu lourd comme nom. .x et .y irait très bien
    2) Quand on traite avec numpy on a une bien meilleur artillerie que juste avec la librairie math. Donc l'import de la librairie math peut être virer et tirer plutot ce dont vous avez besoin sur numpy
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from numpy import pi, cos, sin, sqrt, arccos
    Il faut éviter les import * également

Discussions similaires

  1. Comment etre payé pour une mission ponctuelle?
    Par zefroggy dans le forum Paie
    Réponses: 21
    Dernier message: 15/01/2017, 00h32
  2. Simuler rebond d'une balle
    Par Coco4486 dans le forum Ogre
    Réponses: 2
    Dernier message: 09/05/2008, 20h26
  3. Simuler Click d'une autre page
    Par alexandre7g dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 27/09/2007, 13h39
  4. Réponses: 23
    Dernier message: 20/07/2007, 00h49
  5. Simuler l’appuie sur une touche du clavier
    Par Furius dans le forum C++
    Réponses: 2
    Dernier message: 26/09/2005, 18h15

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