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

C++ Discussion :

Normalisation d'un vecteur 3D


Sujet :

C++

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2016
    Messages : 7
    Points : 7
    Points
    7
    Par défaut Normalisation d'un vecteur 3D
    Bonjour,
    J'ai un problème lorsque je cherche à normaliser un vecteur 3D. Sur le papier c'est censé être correct, à savoir, par rapport au calcul de la norme
    ||v||= sqrt ( v.x² + v.y² + v.z² ) => 1 = sqrt ( (v.x/||v||)² + (v.y/||v||)² + (v.z/||v||)² ) mais dans la réalité du code ci-après, ça ne fonctionne pas très bien. Entre autre des erreurs de calculs parfois énorme et des incohérences.

    Résultat de mon côté :
    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
     
    vecteur1 non normalise: x = 5, y = 2, z = 1, norme = 5.47723
     
    vecteur2 non normalise: x = 0, y = 3, z = 2, norme = 3.60555
     
    somme: x = 5, y = 5, z = 3, norme = 7.68115
     
    vecteur1 normalise: x = 0.912871, y = 0.166667, z = 0.182574, norme = 0.945751
     n'est pas normalise
     
    vecteur2 normalise: x = 0, y = 0, z = 0.5547, norme = 0.5547
     n'est pas normalise
     
    somme: x = 0.912871, y = 0.166667, z = 0.737274, norme = 1.18519
     n'est pas normalise
     
    Process returned 0 (0x0)   execution time : 0.016 s
    Press any key to continue.
    Le code :
    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
     
    #include <iostream>
    #include <cmath>
     
    using namespace std;
    struct Vecteur3D
    {
        double x;
        double y;
        double z;
    };
     
    double Vecteur3DGetNorme(const Vecteur3D &v)
    {
        return sqrt( v.x*v.x + v.y*v.y + v.z*v.z );
    }
    void Vecteur3DNormaliser(Vecteur3D &vecteur)
    {
        double norme = Vecteur3DGetNorme(vecteur);
        if(norme != 0)
        {
            vecteur.x = vecteur.x/norme;
            vecteur.y = vecteur.x/norme;
            vecteur.z = vecteur.z/norme;
        }
    }
    bool Vecteur3DEstNormalise(const Vecteur3D &vecteur)
    {
        if(Vecteur3DGetNorme(vecteur) == 1)
            return true;
        else
            return false;
    }
    Vecteur3D Vecteur3DAdd(const Vecteur3D &v1, const Vecteur3D &v2)
    {
        Vecteur3D tmp;
        tmp.x = v1.x+v2.x;
        tmp.y = v1.y+v2.y;
        tmp.z = v1.z+v2.z;
        return tmp;
    }
    void Vecteur3DAfficher(const Vecteur3D &vecteur)
    {
        cout << "x = " <<vecteur.x<< ", y = " <<vecteur.y<< ", z = "<<vecteur.z<<", norme = "<<Vecteur3DGetNorme(vecteur)<<endl;
    }
    int main(void)
    {
        Vecteur3D vecteur1 = {5,2,1};
        Vecteur3D vecteur2 = {0,3,2};
        cout << "vecteur1 non normalise: ";
        Vecteur3DAfficher(vecteur1);
        cout << endl;
        cout << "vecteur2 non normalise: ";
        Vecteur3DAfficher(vecteur2);
        cout << endl;
        cout << "somme: ";
        Vecteur3DAfficher(Vecteur3DAdd(vecteur1,vecteur2));
        cout << endl;
        Vecteur3DNormaliser(vecteur1);
        Vecteur3DNormaliser(vecteur2);
        cout << "vecteur1 normalise: ";
        Vecteur3DAfficher(vecteur1);
        if(Vecteur3DEstNormalise(vecteur1))
            cout << " est normalise" << endl;
        else
            cout << " n'est pas normalise" << endl;
        cout << endl;
        cout << "vecteur2 normalise: ";
        Vecteur3DAfficher(vecteur2);
        if(Vecteur3DEstNormalise(vecteur2))
            cout << " est normalise" << endl;
        else
            cout << " n'est pas normalise" << endl;
        cout << endl;
        cout << "somme: ";
        Vecteur3D somme = Vecteur3DAdd(vecteur1,vecteur2);
        Vecteur3DAfficher(somme);
        if(Vecteur3DEstNormalise(somme))
            cout << " est normalise" << endl;
        else
            cout << " n'est pas normalise" << endl;
     
        return 0;
    }
    Merci d'avances à ceux qui m'aideront à résoudre mon problème ^^"

  2. #2
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Mai 2012
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2012
    Messages : 163
    Points : 624
    Points
    624
    Par défaut
    Bonjour
    Je n'ai pas regardé en détails mais ceci a l'air douteux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void Vecteur3DNormaliser(Vecteur3D &vecteur)
    {
            ...
            vecteur.y = vecteur.x/norme;  // ???
            ...
    D'autre part, il ne faut pas comparer des doubles directement mais à un epsilon près, à cause des approximations numériques.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2016
    Messages : 7
    Points : 7
    Points
    7
    Par défaut
    Oups ! Merci, c'était une étourderie de ma part, tout fonctionne maintenant.
    Et oui de base je faisais mes test sur un encadrement par epsilon de mes doubles, mais j'ai voulu "simplifier" mes tests pour trouver l'erreur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void Vecteur3DNormaliser(Vecteur3D &vecteur)
    {
        double norme = Vecteur3DGetNorme(vecteur);
        if(norme != 0)
        {
            vecteur.x /= norme;
            vecteur.y /= norme;
            vecteur.z /= norme;
        }
    }

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Ceci dit, je ne vois pas vraiment pourquoi tu préfixe toutes tes fonctions de Vecteur3D...

    De deux choses l'une :
    ou bien tu veux normaliser un vecteur ou vérifier s'il est normalisé et tu te fous pas mal de savoir de quel type de vecteur il s'agit (du moment que la fonction le sait au travers de son paramètre, il n'y a pas de problème)
    ou bien tu essaye d'avoir une approche que l'on tend de plus en plus à promouvoir qui consiste à "penser en termes de services", mais, à ce moment là, tu aurais sans doute intérêt à créer des fonctions membres

    En effet, C++ suppporte parfaitement un principe nommé la "surcharge de fonction", qui permet à deux fonctions (ayant le même but) de travailler avec des paramètres de type différents. Or, le fait de préfixer toutes tes fonctions de Vecteur3D va avoir pour effet que, tôt ou tard, tu en arrivera à créer des fonctions (strictement identiques dans leurs objectifs) proche de Vecteur2DNormaliser, Vcteur2DEstNormalise, Vecteur2DAfficher, Vecteur2DAdd, etc.

    Ce n'est pas une erreur en soi, mais, si l'on y réfléchit trente seconde, c'est le normaliser, le estNormailisé, le add ou encore le afficher qui importe. Et le langage ne nous oblige pas forcément (comme c'est le cas pour C) d'avoir des noms de fonctions différents même lorsque le type des paramètres est différent.

    Dés lors, pourquoi se faire du mal inutilement

    PS : Tu aurais aussi très largement intérêt à décider une bonne fois pour toute de la langue dans laquelle tu sélectionnes les différents identifiants dont tu te sers (les noms de fonction, entre autres), car:
    • getNorme, c'est du franglais
    • estNormalisé, c'est du français
    • add, c'est de l'anglais
    • etc ...

    A titre personnel, je te conseillerais de choisir l'anglais, entre autres parce que c'est une langue qui, contrairement au francais, n'utilise aucun caractère accentué susceptible de modifier le sens d'un mot (normalise et normalisé ont deux sens très différents ). Mais tu fais bien sur comme tu l'entend . Par contre, il est vraiment très important de veiller à utiliser toujours la même langue!!! Je me fous pas mal que tu choisisse le français, l'anglais, l'italien ou le papou, tant que tous tes identfiants soient issus de la même langue, et qu'il n'y en ait pas qui soient issus du français, d'autre de l'italien et d'autres encore du papou
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. Normalisation des composantes d'un vecteur
    Par soniaIRM dans le forum Mathématiques
    Réponses: 15
    Dernier message: 26/02/2013, 22h36
  2. normalisation d'un vecteur
    Par NEKABSMAIL dans le forum Signal
    Réponses: 1
    Dernier message: 13/05/2011, 22h27
  3. Réponses: 9
    Dernier message: 24/06/2009, 12h59
  4. matrices * vecteur
    Par delire8 dans le forum Algorithmes et structures de données
    Réponses: 15
    Dernier message: 07/09/2002, 14h15

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