The annoying and mysterious Rotation Matrix

  • 13 years ago

    Hi guys,

    I'm halfway on my way to making this rotation matrix work. The problem is I've been on it for about 6 days and I'm completely stumped. You know that stage where you've been staring at the code for so long, and you've tried so many different alternatives, none of which have worked? I've reached that point.

    Essentially, what I have is a GraphicObject which contains a vertex array. The vertex array is essenttially (*)(3) - an array of arrays, each one containing three objects - the x, y and z coordinate. I have a Matrix33f class. I set the value by which I want to rotate the graphicobject's vertices (multiplied by the difference in time between frames so the simulation is hardware independant). I convert from degrees to radians. This is then used to create three rotation matrices - one for each of the x, y and z axes - which are multiplied together to give the rotation about a single arbitrary axis. This is then multipled with each vertex. That's the final manipulation performed on the vertex to rotate it. Rotation takes place about the origin (0, 0, 0).

    Currently, with what I have the graphicobject (actually a Sphere, which has GraphicObject as a base class) simply deforms. It stretches along the axis of rotation off to infinity.

    I've tried Euler angles, quaternions, code samples from sites and nothing I have seems to work. I've emailed lecturers and had an email back saying literally "nothing obvious". So I really dont know what to do at this point. I'm struggling to get to grips with the formatting on this site atm as well...











    /***********************************************************************
    Update the player - This is performed before GraphicObject::Rotate() so that the value to rotate
    by is set
    ***********************************************************************/
    void Player::Update(void)
    {


         // Update dt value

         dt = (float)timer.GetDT();



         float rotationInDegrees = 30.0f;

         float rotationInRadians = rotationInDegrees*dt*(PI/180.0f);

         rotation.xyzw[0] = rotationInRadians;
         rotation.xyzw[1] = rotationInRadians;
         rotation.xyzw[2] = rotationInRadians;

         SetRotation(rotation);
    }
    /*******************************************************************************
    Rotate this graphicobject's vertices
    *******************************************************************************/



    void GraphicObject::Rotate(const float rotateX, const float rotateY, const float rotateZ)
    {




         // Rotation about an arbitrary axis

         Matrix33f rotationMatrixX;
         Matrix33f rotationMatrixY;
         Matrix33f rotationMatrixAll;

         rotationMatrixX.MakeRotationMatrixX(rotation.xyzw[0]);
         rotationMatrixY.MakeRotationMatrixY(rotation.xyzw[1]);
         rotationMatrixAll.MakeRotationMatrixZ(rotation.xyzw[2]);

         rotationMatrixAll.MultiplyThis(rotationMatrixX);
         rotationMatrixAll.MultiplyThis(rotationMatrixY);












         // Update vertices

         Vector3f temp;

         for (int i = 0; i < numberOfVertices; i++)
         {
              temp.Set3f(vertexArray[i][0], vertexArray[i][1], vertexArray[i][2]);
              temp.MultiplyThis33f(rotationMatrixAll);
              vertexArray[i][0] = temp.xyz[0];
              vertexArray[i][1] = temp.xyz[1];
              vertexArray[i][2] = temp.xyz[2];
         }










         // TODO: update normals!

    }
    /*******************************************************************************
    Creates a rotation matrix which vector3fs can be multiplied to rotate around the
    X axis
    *******************************************************************************/




    void Matrix33f::MakeRotationMatrixX(float angle)
    {


         float fCos = cosf(angle);

         float fSin = sinf(angle);
         m[0][0] = 1.0f; m[1][0] = 0.0f; m[2][0] = 0.0f;
         m[0][1] = 0.0f; m[1][1] = fCos; m[2][1] = fSin;
         m[0][2] = 0.0f; m[1][2] = -fSin; m[2][2] = fCos;
    }





    /*******************************************************************************
    Creates a rotation matrix which vector3fs can be multiplied to rotate around the
    Y axis
    *******************************************************************************/




    void Matrix33f::MakeRotationMatrixY(float angle)
    {


         float fCos = cosf(angle);

         float fSin = sinf(angle);
         m[0][0] = fCos; m[1][0] = 0.0f; m[2][0] = -fSin;
         m[0][1] = 0.0f; m[1][1] = 1.0f; m[2][1] = 0.0f;
         m[0][2] = fSin; m[1][2] = 0.0f; m[2][2] = fCos;
    }





    /*******************************************************************************
    Creates a rotation matrix which vector3fs can be multiplied to rotate around the
    Z axis
    *******************************************************************************/




    void Matrix33f::MakeRotationMatrixZ(float angle)
    {


         float fCos = cosf(angle);

         float fSin = sinf(angle);
         m[0][0] = fCos; m[1][0] = fSin; m[2][0] = 0.0f;
         m[0][1] = -fSin; m[1][1] = fCos; m[2][1] = 0.0f;
         m[0][2] = 0.0f; m[1][2] = 0.0f; m[2][2] = 1.0f;
    }
    /*******************************************************************************
    Multiply this Matrix33f by another Matrix33f
    *******************************************************************************/



    void Matrix33f::MultiplyThis(Matrix33f& a)
    {


         // Calculate the dot products

         m[0][0] = m[0][0]*a.m[0][0] + m[0][1]*a.m[1][0] + m[0][2]*a.m[2][0];
         m[1][0] = m[0][0]*a.m[0][1] + m[0][1]*a.m[1][1] + m[0][2]*a.m[2][1];
         m[2][0] = m[0][0]*a.m[0][2] + m[0][1]*a.m[1][2] + m[0][2]*a.m[2][2];

         m[0][1] = m[1][0]*a.m[0][0] + m[1][1]*a.m[1][0] + m[1][2]*a.m[2][0];
         m[1][1] = m[1][0]*a.m[0][1] + m[1][1]*a.m[1][1] + m[1][2]*a.m[2][1];
         m[2][1] = m[1][0]*a.m[0][2] + m[1][1]*a.m[1][2] + m[1][2]*a.m[2][2];

         m[0][2] = m[2][0]*a.m[0][0] + m[2][1]*a.m[1][0] + m[2][2]*a.m[2][0];
         m[1][2] = m[2][0]*a.m[0][1] + m[2][1]*a.m[1][1] + m[2][2]*a.m[2][1];
         m[2][2] = m[2][0]*a.m[0][2] + m[2][1]*a.m[1][2] + m[2][2]*a.m[2][2];
    }
    /*******************************************************************************
    Multiply this vector by a matrix33f
    *******************************************************************************/



    void Vector3f::MultiplyThis33f(Matrix33f& mat)
    {


         xyz[0] = mat.m[0][0]*xyz[0] + mat.m[0][1]*xyz[1] + mat.m[0][2]*xyz[2];
         xyz[1] = mat.m[1][0]*xyz[0] + mat.m[1][1]*xyz[1] + mat.m[1][2]*xyz[2];
         xyz[2] = mat.m[2][0]*xyz[0] + mat.m[2][1]*xyz[1] + mat.m[2][2]*xyz[2];
    }
































Post a reply

No one has replied yet! Why not be the first?

Sign in or Join us (it's free).

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“God could create the world in six days because he didn't have to make it compatible with the previous version.”