4

Say we have a 4x4 matrix with indices like so:

00 01 02 03
10 11 12 13
20 21 22 23
30 31 32 33

How does one convert the rotation data (ignoring the z axis, if that helps) contained in this matrix into a single 2d rotational angle (in radians)?

Background: I have a 3D .dae animation exported from Blender into the Collada format. The animation is technically 2d, all of the z axis values are 0. I'm trying to convert the 4x4 matrices into 2d translation, rotation and scale data.

Nathanael Weiss
  • 737
  • 1
  • 10
  • 23

2 Answers2

11

Scale matrix S looks like this:

sx 0  0  0
0  sy 0  0
0  0  sz 0
0  0  0  1

Translation matrix T looks like this:

1  0  0  0
0  1  0  0
0  0  1  0
tx ty tz 1

Z-axis rotation matrix Rlooks like this:

 cos(a) sin(a)  0  0
-sin(a) cos(a)  0  0
   0      0     1  0
   0      0     0  1

If you have a transformation matrix M, it is a result of a number of multiplications of R, T and S matrices. Looking at M, the order and number of those multiplications is unknown. However, if we assume that M=S*R*T we can decompose it into separate matrices. Firstly let's calculate S*R*T:

        ( sx*cos(a) sx*sin(a) 0  0)       (m11 m12 m13 m14)
S*R*T = (-sy*sin(a) sy*cos(a) 0  0) = M = (m21 m22 m23 m24)
        (     0         0     sz 0)       (m31 m32 m33 m34)
        (     tx        ty    tz 1)       (m41 m42 m43 m44)

Since we know it's a 2D transformation, getting translation is straightforward:

translation = vector2D(tx, ty) = vector2D(m41, m42)

To calculate rotation and scale, we can use sin(a)^2+cos(a)^2=1:

(m11 / sx)^2 + (m12 / sx)^2 = 1
(m21 / sy)^2 + (m22 / sy)^2 = 1

m11^2 + m12^2 = sx^2
m21^2 + m22^2 = sy^2

sx = sqrt(m11^2 + m12^2)
sy = sqrt(m21^2 + m22^2)

scale = vector2D(sx, sy)

rotation_angle = atan2(sx*m22, sy*m12)
miloszmaki
  • 1,635
  • 15
  • 21
  • The only thing I would add it not avoid `acos` as it disregards the sign of rotation. It is better to use `a=atan2(sx*m22,sy*m12)` or `a=atan2(-sy*m11,sx*m21)`. {I use `atan2(dx,dy)`, but some systems define it as `atan2(dy,dx)` so be careful}. – John Alexiou May 17 '12 at 13:47
  • @ja72: Thank you, I fixed it. It's also convenient to assume that scale is positive while calculating the angle. – miloszmaki May 17 '12 at 14:08
2

this library has routines for converting a 4x4 matrix into its 5 components - rotation, translation, scale, shear, and perspective. You should be able to take the formulas and just drop the 3rd component of the 3d vectors.

jterrace
  • 64,866
  • 22
  • 157
  • 202
  • calculating eigenvalue is really a smart method. – xiaoyi May 17 '12 at 04:30
  • Pros: Looks promising. Cons: Dependent on NumPy, hence, it seems a bit convoluted. Anything similar written in C++? – Nathanael Weiss May 17 '12 at 04:35
  • 1
    The algorithm and an implementation in C are published in (1) Decomposing a matrix into simple transformations. Spencer Thomas. In "Graphics Gems II", pp 320-323. Morgan Kaufmann, 1991. See also (2) Recovering the data from the transformation matrix. Ronald Goldman. In "Graphics Gems II", pp 324-331. Morgan Kaufmann, 1991. – cgohlke May 17 '12 at 06:36
  • I don't know of anything in c/c++ – jterrace May 17 '12 at 13:52