#include <r3_rotation.h>
Public Member Functions | |
| axis_and_angle_from_matrix () | |
| Default constructor. Some data members are not initialized! | |
| axis_and_angle_from_matrix (mat3< FloatType > const &r) | |
| Computation of rotation axis and angle. | |
| FloatType | angle (bool deg=false) const |
| Rotation angle in radians or degrees. | |
| mat3< FloatType > | as_matrix () const |
| Reconstructs the rotation matrix using axis_and_angle_as_matrix(). | |
| af::tiny< FloatType, 4 > | as_unit_quaternion () const |
| Returns (q0,q1,q2,q3), where q0 is the scalar part of the unit quaternion. | |
Public Attributes | |
| vec3< FloatType > | axis |
| Normalized rotation axis. | |
| FloatType | angle_rad |
| Rotation angle in radians. | |
The rotation axis is determined by solving the system R-I=0 using row echelon reduction with full pivoting (matrix::row_echelon::full_pivoting_small<>) and back-substitution. R is the input rotation matrix, I the identity matrix.
The rotation angle is determined in three steps. First, the cross product of the normalized axis vector and each basis vector is determined. Each cross product yields a vector perpendicular to the rotation axis, or the null vector if the rotation axis is parallel to one of the basis vectors. The cross product with the largest length is selected for the second step. Let this vector be "perp". It is multiplied with the rotation matrix to yield a second vector "r_perp" which is also perpendicular to the rotation axis. The angle between perp and r_perp is the rotation angle. In the third step, the magnitude of the angle is determined via the scalar product. The sign relative to the rotation axis vector is determined via axis.dot(perp.cross(r_perp)).
The algorithm works reliably for all rotation matrices even if the rotation angle is very small (the corresponding unit test is tst_r3_rotation.py). The accuracy of the results is determined purely by the precision of the floating-point type. In contrast to quaternion-based alternative algorithms (http://skal.planet-d.net/demo/matrixfaq.htm), arbitrary cutoff tolerances are not needed at any stage. At the same time, the algorithm is very fast.
If the input matrix is not a rotation matrix the results are meaningless. To check for this condition, use the as_matrix() member function to reconstruct a rotation matrix and compare with the input matrix element-by-element. Large discrepancies are an indication of an improper input matrix.
1.5.6