By: David Brown  dabhome 
I noticed your matrix to AngleAxis cannot handle matrices that represent
a rotation of 180 degrees (or at least some of them). 
By: Martin Baker 
David, 
By: Martin Baker 
Correction, I just said "These are both special cases where the axis
is not important" which is wrong of course. 
By: Martin Baker  martinbaker 
I've updated the wepage 
Subject: RE: Matrix to Axis Angle singularities
Date: Tuesday 19 April 2005 17:40
From: "David Brown" dabhome
To: martinbaker
Cc: dabhome
Message body follows:
Martin,
Thanks for the quick response. It was very helpful. Also,
thanks for the credit. :) The modification looks good.
I would like to point out a couple of minor nits. Let me know
what you think.
When there is a singularity of 180 degrees you use a sqrt
function on a calculation that could be negative. This can
only happen if one of the values m00, m11, or m22 is > 1,
but this could happen within an epsilon (for example, 
1.000000001).
Also, the if statement for s is not necessary. It cannot be <
0.001, since the singularity if statement would be true.
When I coded it I actually calculated s and used that to
determine if there is a singularity.
Thanks,
David
Subject: RE: Matrix to Axis Angle singularities
Date: Friday 22 April 2005 19:54
From: "David Brown"
To: 'Martin Baker'
Martin,
I took a closer look at the singularity algorithm and found a flaw.
For example the matrix
0 1 0
1 0 0
0 0 1
Should produce the axis angle 0.7071 0.7071 0 180. However, using the
algorithm it produces 0.7071 0.7071 0 180. This is because the results
of a
sqrt can be + or . We therefore have to determine the signs of x, y
and z.
When the angle is 180 there are always two correct answers (x y z 180
and x
y z 180) where x,y and z can be positive or negative. Therefore, you
can
always produce a result where x,y and z are either all positive or only
one
of them is negative. If m01 m02 and m12 are all >= 0 then x,y and z
are all
positive. If any of those numbers are negative then one of x,y or z is
negative.
I think the following code does the trick. What do you think?
if (m01 < 0.001) {
/* x*y is negative */
if (m13 < 0.001) {
/* x*z and y*z is negative, so make y negative */
y = y;
}
else {
/* x*y and y*z is positive, so make x negative */
x = x;
)
}
else {
if (m02 < 0.001) {
/* x*y is positive and x*z is negative, so make z negative */
z = z;
}
}
David
Subject: FW: Matrix to Axis Angle singularities
Date: Friday 22 April 2005 21:28
From: "David Brown"
To: "'Martin Baker'"
In my code below it should be m12 not m13.
Subject: Another minor glitch in singularity case
Date: Friday 22 April 2005 19:58
From: "David Brown"
To: "'Martin Baker'"
Martin,
I almost forgot. I ran into a problem where my test for singularity was
true within epsilon but my test for angle 0 was not. I therefore
accidentally made it 180 when it really was 0. Since once a singularity
has been determined the angle can only be 0 or 180 the test for 0 should be
broadened to make sure a 0 angle does not get treated as 180.
Another case where epsilon is not epsilon is not epsilon. :)
David
Subject: Re: Matrix to Axis Angle singularities
Date: Saturday 23 April 2005 14:43
From: Martin Baker
To: "David Brown"
David,
Its starting to get quite complicated isn't it! I have been trying to
convince myself that your code handles all possibilities correctly,
what I'm
not sure about is; can we deal with all 6 combinations where the axis
is at
45 degrees to two axies (since this produces x,y or z =0).
So I have added a table to show these combinations on the webpage:
https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/
Can we work out an algorithm from this table like this:
if (matrix symmetrical) {
if (identity matrix) return zero angle
// this is 180 deg rotation
calculate axis with positive values
if (x*y = x*z = y*z = 0) return positive values
// rotation about x, y or z axis only
if (two of x*y , x*z and y*z are zero)
if (nonzero one is negative) invert corresponding value
if (x*y , x*z and y*z are all positive) return positive values
if (y*z is positive) invert x
if (x*z is positive) invert y
if (x*y is positive) invert z
}
I have not changed the full code yet, I thought I would see what you think first.
Martin
Subject: RE: Matrix to Axis Angle singularities
Date: Sunday 24 April 2005 10:30
From: "DAB Consulting"
To: "'Martin Baker'"
Yes it is getting complicated! :) You inspired me to really check the whole thing over. I hope this is useful.
The cases you pointed out where two of the three matrix values are zero are not restricted to 45 degrees. All that is required is one of the x, y or z is 0. But, your algorithm still works. My algorithm had a flaw (see below after the chart).
Both of our algorithms have a problem with epsilons. Instead of checking the matrix numbers we should be checking the x, y and z numbers or using a tighter epsilon. I have included a discussion below (after the chart) with modified algorithms (yours and mine).
I created a different chart for the possible x*y, x*z, and y*z permutations.
For most of the permutations you get two x, y, and z results. For all zeros
there are 6 results. For the permutations with one minus and two pluses there
are no solutions. And for the permutations with only one zero there are no solutions
(note: the one zero permutations are not shown in the chart; also see my discussion
about epsilons at the bottom of my email).
The results are color coded based on which negative I use. I picked negative
values that matched my modified algorithm (listed after the chart).
Your algorithm didn't specify which value to make negative in the case of two
zeros.
x  y  z  x*y  x*z  y*z  Notes 
+   +   +   +  +  +  Use positive 
+ 
+ 
  Not possible  
+ 
 
+  Not possible  
 
+ 
+  Not possible  
+   +    +  +      Use z 
+    +  +     +    Use y 
 +  +   +       +  Use x 
      Not possible  
0  + 1  0  0  
0  0  + 1  0  
0  0  0  + 1  
0  0  0  Rotation around an axis. Use positive 1  
0  +   +   0  0  +  Use positive 
+   0  +   0  +  0  Use positive 
+   +   0  +  0  0  Use positive 
0  +    +  0  0    Use z (can be y or z) 
+   0   +  0    0  Use z (can be x or z) 
 +  +   0    0  0  Use x (can be x or y) 
My original algorithm failed to handle the case where x*y and x*z = 0 and
y*z is negative. I modified it to account for this case. I also modified
the epsilons (see discussion after the program). The modifications are in
red.
if (m01 < 0.000001) { /* x*y is negative */ if (m12 < 0.000001) { /* x*z and y*z is negative, so make y negative */ y = y; } else { /* x*y and y*z is positive, so make x negative */ x = x; ) } else { if ((m02 < 0.000001)  (m12 < 0.000001)) { /* x*y is positive and x*z or y*z is negative, so make z negative*/ z = z; } }
Finally, there is a small problem with dealing with epsilons. For example,
if you have an axis {0.01, 0.01, 0.99989999} then the matrix is:
0.9998  0.0002  0.019998 
0.0002  0.9998  0.019998 
0.019998  0.019998  0.9996 
If you use the epsilon of 0.001 then M01 is zero, but M02 and M12 are not.
This is not a legal case. I therefore think you have to use a tighter
epsilon (epsilon*epsilon?) for checking for zero. Either that or check the
values of x, y and z instead.
Using your algorithm but checking x, y and z for zero the algorithm with
some cleanup becomes:
if (matrix symmetrical) { if (identity matrix) return zero angle // this is 180 deg rotation calculate axis with positive values if (x is zero and y,z are not zero) invert y or z else if (y is zero and z is not zero) invert x or z else if (z is zero) invert x or y else if (x*y , x*z and y*z are all positive) return positive values else if (y*z is positive) invert x else if (x*z is positive) invert y else if (x*y is positive) invert z }
What do you think?
David
metadata block 

see also: 

Correspondence about this page  
Book Shop  Further reading. Where I can, I have put links to Amazon for books that are relevant to the subject, click on the appropriate country flag to get more details of the book or to buy it from them. 
Introductory Techniques for 3D Computer Vision by Emanuele Trucco, Alessandro Verri

This site may have errors. Don't use for critical systems.
Copyright (c) 19982021 Martin John Baker  All rights reserved  privacy policy.