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

Mathématiques Discussion :

Angle orienté deux vecteurs: gestion des cas particuliers


Sujet :

Mathématiques

  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut Angle orienté deux vecteurs: gestion des cas particuliers
    Bonjour tout le monde,

    Je souhaites calculer l'angle orienté entre trois points, j'utilise donc l'arc tangente entre la norme du produit vectoriel sur le produit scalaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    atanf( (cross(v1, v2).length()) / (dot(v1, v2) )
    Seulement voila, j'ai un problème pour les points suivants:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    p1(0, 0)
    p2(1, 0)
    p3(0.5, -0.5)
    v1 = p2 - p1 = (1, 0)
    v2 = p3 - p1 = (0.5, -0.5)
    Si on veut l'angle orienté de p2p1p3 (en gros le coin inférieur droit du cercle trigo), j'obtiens un angle positif: je pense que c'est dû au calcul du produit scalaire donne une valeur positive:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dot (v1, v2) = 1*0.5 + 0*(-0.5) = 0.5
    Il doit y avoir une astuce mais je ne m'en rappelle plus du tout.

    Quelqu'un peut-il me dire où est-ce que je me trompe?

    Merci

    PS: Evidemment j'ai cherché avec Google mais certainement mal...

  2. #2
    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
    Salut

    Citation Envoyé par darkman19320 Voir le message
    je pense que c'est dû au calcul du produit scalaire donne une valeur positive:
    Non, c'est dû à ton produit vectoriel qui est pris en norme, et qui donc ne conserve aucune notion de signe.
    L'astuce est là...
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  3. #3
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    Salut,

    Merci pour la réponse.

    Faut-il que je fasse le produit scalaire entre mon vecteur du produit vectoriel et le premier vecteur v1?

    Je vais tester ça tout à l'heure et je vous tiens au courant.

    Edit: Malheureusement, cela ne change rien.

    Edit 2: J'ai enfin trouvé la formule:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    float sign = v1[0]*v2[1] - v1[1]-v2[2]; //Calcul du déterminant
      if (sign > 0)
      {
        sign = 1;
      }
      else
      {
        sign = -1;
      }
      //Arc cosinus modulo 2*pi.
      float res = fmod((sign * acos(dot(v1, v2)/(v1.length()*v2.length()))), 2*PI) * 180 / PI;
    Est-ce qu'il n'y aura pas des opérations moins coûteuse?

  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 darkman19320 Voir le message
    Est-ce qu'il n'y aura pas des opérations moins coûteuse?
    Ben si...

    Quand tu fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    float sign = v1[0]*v2[1] - v1[1]-v2[2]; //Calcul du déterminant
    en fait tu calcules un produit vectoriel (vu que tu es en 2D... donc sans notion de vecteur normal hors plan). En gros, c'est une norme signée de produit vectoriel, si on peut dire...

    Donc tu réinjectes ça directement à la place de ton cross(...).length() dans ta formule du premier post, et terminé. Seconde option, tu peux aussi récupèrer la troisième composante du cross(...) si tu veux garder cette fonction et ne pas faire intervenir la formule explicitement.

    Et même pas de test sur le signe à faire...

    Sinon, autre méthode, tu passes un atan2f sur tes deux vecteurs, et tu fais la différence entre les deux...
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  5. #5
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    Mille merci!!!

    Tu m'as vraiment bien aidé!

    Donc pour résumer, voici le bout de pseudo-code pour calculer l'angle orienté entre trois points:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    double orientedAngle(const Point2D & p1, const Point2D & p2, const Point2D & p3)
    {
       Vecteur v1 = p2 - p1;
       Vecteur v2 = p3 - p1;
     
       return atan2f(v1.x, v1.y) - atan2f(v2.x, v2.y);
    }

  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 darkman19320 Voir le message
    Donc pour résumer, voici le bout de pseudo-code pour calculer l'angle orienté entre trois points:
    En inversant les x et les y dans tes atan2f... normalement, la signature de la fonction est atan2f(y,x) (voir la doc du langage que tu utilises pour plus de détails).

    Ensuite, tu veux l'angle p2p1p3, il te faut donc faire angle(p1p3)-angle(p1p2), donc inverser tes vecteurs dans la formule.

    Il reste toutefois quelques cas particuliers à gérer... si tu as un angle pour v1 de -170° et un angle pour v2 de +170°, la différence va te donner -340° au lieu de +20°. Mathématiquement, c'est la même chose... mais à voir si tu préfères une présentation entre -180° et +180° (jouer sur des modulos 360 si nécessaire)
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

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

Discussions similaires

  1. [GLSL] Calculer un angle entre deux vecteurs.
    Par who_knows dans le forum OpenGL
    Réponses: 5
    Dernier message: 05/05/2010, 17h40
  2. Programmation Python angles entre deux vecteurs
    Par Manudu38 dans le forum Calcul scientifique
    Réponses: 3
    Dernier message: 18/11/2009, 18h17
  3. Gestion des caractères particuliers.
    Par piotrr dans le forum Eclipse Platform
    Réponses: 2
    Dernier message: 08/01/2008, 16h01
  4. Calcul d'angle entre deux vecteurs
    Par feynman dans le forum Fortran
    Réponses: 8
    Dernier message: 22/09/2007, 13h59
  5. Gestion des caractères particuliers pendant un import
    Par clemasson dans le forum Access
    Réponses: 2
    Dernier message: 09/12/2006, 17h58

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