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 :

Physique simple à base vecteurs


Sujet :

Physique

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 41
    Points : 25
    Points
    25
    Par défaut Physique simple à base vecteurs
    Bonjour à tous. Dans l'optique de créer un petit moteur physique très basique avec une gestion des rebondes, j'ai suivi ce tutorial, que je trouvais à la fois clair et simple :
    http://texel3d.free.fr/opengl/collisions.htm

    J'ai créer une classe de Vecteur, qui semble être parfaitement en règle, juste sur un point auquel je doute, le produit scalaire ou dot product. En effet j'ai des valeurs proches de 1 malgré la fonction acos... :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    double Vecteur::DotProduct(Vecteur *vec)
    {
    	double dot = (x * vec->x) + (y * vec->y);
    	double angle = acos(dot)*this->Longueur()*vec->Longueur();
    	return angle;
    }
    J'ai pas l'impression que sont des valeurs en degré.


    voici mon code entier :
    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
     
    for(int i = 0; i < vec.size() ; i++)
    				vec[i]->Normalise();
     
    				D = 0 - (pts[0]->x * pts[3]->x) - (pts[2]->x * pts[3]->y); // Calcul de D
    				dist = (pts[0]->x * pts[3]->x) + (pts[2]->y * pts[3]->y) + D; // Calcul de H
     
    				if(dist < 0)
    				{
    					CollisionSol = false;
    				}
    				else if (dist > 0)
    				{
     
    					for(int i = 0; i < vec.size() ; i++)
    					vec[i]->Normalise();
     
     
     
    					R = dist / (vec[2]->DotProduct(vec[3])); // Calcul de R
    					pts[4]->x = pts[3]->x - (vec[3]->x * R); // On redéfinit le point I avec ses coordonnées
    					pts[4]->y = pts[3]->y - (vec[3]->y * R);
     
     
    					vec[4]->SoustrairePts(pts[0], pts[4]); //AI
    					vec[5]->SoustrairePts(pts[0], pts[2]); //AB
     
    					for(int i = 0; i < vec.size() ; i++)
    					vec[i]->Normalise();
     
    					angle = vec[4]->DotProduct(vec[5]); 
     
    					cout << "angle final = " << angle << endl; 
    					if(angle == 1)
    					CollisionSol = true;
     
     
    				}
    Voici mes questions, j'ai du faire des modifs sont elles justes ? comme à cette partie :

    xi = x - ( xv * R)
    yi = y - ( yv * R)

    en code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    pts[4]->x = pts[3]->x - (vec[3]->x * R);
    pts[4]->y = pts[3]->y - (vec[3]->y * R);
    Et je ne comprend pas cette partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    III. On Cherche si le point I appartient au segment.
     
    Si le point I(xi,yi) appartient au segment, l'angle qui relient I(xi,yi) aux deux sommets du segment est égale à 180 degrés (ou PI).
    Si cet angle est égal à -180 degrés, le point G(x,y) est à l'extérieur du segment.
    On utilise le produit scalaire pour trouver cet angle.
    Attention aux extrémités des segments? 
     
    Note: 
     
    Le point G(x,y) appartiendra forcement à la droite donc l'angle est égal à -180 ou 180 degrés. Alors vous pouvez être très large dans le choix de votre marge d'incertitude.
    Ni la fin, avec le vecteur de rebond (extrémment important pourtant !!!)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    NouveauVecteurVitesse= V + 2*(-V.N)*N.
    Comment il fait cette multiplication, ça n'a pas été abordé dans le cours de Yno et donc dans mon implantation vectorielle en C++ non plus...

    Voilà j'ai besoin de votre aide !!! Merci d'avance

  2. #2
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut
    Salut,

    les fonctions trigo bossent avec des Radians et non des degrés... donc c'est normal que tu obtienne des petites valeurs.

    Suffit de te faire uen petite fonction de conversion de radians vers degrés et vice versa. mais tant que tu n'as pas à utiliser tes angels ailleurs que dans le code, autant tout laisser en radians...
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 41
    Points : 25
    Points
    25
    Par défaut
    Merci pour ta réponse, j'ai bien implanter le produit Scalaire, avec une fonction bien à part qui converti le radian en degré
    Néanmoins, quelqu'un peut m'éclairer sur le III) du Tuto, même juste en théorie, je ne comprend pas trop ...
    J'ai un niveau de maths de Seconde, mais je me suis avancé avec des tutos sur internet des vecteurs, je comprend donc la pluparts des choses, mais il y a peut être des notions qui m'échappent.... ?

    Notamment, comment faire ce calcul ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    NouveauVecteurVitesse= V + 2*(-V.N)*N.
    qui est le vecteur de rebond, je ne comprend pas trop les multiplications...
    Merci d'avance à tous pour vos réponses !

  4. #4
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Citation Envoyé par Daxter06 Voir le message
    Notamment, comment faire ce calcul ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    NouveauVecteurVitesse= V + 2*(-V.N)*N.
    qui est le vecteur de rebond, je ne comprend pas trop les multiplications...
    V est le vecteur vitesse (avant le contact), N est le vecteur normal à la surface au point de contact.
    En fait -(V.N)*N projète le vecteur vitesse selon la normale, reste plus qu'à l'ajouter en fois 2 au vecteur vitesse initial pour avoir le vecteur final
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 41
    Points : 25
    Points
    25
    Par défaut
    Merci beaucoup pour vos réponses.
    Mon algorythme marche maintenant pour les droites plates... mais pas pour les droites penchés. La partie de la calcul de distance est impossible apparement à mettre en oeuvre... j'ai donc décider de tester directement si l'angle AIB = 180° comme expliqué ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    III. On Cherche si le point I appartient au segment.
     
    Si le point I(xi,yi) appartient au segment, l'angle qui relient I(xi,yi) aux deux sommets du segment est égale à 180 degrés (ou PI).
    Si cet angle est égal à -180 degrés, le point G(x,y) est à l'extérieur du segment.
    On utilise le produit scalaire pour trouver cet angle.
    Attention aux extrémités des segments? 
     
    Note: 
     
    Le point G(x,y) appartiendra forcement à la droite donc l'angle est égal à -180 ou 180 degrés. Alors vous pouvez être très large dans le choix de votre marge d'incertitude.
    Donc, si tout était parfait ça devrait être ainsi :


    Hors, AI->DotProduct prend des valeurs étranges... pas du tout le 1 espéré lorsque AIB = 180°...

    voici mes fonctions DotProduct :
    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
     
    double Vecteur::DotProduct(Vecteur *vec)
    {
    	double dot = 0;
     
    	if(nbDimension == vec->nbDimension)
    	{
     
    	if(nbDimension == 1)
    	dot += (x * vec->x);
    	if(nbDimension == 2)
    	dot += (y * vec->y);
    	if(nbDimension == 3)
    	dot += (z * vec->z);
    	}
     
    	return dot;
    }
    et CollisionLvl :
    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
     
    bool Level::CollisionLvl(Object2DRigid *obj, int i)
    {
    		AI->SoustrairePts(A, obj->objet); // AI
    		BI->SoustrairePts(B, obj->objet); // BI
    		AI->Normalise();
    		BI->Normalise();
     
     
    		dot[i] = AI->DotProduct(BI);
    		cout << dot[i] << endl;
    		if(dot[i] > 1)
    		{
    			return true;
    		}
    		else
    		return false;
     
    }
    Comme vous le voyez, tout à été fait dans l'ordre, la soustraction des points, la normalisation et enfin le produit scalaire.... alors ou est le problème ? Ai-je utiliser le bon résonnement ? Faut-il forcément normaliser les vecteurs dans ce cas précis ? Voilà je m'arrache les cheveux avec ce problème j'ai besoin de votre aide !!
    Merci d'avance !

  6. #6
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Citation Envoyé par Daxter06 Voir le message
    mais pas pour les droites penchés. La partie de la calcul de distance est impossible apparement à mettre en oeuvre...
    Ca se fait très simplement avec un produit vectoriel... normalement...

    Citation Envoyé par Daxter06 Voir le message
    Hors, AI->DotProduct prend des valeurs étranges... pas du tout le 1 espéré lorsque AIB = 180°...
    Et il prend quelles valeurs exactement?
    De plus, lorsque I est sur le segment, tu devrais avoir AI.BI=-1, et pas 1 (les deux vecteurs sont parallèles, mais pas de même sens).
    Et encore de plus, avec des vecteurs normalisés, le produit scalaire sera forcément entre -1 et 1.


    Citation Envoyé par Daxter06 Voir le message
    Comme vous le voyez, tout à été fait dans l'ordre, la soustraction des points, la normalisation et enfin le produit scalaire.... alors ou est le problème ?
    Peut-être dans tes fonctions SoustrairePts ou Normalise...
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 41
    Points : 25
    Points
    25
    Par défaut
    Ca se fait très simplement avec un produit vectoriel... normalement...
    Comment ça ? J'utilise actuellement le produit vectoriel pour trouver la normale.

    Et il prend quelles valeurs exactement?
    Tout entre 1 et -1, mais il change de signe en touchant la droite... ce n'est pas normal... voilà quelques valeurs enregistrées au passage du point dans le segment :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    0.254136
    0.178075
    0.0986064
    0.0177797
    -0.062415
    -0.139987
    -0.212858
    -0.278918
    C'est bizarre... je n'ai pas touché à ma fonction DotProduct qui reste la même à savoir :
    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
     
    double Vecteur::DotProduct(Vecteur *vec)
    {
    	double dot = 0;
     
    	if(nbDimension == vec->nbDimension)
    	{
     
    	if(nbDimension == 1)
    	dot += (x * vec->x);
    	if(nbDimension == 2)
    	dot += (y * vec->y);
    	if(nbDimension == 3)
    	dot += (z * vec->z);
     
            }
     
    	return dot;
    }
    et voici mes fonctions SoustrairePTS :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void Vecteur::SoustrairePts(Point *pt, Point *pt2)
    {
    	x = pt2->x - pt->x;
    	y = pt2->y - pt->y;
    	z = pt2->z - pt->z;
    	reperex = pt->x;
    	reperey = pt->y;
     
    }
    et Normalise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void Vecteur::Normalise()
    {
    	for(int i = 0 ; i < 10 ; i++)
    	{
    	x = x / sqrt((x*x)+(y*y));
    	y = y / sqrt((x*x)+(y*y));
    	z = z / sqrt((x*x)+(y*y));
    	}
     
    }
    Je suis obligé de faire une boucle for pour que la normalisation se fasse vraiment à 1, sinon on a des valeurs approchées comme 1.015 pour la longueur, mais pas 1.00 ... voilà.

    Tout me paraît normal, je ne comprend pas !

  8. #8
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Citation Envoyé par Daxter06 Voir le message
    Comment ça ? J'utilise actuellement le produit vectoriel pour trouver la normale.
    Le produit vectoriel sert à plein de choses...
    Normalement, si tu calcules un produit vectoriel AI*Normalize(AB), que tu en prends la norme, ça devrait te donner la distance entre AB et ton point I.


    Citation Envoyé par Daxter06 Voir le message
    Tout entre 1 et -1, mais il change de signe en touchant la droite... ce n'est pas normal... voilà quelques valeurs enregistrées au passage du point dans le segment :
    Tout entre -1 et 1, c'est normal, que ça change de signe ça l'est moins, mais...


    Citation Envoyé par Daxter06 Voir le message
    Je suis obligé de faire une boucle for pour que la normalisation se fasse vraiment à 1, sinon on a des valeurs approchées comme 1.015 pour la longueur, mais pas 1.00 ...
    ... ça c'est n'importe quoi!

    Si tu es en 3D, il faut faire intervenir Z dans la racine, et on ne recalcule pas la racine avec une valeur qu'on vient de modifier la ligne d'avant!!!

    La racine représente la longueur de ton vecteur, si tu la calcules pour le y avec la valeur de x modifiée la ligne précédente, ça ne colle plus du tout. Donc tu vires ta boucle, tu calcules la racine au tout début, que tu mets dans une jolie variable, qui sera utilisée pour calculer les nouveaux x, y et z... mais là non! Tu mériterais des coups de fouets!
    Et ensuite tu retestes tes valeurs du produit scalaire... parce que là c'est normal que ça soit faux.
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 41
    Points : 25
    Points
    25
    Par défaut
    Merci pour toutes tes réponses, j'ai résolu mon problème grâce à ta technique pour la distance

    Même si je trouve que les phrases style
    ça c'est n'importe quoi!
    ou
    Tu mériterais des coups de fouets!
    sont de trop, et ne vont pas avec l'esprit d'entraide de ce forum. Même si je peux comprendre ton énervement vu mon niveau de Seconde en maths.

    Merci encore néanmoins !

  10. #10
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Citation Envoyé par Daxter06 Voir le message
    Même si je trouve que les phrases style
    [...]
    sont de trop, et ne vont pas avec l'esprit d'entraide de ce forum. Même si je peux comprendre ton énervement vu mon niveau de Seconde en maths.
    Toutes mes excuses si tu l'as mal pris, mais quand il y a un "" juste après, c'est de l'humour!

    Quand quelqu'un s'énerve ici, ça vire plutôt au

    C'est juste pour t'entrainer au futur monde du travail... (où tu aurais pris des coups de fouets! )
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Importer un modèle physique simple (robot)
    Par acx01b dans le forum Physique
    Réponses: 0
    Dernier message: 09/12/2008, 10h31
  2. Connection simple base de donnée SQL !
    Par 19cmos83 dans le forum JDBC
    Réponses: 4
    Dernier message: 30/07/2007, 11h49
  3. Copie physique de base avec nom instance différent
    Par Labienus dans le forum Administration
    Réponses: 3
    Dernier message: 25/06/2007, 15h18
  4. [systeme] ou est stockee physiquement une base de donnee ?
    Par pierre.zelb dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 05/07/2005, 14h42

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