Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef EIGEN_LGSM_ROTATIONS_H
00011 #define EIGEN_LGSM_ROTATIONS_H
00012
00013 template <typename QuatDerived, typename Derived>
00014 inline typename internal::traits<QuatDerived>::PlainObject projectRotation(
00015 const QuaternionBase<QuatDerived>& q,
00016 const MatrixBase<Derived>& n,
00017 typename internal::traits<Derived>::Scalar& theta)
00018 {
00019 typedef typename internal::traits<Derived>::Scalar Scalar;
00020 typedef typename internal::traits<QuatDerived>::PlainObject Quaternion;
00021 typedef Matrix<Scalar, 3, 3> AdjointMatrix;
00022
00023 const AdjointMatrix& R = q.toRotationMatrix();
00024
00025
00026 Scalar tr1 = (R(2,1)-R(1,2))*n[0] + (R(0,2)-R(2,0))*n[1] + (R(1,0)-R(0,1))*n[2];
00027
00028 Scalar tr2 = n[0] * (R(0,0)*n[0]+R(1,0)*n[1]+R(2,0)*n[2])
00029 + n[1] * (R(0,1)*n[0]+R(1,1)*n[1]+R(2,1)*n[2])
00030 + n[2] * (R(0,2)*n[0]+R(1,2)*n[1]+R(2,2)*n[2])
00031 - R(0,0) - R(1,1) - R(2,2);
00032
00033 Scalar alpha = atan2(tr1, tr2);
00034 theta = M_PI - alpha;
00035 Scalar s = sin(theta);
00036 Scalar c = cos(theta);
00037 Scalar ic = 1-c;
00038
00039 AdjointMatrix Rp;
00040 Rp(0,0) = + ic*n[0]*n[0] + c;
00041 Rp(0,1) = -s*n[2] + ic*n[0]*n[1];
00042 Rp(0,2) = s*n[1] + ic*n[0]*n[2];
00043 Rp(1,0) = s*n[2] + ic*n[1]*n[0];
00044 Rp(1,1) = + ic*n[1]*n[1] + c;
00045 Rp(1,2) = -s*n[0] + ic*n[1]*n[2];
00046 Rp(2,0) = -s*n[1] + ic*n[2]*n[0];
00047 Rp(2,1) = s*n[0] + ic*n[2]*n[1];
00048 Rp(2,2) = + ic*n[2]*n[2] + c;
00049
00050 return Quaternion(Rp);
00051 }
00052
00053 template <typename QuatDerived, typename Derived>
00054 inline typename internal::traits<QuatDerived>::PlainObject projectRotation(
00055 const QuaternionBase<QuatDerived>& q,
00056 const MatrixBase<Derived>& v)
00057 {
00058 typename internal::traits<Derived>::Scalar tmp;
00059 return projectRotation(q, v, tmp);
00060 }
00061
00062 template <typename QuatDerived, typename Derived>
00063 inline bool isRotationAround(const QuaternionBase<QuatDerived>& q, const MatrixBase<Derived>& v)
00064 {
00065 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
00066 typedef typename QuaternionBase<QuatDerived>::Scalar Scalar;
00067 AngleAxis<Scalar> aa(q);
00068 return aa.axis().isApprox(v) || aa.axis().isApprox(-v) || aa.angle() == 0;
00069 }
00070
00071 template <typename QuatDerived, typename Derived>
00072 inline typename QuaternionBase<QuatDerived>::Scalar getAngleAround(const QuaternionBase<QuatDerived>& q, const MatrixBase<Derived>& v)
00073 {
00074 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
00075 assert(isRotationAround(q,v));
00076 typedef typename QuaternionBase<QuatDerived>::Scalar Scalar;
00077 AngleAxis<Scalar> aa(q);
00078 return aa.angle()*(aa.axis().dot(v));
00079 }
00080
00081 #endif