bug #1312: Quaternion to AxisAngle conversion now ensures the angle will be in the range [-pi,pi]. This also increases accuracy when q.w is negative.

This commit is contained in:
Gael Guennebaud 2016-09-29 23:23:35 +02:00
parent 33500050c3
commit 3860a0bc8f

View File

@ -158,7 +158,8 @@ typedef AngleAxis<float> AngleAxisf;
typedef AngleAxis<double> AngleAxisd; typedef AngleAxis<double> AngleAxisd;
/** Set \c *this from a \b unit quaternion. /** Set \c *this from a \b unit quaternion.
* The resulting axis is normalized. *
* The resulting axis is normalized, and the the computed angle is in the [-pi,pi] range.
* *
* This function implicitly normalizes the quaternion \a q. * This function implicitly normalizes the quaternion \a q.
*/ */
@ -167,12 +168,16 @@ template<typename QuatDerived>
AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q) AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
{ {
using std::atan2; using std::atan2;
using std::abs;
Scalar n = q.vec().norm(); Scalar n = q.vec().norm();
if(n<NumTraits<Scalar>::epsilon()) if(n<NumTraits<Scalar>::epsilon())
n = q.vec().stableNorm(); n = q.vec().stableNorm();
if (n > Scalar(0))
if (n != Scalar(0))
{ {
m_angle = Scalar(2)*atan2(n, q.w()); m_angle = Scalar(2)*atan2(n, std::abs(q.w()));
if(q.w() < 0)
n = -n;
m_axis = q.vec() / n; m_axis = q.vec() / n;
} }
else else