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

Algorithmes et structures de données Discussion :

Calcul de rotation pour faire correspondre deux modules


Sujet :

Algorithmes et structures de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 125
    Par défaut Calcul de rotation pour faire correspondre deux modules
    salut,

    j'essaye de faire de la génération procédurale de donjon en 3D mais j'ai un peu de mal à trouver le bon algorithme pour calculer les rotations.

    en gros j'ai ça :

    deux modules A et B qui comprennent chacun plusieurs sorties.
    une sortie de A et une sortie de B sont sélectionnées aléatoirement et je cherche comment calculer la rotation que le module B devra effectuer pour que sa sortie sélectionnée corresponde avec la sortie sélectionnée du module B.
    par exemple si la sortie de A est 90°, il faut que B tourne ou reste immobile pour que sa sortie devienne -90°

    j'utilise des angles d'euler parce que je ne comprends pas bien comment utiliser les quaternions mais je ne suis pas contre des explications parce qu'il me semble que cela faciliterait mon problème, j'ai lu quelque part qu'il n'y avait pas de limitation à 180 ou un truc dans le genre avec les quaternion.
    et pour ce qui est de la disposition des angles, ce sont les valeurs qui me sont retournés dans le moteur. j'utilise urho3d donc ça sera en c++.

    j'ai essayé quelque truc avec mon programme mais comme ça fonctionnait bien une fois sur deux, je préfère ne pas mettre de code.
    j'ai déjà écrit le code pour calculer ensuite la position mais si je n'ai pas la bonne rotation, mon calcul est faussé car la position des sorties changent avec la rotation.

    je sais que ce n'est pas un calcul très complexe mais j'ai un peu de mal avec l'abstraction, quelqu'un peut-il m'expliquer comment faire ?

    merci.

  2. #2
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 289
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 289
    Par défaut
    Bonjour

    Déjà, tu devrais supprimé les angles négatifs pour être entre 0° et 360°. Donc -90 devient 270.
    Cela permet de faire un modulo si tu es au dessus de 360°.

    Ensuite, c'est quoi le problème ?
    Les sorties indiquées sont justement le nombre de degrés dont il faut tourner la pièce pour arriver à être en face.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 125
    Par défaut
    Citation Envoyé par Flodelarab Voir le message
    Déjà, tu devrais supprimé les angles négatifs pour être entre 0° et 360°. Donc -90 devient 270.
    Cela permet de faire un modulo si tu es au dessus de 360°.
    j'pensais utiliser les 360° au début mais c'est en convertissant les quaternion en angle euler et en regardant les valeurs du programme que j'me suis rendu compte qu'il les convertissait de cette façon avec 0, 90, -90, etc... et j'essaye de m'en sortir avec ça du coup.

    Citation Envoyé par Flodelarab Voir le message
    Ensuite, c'est quoi le problème ?
    Les sorties indiquées sont justement le nombre de degrés dont il faut tourner la pièce pour arriver à être en face.
    il faut que je prenne en compte les deux angles des deux sorties sélectionnées pour calculer la rotation du module B pour que sa sortie corresponde avec la sortie du module A.

    j'm'y perd un peu avec mes variables, les +, les -, j'vais faire d'autres tests avec mon programme.
    ça devrait etre un truc dans le genre je crois :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if(sortie_B.rotation>=0)
    {
        sortie_A.rotation.y_ - (180 - sortie_B.rotation.y_);
    }
    else
    {
        sortie_A.rotation.y_ - (180 - sortie_B.rotation.y_ * (-1));
    }
    mais il me semble que j'oublie des cas particuliers là.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 125
    Par défaut
    non ben j'sais pas, je sais que c'est un problème tout con mais mon cerveau fait un blocage la dessus ><

    j'me retrouve avec ce genre de résultat :

    donc même mon placement n'est pas bon parce que si la rotation est bonne, la sortie se retrouve dans le vide.

    Code c : 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
    //calculate new rotation of module with e_connector and m_connector
    ////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////
     
            rotation.x_ = 0;
            rotation.z_ = 0;
     
            if(m_connector.rotation.y_ >= 0)
            {
                e_connector.rotation.y_ - (180 - m_connector.rotation.y_);
            }
            else
            {
                e_connector.rotation.y_ - (180 - m_connector.rotation.y_ * (-1));
            }
     
            temp_Qrot = Vec2Quat(rotation);
            moduleNode->SetWorldRotation(temp_Qrot);
     
     
    //calculate new position of module with e_connector and m_connector
    ////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////
     
    //get choosen module exit node to have the updated position !!
            exit_child_name = stringInt ("exit", randomConnectorNbr);                            
            exit_name_urho = string2urhoString(exit_child_name);
            exitNode = moduleNode->GetChild(exit_name_urho, true);
     
            m_connector.position=exitNode->GetWorldPosition();   // position !!
            //m_connector.relative_pos=exitNode->GetPosition();    // relative_pos   !!  
     
     
            if(e_connector.position.x_>=0)
            {
                if(m_connector.position.x_>=0)
                {
                    position.x_ = m_connector.position.x_ + e_connector.position.x_;
                }
                else
                {
                    position.x_ = (m_connector.position.x_ * (-1)) + e_connector.position.x_;
                }
            }
            else
            {
                if(m_connector.position.x_>=0)
                {
                    position.x_ = (m_connector.position.x_ * (-1)) + e_connector.position.x_;
                }
                else
                {
                    position.x_ = m_connector.position.x_ + e_connector.position.x_;
                }
            }
     
            if(e_connector.position.z_>=0)
            {
                if(m_connector.position.z_>=0)
                {
                    position.z_ = m_connector.position.z_ + e_connector.position.z_;
                }
                else
                {
                    position.z_ = (m_connector.position.z_ * (-1)) + e_connector.position.z_;
                }
            }
            else
            {
                if(m_connector.position.z_>=0)
                {
                    position.z_ = (m_connector.position.z_ * (-1)) + e_connector.position.z_;
                }
                else
                {
                    position.z_ = m_connector.position.z_ + e_connector.position.z_;
                }
            }
     
     
            if(e_connector.position.y_>=0)
            {
                if(m_connector.position.y_>=0)
                {
                    position.y_ = e_connector.position.y_ + m_connector.position.y_;
                }
                else
                {
                    position.y_ = e_connector.position.y_ + (m_connector.position.y_ * (-1));
                }
             }
             else
             {
                if(m_connector.position.y_>=0)
                {
                    position.y_ = e_connector.position.y_ + (m_connector.position.y_ * (-1));
                }
                else
                {
                    position.y_ = e_connector.position.y_ + m_connector.position.y_;
                }
             }
     
            moduleNode->SetWorldPosition(position);


    je vais essayer de mieux poser le problème textuellement parce que j'ai vraiment du mal à imprimer là.


    en fait j'ai une liste des exits, une exit est choisi au hazard, c'est mon e_connector.
    ensuite je charge un nouveau module en position ZERO qui comprend x exits.
    je stocke les exits (type, pos, rot, etc..) dans une liste d'exits qui fait partie de ma classe module et j'en choisi une au hazard, m_connector.
    mon but est donc de faire correspondre l'exit du module à l'exit de la liste.
    pour se faire, je dois d’abord faire tourner mon module pour que la rotation de son exit soit l'inverse de la rotation de l'exit de la liste.

    ha, ben ça vient de me donner une idée. avec urho3D, j'ai une fonction :
    RotateAround (const Vector3 &point, const Quaternion &delta, TransformSpace space=TS_LOCAL)
    Rotate around a point in the chosen transform space.
    avec ça, je devrait pouvoir faire du m_connector le centre de rotation de mon module pour que m_connector.rotation.y_ == e_connector.rotation.y_ * (-1) avec comme cas particuliers si 0° ou 180°

    euh.. non en fait.
    j'm'embrouille avec les rotation des exits relative au module et les "world" rotation des exits et des modules.

    je vais refaire d'autre test avec mon programme pour bien voir les valeurs qui me sont retourné, j'fais vraiment un blocage avec cette connerie, c'est frustrant.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 125
    Par défaut
    je crois que même mon calcul des position n'est pas bon, j'ai beau essayer de différentes manière, j'arrive toujours à peu prêt au même résultat.
    y'aurait pas une meilleur méthode pour faire ça ? j'm'y perd vraiment avec les positions et rotations relatives et globales.

    il me semble que juste ça, c'est bon pour les rotation :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    rotation.y_ = e_connector.rotation.y_ - (180 - m_connector.rotation.y_);

    mais comme ça remarche encore une fois sur deux et que ça peut être à cause de la rotation ou de la position, j'arrive pas à bien cibler le problème.
    franchement, si quelqu'un pouvait m'éclaircir ou proposer une autre méthode ça serait sympa.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 125
    Par défaut
    bon, j'ai vérifié mes valeurs.
    entre blender et urho3D, j'm'étais un peu perdu dans les axes je crois.


    je dois donc utiliser le z de la rotation local de mes exits pour l'angle, x et z de la position global pour les coordonnés et y de la position global pour la hauteur.
    (en sachant que je dois appliquer la rotation sur l'axe des Y pour ce qui est du module si je ne m'abuse)

    ça devrait peut-être fonctionner un peu mieux comme ça... ><

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

Discussions similaires

  1. faire correspondre deux fichiers XML
    Par Ya7yaKech dans le forum Windows Forms
    Réponses: 21
    Dernier message: 22/01/2009, 19h25
  2. Réponses: 2
    Dernier message: 12/09/2007, 09h29
  3. faire correspondre deux cellules
    Par ncls1983 dans le forum Excel
    Réponses: 2
    Dernier message: 08/06/2007, 14h34
  4. Problème pour faire bouger deux objets simultanement
    Par LinuxUser dans le forum AWT/Swing
    Réponses: 13
    Dernier message: 22/04/2007, 23h19
  5. pb pour faire correspondre 2 listes de choix
    Par david714 dans le forum Access
    Réponses: 5
    Dernier message: 27/02/2006, 11h12

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