Problems with QQuaternion



  • Hello everyboy,

    i want to rotate my object via gui-arows and quaternions. With up and down arrow it should be possible to rotate round the x-axis. with left and right round y and with two other buttons round the z axis.

    I am using opengl in qt. I have achived to rotate the object round every axis via these slot-functions:
    @
    void OpenGLScene::rotate_plus_x()
    {
    OpenGLScene::anglex += 5;
    test->rotation = QQuaternion::fromAxisAndAngle(QVector3D(1,0,0),OpenGLScene::anglex);
    update();

    }

    void OpenGLScene::rotate_minus_x()
    {
    OpenGLScene::anglex -= 5;
    test->rotation = QQuaternion::fromAxisAndAngle(QVector3D(1,0,0),OpenGLScene::anglex);
    update();
    }

    void OpenGLScene::rotate_plus_y()
    {
    OpenGLScene::angley += 5;
    test->rotation = QQuaternion::fromAxisAndAngle(QVector3D(0,1,0),OpenGLScene::angley);
    update();
    }
    @

    In this class my actual rotation is happening.(Where the rotation is multiplied with the modelview matrix)

    @
    QMatrix4x4 matrix;
    matrix.rotate(rotation);
    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();

                glPushMatrix();
                light->drawLight(light->light_rotate_x,light->light_rotate_y,light->light_rotate_z);
    
                gluLookAt(   0,   0, -400,  
                             0,   0,    0,   
                             0,   1,    0);  
                qMultMatrix(matrix);
                object->drawObject(Red,Green,Blue);
                draw->drawAxes();
                glPopMatrix();
    

    @

    (The qmultmatrix function is from the pbuffers-example from the qt-examples.)

    My problem is, that the object is always jumping back to the initial position, when i change the rotation-axis. For instance, when i rotate round the x-axis and afterwards round the y-axis the object starts to rotate from the initial position and not from the newest one.

    I think there might be a problem with how i multiply my matrix with the modelview-matrix. I think i should store the last changed matrix and multiply it with the newest one. How to do that is a mystery to me.
    I have tried several things but nothing is working.

    Maybe you could help me.

    Thanks in Advance



  • You need to do the math. You create a unit matrix and then rotate it according to a certain quaternion -- that is, you're throwing away the previous rotation by assigning them in your slots.

    IIRC the following should provide better results:
    @
    void OpenGLScene::rotate_plus_x()
    {
    OpenGLScene::anglex += 5;
    test->rotation *= QQuaternion::fromAxisAndAngle(QVector3D(1,0,0),OpenGLScene::anglex);
    update();

    }

    void OpenGLScene::rotate_minus_x()
    {
    OpenGLScene::anglex -= 5;
    test->rotation *= QQuaternion::fromAxisAndAngle(QVector3D(1,0,0),OpenGLScene::anglex);
    update();
    }

    void OpenGLScene::rotate_plus_y()
    {
    OpenGLScene::angley += 5;
    test->rotation *= QQuaternion::fromAxisAndAngle(QVector3D(0,1,0),OpenGLScene::angley);
    update();
    }
    @



  • As FranzK says you are resetting your rotation matrices in the rotate_*() functions. Instead of replacing the matrix, calculate another matrix from the quarternion and pre-multiply the pre-existing transformation matrix with it.

    I think the order of the matrix multiplication should be opposite to what Franzk said though (but to be fair I've not tried it myself). For e.g.:

    @
    void OpenGLScene::rotate_plus_x()
    {
    OpenGLScene::anglex += 5;
    QMatrix4x4 newRotation = QQuaternion::fromAxisAndAngle(QVector3D(1,0,0),OpenGLScene::anglex);
    test->rotation = newRotation * test->rotation;
    update();
    }
    @



  • Gah! Sorry ignore my last post I was thinking of matrices not quaternions. Sorry for the confusion. Long day ;-)



  • Thanks to both of you. Especially to FranzK. It was exactly the problem.
    Now its working. One thing was wrong as well.
    It should be:

    @
    OpenGLScene::anglex = 5;
    @
    or
    @
    OpenGLScene::anglex = -5;
    @

    Otherwise the rotationangle gets bigger and bigger with every click.
    For those who are interested.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.