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

API graphiques Discussion :

Calcule matrice de rotation


Sujet :

API graphiques

  1. #1
    Membre régulier
    Calcule matrice de rotation
    Bonjour,

    je ne sais pas trop si mon message et dans la bonne rubrique mais si ce n'est pas le cas je fait confiance au modérateur pour me rediriger.

    je développe actuellement sous QtCreator et avec Qt 5.2.1 une application permettant l'affichage d'objet 3D en OpenGL.

    Je souhaite actuellement permettre à l'utilisateur d'appliquer une rotation à cette objet en sélectionnant puis en effectuant un mouvement de souris, selon l'amplitude et la direction du mouvement une matrice de rotation doit être calculé et appliquer à l'objet.
    et c'est là que mes compétences pèchent un peu mathématiquement parlant.

    J'ai du mal à calculer l'axe de rotation autours du quelle tourner en fonction de la position de la caméra, et la position de l'objet.

    voici ce que j'ai fait, mais mon objet ne suis pas bien le mouvement de la souris et j'ai l'impression que c'est le calcule des axe de rotation qui ne sont pas bon.
    En réalité la rotation lorsque la souris bouge verticalement semble bonne, mais pas la rotation lorsque la souris effectue un mouvement horizontal :
    void Apercu3D::Rotation(QPointF newPos)
    {
    if (elementSelectionner == -1)
    return ;

    QPointF offset = newPos - lastPos;
    QVector3D positionObjet = listeDesObjets.GetObjectByID(elementSelectionner).GetPosition().ToVector3D();
    QVector3D vecteurCameraObjet= cameraSpherique.getPosition() - positionObjet;

    QQuaternion quat = QQuaternion::fromAxisAndAngle(QVector3D(-vecteurCameraObjet.y(),-vecteurCameraObjet.x(),vecteurCameraObjet.z()),offset.x()*15)
    * QQuaternion::fromAxisAndAngle(QVector3D(-vecteurCameraObjet.y(),vecteurCameraObjet.x(),positionObjet.z()),offset.y()*15);

    QVector3D angle = quat.vector();
    listeDesObjets.GetObjectByID(elementSelectionner).SetRotation(CPoint(angle.x(),angle.y(),angle.z()));
    }
    Pourriez vous m'aider à trouver la solution de ce problème qui me semble mathématique?

  2. #2
    Membre éprouvé
    Salut,

    La prochaine fois, pourrais-tu mettre ton code dans la balise CODE, s'il te plait ? Car ce n'est pas très lisible actuellement.

    Juste pour jouer le rabat-joie, si tu codes en français, donnes que des noms en français à tes variables : offset est en anglais par exemple. Bien que le mieux et le bon réflexe de base serait de coder en anglais - au risque de m'attirer les foudres des défenseurs de la programmation en français.

    Venons-en au code. De ce que je vois, tu veux faire tourner l'objet sur lui-même mais pas la caméra autour de lui, c'est bien cela ?

    Quel comportement attends-tu quand tu bouges la souris:
    • horizontalement: rotation de l'objet sur l'axe vertical ( généralement (0,1,0) ) ou rotation de l'objet sur l'axe vertical de la caméra (son axe "up") ?
    • verticalement: rotation de l'objet sur l'axe X ou rotation de l'objet sur l'axe horizontale de la caméra (son axe "right" ou "left") ?


    Généralement, on applique la rotation sur l'axe vertical du monde et sur l'axe horizontale de la caméra.

    En pseudo code:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    float horizontalFactor = mouse.relativeY * Time::timePerFrame;
    float verticalFactor = mouse.relativeX * Time::timePerFrame;
     
    Vector3 right = camera.getRight();
    Vector3 vertical = world.getVertical(); // or Vector3 (0,1,0);
     
    Quaternion rightRotation = Quaternion::AxisAngle(right, horizontalFactor);
    Quaternion verticalRotation = Quaternion::AxisAngle(vertical , verticalFactor );
     
    object.rotate(rightRotation * verticalRotation); // or verticalRotation * rightRotation


    Le timePerFrame est le temps écoulé entre chaque rendu (en secondes. eg: à 60fps, timePerFrame ~= 0.016667s). Cela te permet de donner une animation fluide et constante dans le temps même si l'application rame

    Vérifies si cela te donnes le comportement que tu souhaites.
    «Le management, tel qu’on l’apprend dans les écoles et tel qu’on l’applique ensuite, sous prétexte de «motivation du personnel», organise exactement le contraire, à savoir la démotivation organisée.» - Bernard Stiegler