Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: N-Arbitrary Rotations -> Euler angle shortcut?

Hybrid View

  1. #1
    Intern Newbie
    Join Date
    Apr 2007
    Location
    Ohio
    Posts
    45

    N-Arbitrary Rotations -> Euler angle shortcut?

    Hello all,

    I've tried looking through the posts that have already been made regarding the topic of Euler angles, but I'm not sure if Euler angles are the route to take for my current problem. My project has stalled for about two weeks, so I decided to consult the experts here...

    I have an object that will be rotated an arbitrary number of times around the three principals axes, X, Y and Z, in no particular order. What I need is to extract the outcome from the resulting matrix and apply the transformation, preferably using glRotatef. (I have a somewhat older version of OpenGL, v. 2.0 I believe).

    First off, I found Eberly's function for retrieving the Euler angles, which I'll list here:

    Code :
     
    GLfloat x = 0;
    GLfloat y = 0;
    GLfloat z = 0;
    y = asin(m_matrix[2][0]);
    	if(y < PI/2)
    	{
    		if(y > -PI/2)
    		{
    			x = atan2(-(float)m_matrix[2][1],(float)m_matrix[2][2]);
    			z = atan2(-(float)m_matrix[1][0],(float)m_matrix[0][0]);
    		}
    		else
    		{
    			// not a unique solution
    			x = -atan2((float)m_matrix[0][1],(float)m_matrix[1][1]);
    			z = 0;
    		}
    	}
    	else
    	{
    		// not a unique solution
    		x = atan2((float)m_matrix[0][1],(float)m_matrix[1][1]);
    		z = 0;
    	}
    x = x*180/PI;
    	y = y*180/PI;
     z = z*180/PI;

    The matrix is:
    |[0][0] [0][1] [0][2] [0][3]|
    |[1][0] [1][1] [1][2] [1][3]|
    |[2][0] [2][1] [2][2] [2][3]|
    |[3][0] [3][1] [3][2] [3][3]|

    They are all GLfloat values.

    As far as I know, the angles that are being extracted using this function are the correct angles. I tested it by making single axis rotations, one at a time. At least as far as those tests go, the angles are correct.

    In either case, once I have the Euler angles, I implement the transformation of the object using:

    Code :
    glPushMatrix();
        glRotatef(x,1,0,0); 
        glRotatef(y,0,1,0);
        glRotatef(z,0,0,1);
     
        // ... draw object
    glPopMatrix();

    For as long as my series of arbitrary rotations are restricted to one axis (for instance, a bunch of rotations around the z-axis, say), this Euler angle approach works. As soon as I start adding rotations around the other axis, the object rotates incorrectly.

    The first question I'd like to ask is a conceptual one: Is this the reasonable route to take to achieve the goal? The goal, to (hopefully) be clear, is: perform n-number of arbitrary X,Y,Z rotations, pull the Euler angles from the final matrix, and then use the Euler's angles to achieve the net result of the n-number of arbitrary rotations.

    Your help will be greatly appreciated!

  2. #2
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    490
    Quote Originally Posted by paradoxresolved View Post
    For as long as my series of arbitrary rotations are restricted to one axis (for instance, a bunch of rotations around the z-axis, say), this Euler angle approach works. As soon as I start adding rotations around the other axis, the object rotates incorrectly.
    Where is the matrix coming from? Your code is correct for a matrix in row-major order, but OpenGL uses column-major order.

    Quote Originally Posted by paradoxresolved View Post
    The first question I'd like to ask is a conceptual one: Is this the reasonable route to take to achieve the goal? The goal, to (hopefully) be clear, is: perform n-number of arbitrary X,Y,Z rotations, pull the Euler angles from the final matrix, and then use the Euler's angles to achieve the net result of the n-number of arbitrary rotations.
    Why do you want to use Euler angles? If you're just trying to "compress" an orthonormal matrix into three parameters, the axis-and-angle form used by glRotate() can be reduced to 3 parameters by scaling the axis by the angle. Converting this representation back to a matrix is less work than generating three separate matrices then multiplying them.

  3. #3
    Intern Newbie
    Join Date
    Apr 2007
    Location
    Ohio
    Posts
    45
    The matrix is generated separate from OpenGL. For a variety of reasons, I keep a history of the transformations separate from OpenGL, for now anyway.

    I have decided to switch to quaternions in order to try to solve this problem. Unfortunately, I'm getting the exact same result. Rotating along one axis is fine, but as soon as I start rotating around a separate axis, things get screwy. I'm going to need to put some more research into this.

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,184
    paradoxresolved, either of these is possible (decompose to euler rot or decompose to quaternion). You just have to have a working "matrixToEuler()" or "matrixToQuat()" function.

    Here are some links for the quat case:

    * http://www.euclideanspace.com/maths/...nion/index.htm
    * http://www.geometrictools.com/LibMat...Quaternion.inl

    Main thing is you need an alg that's resilient in the face of the basis vectors getting either slightly denormalized and/or slightly out of orthogonal w.r.t. each other.

    Note that an even better solution is to just composite the rotation using quaternions and not even mess with matrices. More efficient that way too.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •