This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Issue with taking thRoot of a 4x4 with a 180 degree rotation

Tags: None
(comma "," separated)
magnet
Registered Member
Posts
2
Karma
0
I read the Eigen Topic "***Read before posting***" and posted to Stackexchange.
https://scicomp.stackexchange.com/questions/37074/why-cant-eigen-library-take-the-root-of-a-matrix-that-is-a-180-degree-rotation

My question was downvoted, and the only response was comments about using complex numbers. I'm back here to ask a question about unsupported functions.

I'm using the Eigen Library to take the roots of 4x4 matrices used as 3D transformations for graphics. Given a Matrix4d that appears as follows:
Code: Select all
-1   0  0  0
  0  -1  0  0
  0   0  1  0
  0   0  0  1


Which is a 180 degree rotation around the Z axis. If the square root is taken with the Eigen Library "pow" function (Eigen Library 3.3.9):
Code: Select all

Eigen::Matrix4d input_Ematrix = Eigen::Map<Eigen::Matrix4d>( in_array, 4, 4 );
Eigen::Matrix4d output_Ematrix = input_Ematrix.pow( 0.5 )



The output is:
Code: Select all

  0   0  0  0
  0   0  0  0
  0   0  1  0
  0   0  0  1


Which is not a valid transformation matrix. I'm not interested in using a square root function, as I want to take the nth root for animation.
It wouldn't resolve into one result, but two: Plus and minus 90 degrees around the Z axis. I was expecting one of those.

According to the Eigen-unsupported website, it does use "exp(p log(M))".
Is there some kind of limitation of taking the "log" and "exp" on matrices like this?
andrew-dy
Registered Member
Posts
15
Karma
0
Your matrix is diagonal. To get an arbitrary, non-unique root of a diagonal matrix, take the element-wise roots or powers.
See that sqrt(1) = 1 and sqrt(-1) = +/- i. Then the resulting matrix to your calculation should be +/-i, +/-i, 1, 1 on the diagonals.
Also note that Eigen::Matrix4d is a typedef for Matrix<double, 4, 4>, or a matrix of doubles (approximating real numbers), but i is complex.

You can't store complex/imaginary numbers in an Eigen::Matrix4d,
so your output matrix needs to be like something of type Matrix<std::complex<double>, 4, 4>.

I'm not sure how appropriate complex matrices are for your graphics application (I'm a math guy).
You could also directly generate a rotation from an angle that meets your needs.
magnet
Registered Member
Posts
2
Karma
0
andrew-dy wrote:I'm not sure how appropriate complex matrices are for your graphics application


I can't think of any 3D graphics application that uses complex numbers, as they need all thee dimensions for 3D images. I'm creating this function for a Sketchup utility function, which uses OpenGL as its underlying graphics environment. The fundamental problem I'm having is related to a diagonal matrix in the upper left 3x3 rotation part of the transformation. But, my original problem included translation, and may also involve scaling. Given the following transformation:
Code: Select all

-1  0  0  200
0  -1  0  0
0  0  1  0
0  0  0  1

In column major order, and when applied to another transformation, rotates the object 180 degrees around the Z axis located at position ( 100, 0, 0). For example, if applied to an object at the origin's position of (0,0,0), it would arc and reverse direction, and end up at position (200, 0, 0).

The transformation above would do that in one animation frame. I want to do it in 100 animation frames by taking the 100th root. In addition, I want to take the multiplicative difference between an initial and final pose (I don't mean subtraction), and then take the nth root. I don't know what the rotation is unless I decompose it.
Using the Eigen Library and raising the transformation above to the power of 0.01 results in the following:
Code: Select all

1  0  0  0.049
0  1  0  0
0  0  1  0
0  0  0  1


I was expecting a transformation that rotates 1.8 degrees around the Z axis at point (100,0,0):
Code: Select all

1.000  -0.031  0   0.049
0.031   1.000  0  -3.141
0.000   0.000  1   0
0.000   0.000  0   1

Thanks for your response. It looks like there is a limitation on diagonal matrices when they involve rotation. Knowing that I have developer a work-around. I decompose the transformation, obtain the angle-axis data from the rotation, and if at or near 180 degrees, I set it to something a bit less, like 179.8 degrees. I then reconstruct the rotation with that data, and then recompose the transformation. It will not quite position the final animation frame correctly, but I will follow up with one more frame that puts it at the desired orientation and position.


Bookmarks



Who is online

Registered users: bartoloni, Bing [Bot], Google [Bot], Yahoo [Bot]