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 5 of 5

Thread: can't extract correct Euler angles from Euler Angle transformation matrix

  1. #1
    Intern Contributor
    Join Date
    May 2017
    Posts
    80

    can't extract correct Euler angles from Euler Angle transformation matrix

    I successfully combined all (3) Euler angle rotations into one single matrix. It was a learning process as I had to convert it from a 3x3 matrix to a 4x4, a row-major format to a column-major format, then convert it once more by a -1 offset since matrices in computers consider 0,0 the origin. I also checked my work with ::GLM, and with custom written rotations for each axis and their results multiplied together. All the matrices agree with each other.

    Now I need some help. You should be able to extract all 3 Euler angles from the matrix, but my numbers aren't coming up right.
    example:
    Yaw angle:
    atan2(r21,r11)

    This uses the Euler product matrix below (labeled). But all the matrices agree anyway, custom and GLM. When I plug r21 and r11 in I should get a 30 degree angle from which the matrix was generated. I used 3 - 30 degree angles for the Euler product generation. The example extraction here isn't even close (81 degrees).

    Output at very bottom.

    Code :
    using namespace glm;
     
    glm::mat4 Euler_product(float u, float v, float w){
    	 float cu = std::cos(u), cv = std::cos(v), cw = std::cos(w);
    	 float su = std::sin(u), sv = std::sin(v), sw = std::sin(w);
    	 return glm::mat4(
    			 cv * cw, cv * sw, -1 * sv, 0.0f,
    			 (su* sv * cw-cu * sw), (cu * cw) + (su * sv * sw) , su * cv, 0.0f,
    			 (su * sw) + (cu * sv * cw), (cu * sv * sw) - (su * cw), cu*cv, 0.0f,
    			  0.0f, 0.0f, 0.0f, 1.0f);
    }
     
    glm::mat4 rotx(float a){
        float s = std::sin(a);
        float c = std::cos(a);
        return glm::mat4(
              1.0f,0.0f,0.0f,0.0f,
    		  0.0f,c,s, 0.0f,
    		  0.0f, -s,  c, 0.0f,
    		  0.0f,0.0f,0.0f,1.0f );
    };
    glm::mat4 roty(float a) {
        float s = std::sin(a);
        float c = std::cos(a);
        return glm::mat4(
               c, 0.0f,   -s, 0.0f,
            0.0f, 1.0f, 0.0f, 0.0f,
               s, 0.0f,    c, 0.0f,
            0.0f, 0.0f, 0.0f, 1.0f);
    };
     
    glm::mat4 rotz(float a) {
        float s = std::sin(a);
        float c = std::cos(a);
        return glm::mat4(
              c,s,0.0f,0.0f,
    		  -s,c,0.0f,0.0f,
    		  0.0f,0.0f,1.0f,0.0f,
    		  0.0f,0.0f,0.0f,1.0f );
    };
     
     
     
     
    void print_mat_4x4(glm::mat4 &matrix, std::string input_string);
    //void print_vector(glm::vec3 & _vector)
    //{
    //	std::cout<<glm::to_string(_vector)<<std::endl;
    //}
    void print_vector(glm::vec4 & _vector);
    ::GLM rotation product z * y * x
    Code :
    int main()
    {			//GLM
     
    			glm::mat4 glm_rotx = glm::mat4(1.0f);
    			glm_rotx = glm::rotate(glm_rotx, 30.0f, glm::vec3(1,0,0));
    			glm::mat4 glm_roty = glm::mat4(1.0f);
    			glm_roty = glm::rotate(glm_roty, 30.0f, glm::vec3(0,1,0));
    			glm::mat4 glm_rotz = glm::mat4(1.0f);
    			glm_rotz = glm::rotate(glm_rotz, 30.0f, glm::vec3(0,0,1));
    			glm::mat4 prod_xyz_glm = glm::mat4(1.0f);
    			prod_xyz_glm = glm_rotz * glm_roty * glm_rotx;
    			print_mat_4x4(prod_xyz_glm, "GLM calculated xyz Euler product");
    custom code : individual rotations multiplied by each other
    Code :
    //custom
    				glm::mat4 _trans_rotx = glm::mat4(1.0f);
    				_trans_rotx = rotx(30.0f);
     
    				glm::mat4 _trans_roty = glm::mat4(1.0f);
    				_trans_roty = roty(30.0f);
     
    				glm::mat4 _trans_rotz = glm::mat4(1.0f);
    				_trans_rotz = rotz(30.0f);
     
    				mat4 trans_product = glm::mat4(1.0f);
    					trans_product = _trans_rotz * _trans_roty * _trans_rotx;
     
    					print_mat_4x4(trans_product, "Custom code calculated rotational xyz product");
    custom mat "Euler product"
    Code :
    mat4 trans_xyz_custom = glm::mat4(1.0f);
    					trans_xyz_custom = Euler_product(30.0, 30.0, 30.0);
     
    					print_mat_4x4(trans_xyz_custom, "Single rotational xyz matrix custom");
     
    					//float yaw_angle = 0.0f, pitch_angle = 0.0f, roll_angle = 0.0f;
    					std::cout<<"Euler angle extraction:"<<std::endl;
    					//x angle
    					float r21 = trans_xyz_custom[1][0];
    					float r11 = trans_xyz_custom[0][0];
    					float rad_angle_x =atan2(r21,r11) ; //swapped i,j->shifted -1x -1y
    					float deg_angle_x = radianstoDegrees(rad_angle_x);
    					std::cout<<"x angle radians: "<<rad_angle_x<<"\tdegs:"<<deg_angle_x<<std::endl;
    					//y angle radians
    					float r31 = trans_xyz_custom[0][2]; //this was: 02 rj swap, then applied -1x -y1 offset for computer mat tol computer =0,0
    				    float rad_angle_y = -asin(r31);
    				    float deg_angle_y = radianstoDegrees(rad_angle_y);
    				//tol matrix in question = 1,1
    					std::cout<<"y angle radians: "<<rad_angle_y<<"\tdegs: "<<deg_angle_y<<std::endl;
    					//z angle degrees
    					float r32 = trans_xyz_custom[1][2]; //this was: 02 rj swap, then applied -1x -y1 offset for computer mat tol computer =0,0
    					float r33 = trans_xyz_custom[2][2];
    					float rad_angle_z = atan2(r32,r33);
    					float deg_angle_z = radianstoDegrees(rad_angle_z);
    					//res_radians = degreesToRadians(angle_y);//tol matrix in question = 1,1
    					std::cout<<"z angle radians: "<<rad_angle_z<<"\tdegs: "<<deg_angle_z<<std::endl;

    Custom code calculated rotational xyz product
    Code :
    0.0237935	-0.152405	0.988032	0	
    0.302987	-0.940729	-0.152405	0	
    0.952698	0.302987	0.0237935	0	
    0	0	0	1
    Single rotational xyz matrix custom
    Code :
    0.0237935	-0.152405	0.988032	0	
    0.302987	-0.940729	-0.152405	0	
    0.952698	0.302987	0.0237935	0	
    0	0	0	1
    Euler angle extraction:
    Code :
    x angle radians: 1.49243	degs:85.5098
    y angle radians: -1.41593	degs: -81.1266
    z angle radians: -1.41593	degs: -81.1266
    Last edited by technologist; 12-04-2017 at 06:24 PM. Reason: for got to tag it up

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,519
    Quote Originally Posted by technologist View Post
    Code :
    	 return glm::mat4(
    			 cv * cw, cv * sw, -1 * sv, 0.0f,
    			 (su* sv * cw-cu * sw), (cu * cw) + (su * sv * sw) , su * cv, 0.0f,
    			 (su * sw) + (cu * sv * cw), (cu * sv * sw) - (su * cw), cu*cv, 0.0f,
    			  0.0f, 0.0f, 0.0f, 1.0f);

    Code :
    					float r21 = trans_xyz_custom[1][0];
    					float r11 = trans_xyz_custom[0][0];
    					float rad_angle_x =atan2(r21,r11) ; //swapped i,j->shifted -1x -1y
    Note that [1][0] is column 1, row 0. From the code for Euler_product(), this would give you r21=(su* sv * cw-cu * sw). If you had used [0][1], then you'd end up with r21=cv * sw, r11=cv * cw, r21/r11=sw/cw=tan(w).

  3. #3
    Intern Contributor
    Join Date
    May 2017
    Posts
    80

    followup on GLM:: rotation mat z*x*y and ::custom Euler mat angle1,angle2,angle3

    Quote Originally Posted by GClements View Post
    Note that [1][0] is column 1, row 0. From the code for Euler_product(), this would give you r21=(su* sv * cw-cu * sw). If you had used [0][1], then you'd end up with r21=cv * sw, r11=cv * cw, r21/r11=sw/cw=tan(w).
    I've tried using those values. lAlso have gotten little desperate and am trying adjacent values picked from the matrix. Its only a 3x3 and with some random picking I should eventually hit 30 degrees but I am not coming close. The matrices created by ::GLM, and myself, are in agreement so I am at a loss to reconcile.

  4. #4
    Junior Member Newbie
    Join Date
    Dec 2017
    Posts
    9

    something i need to know

    Quote Originally Posted by technologist View Post
    I've tried using those values. lAlso have gotten little desperate and am trying adjacent values picked from the matrix. Its only a 3x3 and with some random picking I should eventually hit 30 degrees but I am not coming close. The matrices created by ::GLM, and myself, are in agreement so I am at a loss to reconcile.
    (su* sv * cw-cu * sw), << was this intended as is or ((su*sv*(cw-cu)*sw))?

  5. #5
    Intern Contributor
    Join Date
    May 2017
    Posts
    80

    Euler matrix question

    Quote Originally Posted by didydriver View Post
    (su* sv * cw-cu * sw), << was this intended as is or ((su*sv*(cw-cu)*sw))?
    Hi,

    This was intended as (su* sv * cw)-(cu * sw) by me, but I reviewed the original matrix and the author(s) didn't bother to include the grouping braces, so I took them off as well.
    Still runs the same though.

    Code :
    lm::mat4 Euler_product(float u, float v, float w){
    	 float cu = std::cos(u), cv = std::cos(v), cw = std::cos(w);
    	 float su = std::sin(u), sv = std::sin(v), sw = std::sin(w);
    	 return glm::mat4(
    			 cv * cw, cv * sw, -1 * sv, 0.0f,
    			 su* sv * cw-cu * sw, cu * cw + su * sv * sw , su * cv, 0.0f,
    			 su * sw + cu * sv * cw, cu * sv * sw - su * cw, cu*cv, 0.0f,
    			  0.0f, 0.0f, 0.0f, 1.0f);

Tags for this Thread

Posting Permissions

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