I'm trying to get rotation values along the x, y and z axis from a matrix that can include rotation, translation and scale data. Currently I have this function to return the y rotational value:

float GetYRotDegree( void )
  return D3DXToDegree( asin( m_mMatrix._13 )  );

What I'm doing to test this is first rotating along the y by 90 degrees, then rotate it by 1 more degree, and this returns 89, not 91.

I understand that this is caused because of using asin, and I did find a Stack Overflow question that was 100% identical to mine, and was solved by doing this:

Degree(atan2(orientmatrix[0][2], orientmatrix[0][0]))

The problem with this is, it assumes that there's no other rotational, scale and translation in the matrix, however I do have other data in it.

Any help would be great, and I do appreciate any help given!


1 Answer 1


You can extract the translation by removing the top three elements of the fourth column, (1,4), (2,4) and (3,4);

You can determine the scale by finding the determinant of the top-left 3x3 elements. The determinant of a plain rotation matrix is 1, so any value above or below that is the scale factor. Note that this is only true for uniform scale; per-axis scale is harder.

Once you determine the scale, you can divide the 3x3 top-left elements of the matrix by that amount. That allows you to solve for θ and the unit vector (l,m,n) by solving this simple system of equations, courtesy of wikipedia:

3D rotation matrix

Keep in mind, this axis-angle form is probably the best you can do. Euler (x, y, z) rotations stack onto each other, which means it may not be possible to separate them once they are combined (this is another facet of the problem that causes gimbal lock). More specifically, there are multiple (infinite?) solutions of Euler rotations to produce a given rotation, so finding the "correct" solution will be difficult.


You could elaborate on why you think you need to get these values from a matrix, and folks could try to offer you a better solution.

P.S. Don't use degrees. Learn radians.

  • \$\begingroup\$ +1. Agree "You could elaborate on why you think you need to get these values from a matrix" \$\endgroup\$
    – concept3d
    May 8, 2013 at 5:04
  • \$\begingroup\$ You can use hypot to get scaling: out[0] = Math.hypot(m11, m12, m13);, out[1] = Math.hypot(m21, m22, m23);, out[2] = Math.hypot(m31, m32, m33); Examples in Qt C++ and JavaScript: stackoverflow.com/a/78244913/4159530 \$\endgroup\$
    – 8Observer8
    Mar 29 at 16:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .