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

• 12-04-2017, 06:08 PM
technologist
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```
• 12-04-2017, 11:03 PM
GClements
Quote:

Originally Posted by technologist
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).
• 12-05-2017, 05:41 PM
technologist
followup on GLM:: rotation mat z*x*y and ::custom Euler mat angle1,angle2,angle3
Quote:

Originally Posted by GClements
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.
• 12-05-2017, 09:47 PM
didydriver
something i need to know
Quote:

Originally Posted by technologist
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))?
• 12-06-2017, 09:29 AM
technologist
Euler matrix question
Quote:

Originally Posted by didydriver
(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);```