Warning, file /include/eigen3/Eigen/src/Geometry/Quaternion.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef EIGEN_QUATERNION_H
0012 #define EIGEN_QUATERNION_H
0013 namespace Eigen {
0014
0015
0016
0017
0018
0019
0020
0021 namespace internal {
0022 template<typename Other,
0023 int OtherRows=Other::RowsAtCompileTime,
0024 int OtherCols=Other::ColsAtCompileTime>
0025 struct quaternionbase_assign_impl;
0026 }
0027
0028
0029
0030
0031
0032
0033
0034 template<class Derived>
0035 class QuaternionBase : public RotationBase<Derived, 3>
0036 {
0037 public:
0038 typedef RotationBase<Derived, 3> Base;
0039
0040 using Base::operator*;
0041 using Base::derived;
0042
0043 typedef typename internal::traits<Derived>::Scalar Scalar;
0044 typedef typename NumTraits<Scalar>::Real RealScalar;
0045 typedef typename internal::traits<Derived>::Coefficients Coefficients;
0046 typedef typename Coefficients::CoeffReturnType CoeffReturnType;
0047 typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit),
0048 Scalar&, CoeffReturnType>::type NonConstCoeffReturnType;
0049
0050
0051 enum {
0052 Flags = Eigen::internal::traits<Derived>::Flags
0053 };
0054
0055
0056
0057 typedef Matrix<Scalar,3,1> Vector3;
0058
0059 typedef Matrix<Scalar,3,3> Matrix3;
0060
0061 typedef AngleAxis<Scalar> AngleAxisType;
0062
0063
0064
0065
0066 EIGEN_DEVICE_FUNC inline CoeffReturnType x() const { return this->derived().coeffs().coeff(0); }
0067
0068 EIGEN_DEVICE_FUNC inline CoeffReturnType y() const { return this->derived().coeffs().coeff(1); }
0069
0070 EIGEN_DEVICE_FUNC inline CoeffReturnType z() const { return this->derived().coeffs().coeff(2); }
0071
0072 EIGEN_DEVICE_FUNC inline CoeffReturnType w() const { return this->derived().coeffs().coeff(3); }
0073
0074
0075 EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType x() { return this->derived().coeffs().x(); }
0076
0077 EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType y() { return this->derived().coeffs().y(); }
0078
0079 EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType z() { return this->derived().coeffs().z(); }
0080
0081 EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType w() { return this->derived().coeffs().w(); }
0082
0083
0084 EIGEN_DEVICE_FUNC inline const VectorBlock<const Coefficients,3> vec() const { return coeffs().template head<3>(); }
0085
0086
0087 EIGEN_DEVICE_FUNC inline VectorBlock<Coefficients,3> vec() { return coeffs().template head<3>(); }
0088
0089
0090 EIGEN_DEVICE_FUNC inline const typename internal::traits<Derived>::Coefficients& coeffs() const { return derived().coeffs(); }
0091
0092
0093 EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Coefficients& coeffs() { return derived().coeffs(); }
0094
0095 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE QuaternionBase<Derived>& operator=(const QuaternionBase<Derived>& other);
0096 template<class OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const QuaternionBase<OtherDerived>& other);
0097
0098
0099
0100
0101
0102
0103
0104
0105 EIGEN_DEVICE_FUNC Derived& operator=(const AngleAxisType& aa);
0106 template<class OtherDerived> EIGEN_DEVICE_FUNC Derived& operator=(const MatrixBase<OtherDerived>& m);
0107
0108
0109
0110
0111 EIGEN_DEVICE_FUNC static inline Quaternion<Scalar> Identity() { return Quaternion<Scalar>(Scalar(1), Scalar(0), Scalar(0), Scalar(0)); }
0112
0113
0114
0115 EIGEN_DEVICE_FUNC inline QuaternionBase& setIdentity() { coeffs() << Scalar(0), Scalar(0), Scalar(0), Scalar(1); return *this; }
0116
0117
0118
0119
0120 EIGEN_DEVICE_FUNC inline Scalar squaredNorm() const { return coeffs().squaredNorm(); }
0121
0122
0123
0124
0125 EIGEN_DEVICE_FUNC inline Scalar norm() const { return coeffs().norm(); }
0126
0127
0128
0129 EIGEN_DEVICE_FUNC inline void normalize() { coeffs().normalize(); }
0130
0131
0132 EIGEN_DEVICE_FUNC inline Quaternion<Scalar> normalized() const { return Quaternion<Scalar>(coeffs().normalized()); }
0133
0134
0135
0136
0137
0138
0139 template<class OtherDerived> EIGEN_DEVICE_FUNC inline Scalar dot(const QuaternionBase<OtherDerived>& other) const { return coeffs().dot(other.coeffs()); }
0140
0141 template<class OtherDerived> EIGEN_DEVICE_FUNC Scalar angularDistance(const QuaternionBase<OtherDerived>& other) const;
0142
0143
0144 EIGEN_DEVICE_FUNC inline Matrix3 toRotationMatrix() const;
0145
0146
0147 template<typename Derived1, typename Derived2>
0148 EIGEN_DEVICE_FUNC Derived& setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b);
0149
0150 template<class OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Quaternion<Scalar> operator* (const QuaternionBase<OtherDerived>& q) const;
0151 template<class OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator*= (const QuaternionBase<OtherDerived>& q);
0152
0153
0154 EIGEN_DEVICE_FUNC Quaternion<Scalar> inverse() const;
0155
0156
0157 EIGEN_DEVICE_FUNC Quaternion<Scalar> conjugate() const;
0158
0159 template<class OtherDerived> EIGEN_DEVICE_FUNC Quaternion<Scalar> slerp(const Scalar& t, const QuaternionBase<OtherDerived>& other) const;
0160
0161
0162
0163
0164
0165 template<class OtherDerived>
0166 EIGEN_DEVICE_FUNC inline bool operator==(const QuaternionBase<OtherDerived>& other) const
0167 { return coeffs() == other.coeffs(); }
0168
0169
0170
0171
0172
0173 template<class OtherDerived>
0174 EIGEN_DEVICE_FUNC inline bool operator!=(const QuaternionBase<OtherDerived>& other) const
0175 { return coeffs() != other.coeffs(); }
0176
0177
0178
0179
0180
0181 template<class OtherDerived>
0182 EIGEN_DEVICE_FUNC bool isApprox(const QuaternionBase<OtherDerived>& other, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
0183 { return coeffs().isApprox(other.coeffs(), prec); }
0184
0185
0186 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Vector3 _transformVector(const Vector3& v) const;
0187
0188 #ifdef EIGEN_PARSED_BY_DOXYGEN
0189
0190
0191
0192
0193
0194 template<typename NewScalarType>
0195 EIGEN_DEVICE_FUNC inline typename internal::cast_return_type<Derived,Quaternion<NewScalarType> >::type cast() const;
0196
0197 #else
0198
0199 template<typename NewScalarType>
0200 EIGEN_DEVICE_FUNC inline
0201 typename internal::enable_if<internal::is_same<Scalar,NewScalarType>::value,const Derived&>::type cast() const
0202 {
0203 return derived();
0204 }
0205
0206 template<typename NewScalarType>
0207 EIGEN_DEVICE_FUNC inline
0208 typename internal::enable_if<!internal::is_same<Scalar,NewScalarType>::value,Quaternion<NewScalarType> >::type cast() const
0209 {
0210 return Quaternion<NewScalarType>(coeffs().template cast<NewScalarType>());
0211 }
0212 #endif
0213
0214 #ifndef EIGEN_NO_IO
0215 friend std::ostream& operator<<(std::ostream& s, const QuaternionBase<Derived>& q) {
0216 s << q.x() << "i + " << q.y() << "j + " << q.z() << "k" << " + " << q.w();
0217 return s;
0218 }
0219 #endif
0220
0221 #ifdef EIGEN_QUATERNIONBASE_PLUGIN
0222 # include EIGEN_QUATERNIONBASE_PLUGIN
0223 #endif
0224 protected:
0225 EIGEN_DEFAULT_COPY_CONSTRUCTOR(QuaternionBase)
0226 EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(QuaternionBase)
0227 };
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258 namespace internal {
0259 template<typename _Scalar,int _Options>
0260 struct traits<Quaternion<_Scalar,_Options> >
0261 {
0262 typedef Quaternion<_Scalar,_Options> PlainObject;
0263 typedef _Scalar Scalar;
0264 typedef Matrix<_Scalar,4,1,_Options> Coefficients;
0265 enum{
0266 Alignment = internal::traits<Coefficients>::Alignment,
0267 Flags = LvalueBit
0268 };
0269 };
0270 }
0271
0272 template<typename _Scalar, int _Options>
0273 class Quaternion : public QuaternionBase<Quaternion<_Scalar,_Options> >
0274 {
0275 public:
0276 typedef QuaternionBase<Quaternion<_Scalar,_Options> > Base;
0277 enum { NeedsAlignment = internal::traits<Quaternion>::Alignment>0 };
0278
0279 typedef _Scalar Scalar;
0280
0281 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Quaternion)
0282 using Base::operator*=;
0283
0284 typedef typename internal::traits<Quaternion>::Coefficients Coefficients;
0285 typedef typename Base::AngleAxisType AngleAxisType;
0286
0287
0288 EIGEN_DEVICE_FUNC inline Quaternion() {}
0289
0290
0291
0292
0293
0294
0295
0296
0297 EIGEN_DEVICE_FUNC inline Quaternion(const Scalar& w, const Scalar& x, const Scalar& y, const Scalar& z) : m_coeffs(x, y, z, w){}
0298
0299
0300 EIGEN_DEVICE_FUNC explicit inline Quaternion(const Scalar* data) : m_coeffs(data) {}
0301
0302
0303 template<class Derived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Quaternion(const QuaternionBase<Derived>& other) { this->Base::operator=(other); }
0304
0305
0306 EIGEN_DEVICE_FUNC explicit inline Quaternion(const AngleAxisType& aa) { *this = aa; }
0307
0308
0309
0310
0311
0312 template<typename Derived>
0313 EIGEN_DEVICE_FUNC explicit inline Quaternion(const MatrixBase<Derived>& other) { *this = other; }
0314
0315
0316 template<typename OtherScalar, int OtherOptions>
0317 EIGEN_DEVICE_FUNC explicit inline Quaternion(const Quaternion<OtherScalar, OtherOptions>& other)
0318 { m_coeffs = other.coeffs().template cast<Scalar>(); }
0319
0320 #if EIGEN_HAS_RVALUE_REFERENCES
0321
0322
0323 EIGEN_DEVICE_FUNC inline Quaternion(Quaternion&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_constructible<Scalar>::value)
0324 : m_coeffs(std::move(other.coeffs()))
0325 {}
0326
0327
0328 EIGEN_DEVICE_FUNC Quaternion& operator=(Quaternion&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
0329 {
0330 m_coeffs = std::move(other.coeffs());
0331 return *this;
0332 }
0333 #endif
0334
0335 EIGEN_DEVICE_FUNC static Quaternion UnitRandom();
0336
0337 template<typename Derived1, typename Derived2>
0338 EIGEN_DEVICE_FUNC static Quaternion FromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b);
0339
0340 EIGEN_DEVICE_FUNC inline Coefficients& coeffs() { return m_coeffs;}
0341 EIGEN_DEVICE_FUNC inline const Coefficients& coeffs() const { return m_coeffs;}
0342
0343 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool(NeedsAlignment))
0344
0345 #ifdef EIGEN_QUATERNION_PLUGIN
0346 # include EIGEN_QUATERNION_PLUGIN
0347 #endif
0348
0349 protected:
0350 Coefficients m_coeffs;
0351
0352 #ifndef EIGEN_PARSED_BY_DOXYGEN
0353 static EIGEN_STRONG_INLINE void _check_template_params()
0354 {
0355 EIGEN_STATIC_ASSERT( (_Options & DontAlign) == _Options,
0356 INVALID_MATRIX_TEMPLATE_PARAMETERS)
0357 }
0358 #endif
0359 };
0360
0361
0362
0363 typedef Quaternion<float> Quaternionf;
0364
0365
0366 typedef Quaternion<double> Quaterniond;
0367
0368
0369
0370
0371
0372 namespace internal {
0373 template<typename _Scalar, int _Options>
0374 struct traits<Map<Quaternion<_Scalar>, _Options> > : traits<Quaternion<_Scalar, (int(_Options)&Aligned)==Aligned ? AutoAlign : DontAlign> >
0375 {
0376 typedef Map<Matrix<_Scalar,4,1>, _Options> Coefficients;
0377 };
0378 }
0379
0380 namespace internal {
0381 template<typename _Scalar, int _Options>
0382 struct traits<Map<const Quaternion<_Scalar>, _Options> > : traits<Quaternion<_Scalar, (int(_Options)&Aligned)==Aligned ? AutoAlign : DontAlign> >
0383 {
0384 typedef Map<const Matrix<_Scalar,4,1>, _Options> Coefficients;
0385 typedef traits<Quaternion<_Scalar, (int(_Options)&Aligned)==Aligned ? AutoAlign : DontAlign> > TraitsBase;
0386 enum {
0387 Flags = TraitsBase::Flags & ~LvalueBit
0388 };
0389 };
0390 }
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403 template<typename _Scalar, int _Options>
0404 class Map<const Quaternion<_Scalar>, _Options >
0405 : public QuaternionBase<Map<const Quaternion<_Scalar>, _Options> >
0406 {
0407 public:
0408 typedef QuaternionBase<Map<const Quaternion<_Scalar>, _Options> > Base;
0409
0410 typedef _Scalar Scalar;
0411 typedef typename internal::traits<Map>::Coefficients Coefficients;
0412 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
0413 using Base::operator*=;
0414
0415
0416
0417
0418
0419
0420
0421 EIGEN_DEVICE_FUNC explicit EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
0422
0423 EIGEN_DEVICE_FUNC inline const Coefficients& coeffs() const { return m_coeffs;}
0424
0425 protected:
0426 const Coefficients m_coeffs;
0427 };
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440 template<typename _Scalar, int _Options>
0441 class Map<Quaternion<_Scalar>, _Options >
0442 : public QuaternionBase<Map<Quaternion<_Scalar>, _Options> >
0443 {
0444 public:
0445 typedef QuaternionBase<Map<Quaternion<_Scalar>, _Options> > Base;
0446
0447 typedef _Scalar Scalar;
0448 typedef typename internal::traits<Map>::Coefficients Coefficients;
0449 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
0450 using Base::operator*=;
0451
0452
0453
0454
0455
0456
0457
0458 EIGEN_DEVICE_FUNC explicit EIGEN_STRONG_INLINE Map(Scalar* coeffs) : m_coeffs(coeffs) {}
0459
0460 EIGEN_DEVICE_FUNC inline Coefficients& coeffs() { return m_coeffs; }
0461 EIGEN_DEVICE_FUNC inline const Coefficients& coeffs() const { return m_coeffs; }
0462
0463 protected:
0464 Coefficients m_coeffs;
0465 };
0466
0467
0468
0469 typedef Map<Quaternion<float>, 0> QuaternionMapf;
0470
0471
0472 typedef Map<Quaternion<double>, 0> QuaternionMapd;
0473
0474
0475 typedef Map<Quaternion<float>, Aligned> QuaternionMapAlignedf;
0476
0477
0478 typedef Map<Quaternion<double>, Aligned> QuaternionMapAlignedd;
0479
0480
0481
0482
0483
0484
0485
0486 namespace internal {
0487 template<int Arch, class Derived1, class Derived2, typename Scalar> struct quat_product
0488 {
0489 EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){
0490 return Quaternion<Scalar>
0491 (
0492 a.w() * b.w() - a.x() * b.x() - a.y() * b.y() - a.z() * b.z(),
0493 a.w() * b.x() + a.x() * b.w() + a.y() * b.z() - a.z() * b.y(),
0494 a.w() * b.y() + a.y() * b.w() + a.z() * b.x() - a.x() * b.z(),
0495 a.w() * b.z() + a.z() * b.w() + a.x() * b.y() - a.y() * b.x()
0496 );
0497 }
0498 };
0499 }
0500
0501
0502 template <class Derived>
0503 template <class OtherDerived>
0504 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Quaternion<typename internal::traits<Derived>::Scalar>
0505 QuaternionBase<Derived>::operator* (const QuaternionBase<OtherDerived>& other) const
0506 {
0507 EIGEN_STATIC_ASSERT((internal::is_same<typename Derived::Scalar, typename OtherDerived::Scalar>::value),
0508 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
0509 return internal::quat_product<Architecture::Target, Derived, OtherDerived,
0510 typename internal::traits<Derived>::Scalar>::run(*this, other);
0511 }
0512
0513
0514 template <class Derived>
0515 template <class OtherDerived>
0516 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator*= (const QuaternionBase<OtherDerived>& other)
0517 {
0518 derived() = derived() * other.derived();
0519 return derived();
0520 }
0521
0522
0523
0524
0525
0526
0527
0528
0529 template <class Derived>
0530 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename QuaternionBase<Derived>::Vector3
0531 QuaternionBase<Derived>::_transformVector(const Vector3& v) const
0532 {
0533
0534
0535
0536
0537
0538 Vector3 uv = this->vec().cross(v);
0539 uv += uv;
0540 return v + this->w() * uv + this->vec().cross(uv);
0541 }
0542
0543 template<class Derived>
0544 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE QuaternionBase<Derived>& QuaternionBase<Derived>::operator=(const QuaternionBase<Derived>& other)
0545 {
0546 coeffs() = other.coeffs();
0547 return derived();
0548 }
0549
0550 template<class Derived>
0551 template<class OtherDerived>
0552 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator=(const QuaternionBase<OtherDerived>& other)
0553 {
0554 coeffs() = other.coeffs();
0555 return derived();
0556 }
0557
0558
0559
0560 template<class Derived>
0561 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator=(const AngleAxisType& aa)
0562 {
0563 EIGEN_USING_STD(cos)
0564 EIGEN_USING_STD(sin)
0565 Scalar ha = Scalar(0.5)*aa.angle();
0566 this->w() = cos(ha);
0567 this->vec() = sin(ha) * aa.axis();
0568 return derived();
0569 }
0570
0571
0572
0573
0574
0575
0576
0577 template<class Derived>
0578 template<class MatrixDerived>
0579 EIGEN_DEVICE_FUNC inline Derived& QuaternionBase<Derived>::operator=(const MatrixBase<MatrixDerived>& xpr)
0580 {
0581 EIGEN_STATIC_ASSERT((internal::is_same<typename Derived::Scalar, typename MatrixDerived::Scalar>::value),
0582 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
0583 internal::quaternionbase_assign_impl<MatrixDerived>::run(*this, xpr.derived());
0584 return derived();
0585 }
0586
0587
0588
0589
0590 template<class Derived>
0591 EIGEN_DEVICE_FUNC inline typename QuaternionBase<Derived>::Matrix3
0592 QuaternionBase<Derived>::toRotationMatrix(void) const
0593 {
0594
0595
0596
0597
0598 Matrix3 res;
0599
0600 const Scalar tx = Scalar(2)*this->x();
0601 const Scalar ty = Scalar(2)*this->y();
0602 const Scalar tz = Scalar(2)*this->z();
0603 const Scalar twx = tx*this->w();
0604 const Scalar twy = ty*this->w();
0605 const Scalar twz = tz*this->w();
0606 const Scalar txx = tx*this->x();
0607 const Scalar txy = ty*this->x();
0608 const Scalar txz = tz*this->x();
0609 const Scalar tyy = ty*this->y();
0610 const Scalar tyz = tz*this->y();
0611 const Scalar tzz = tz*this->z();
0612
0613 res.coeffRef(0,0) = Scalar(1)-(tyy+tzz);
0614 res.coeffRef(0,1) = txy-twz;
0615 res.coeffRef(0,2) = txz+twy;
0616 res.coeffRef(1,0) = txy+twz;
0617 res.coeffRef(1,1) = Scalar(1)-(txx+tzz);
0618 res.coeffRef(1,2) = tyz-twx;
0619 res.coeffRef(2,0) = txz-twy;
0620 res.coeffRef(2,1) = tyz+twx;
0621 res.coeffRef(2,2) = Scalar(1)-(txx+tyy);
0622
0623 return res;
0624 }
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636 template<class Derived>
0637 template<typename Derived1, typename Derived2>
0638 EIGEN_DEVICE_FUNC inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b)
0639 {
0640 EIGEN_USING_STD(sqrt)
0641 Vector3 v0 = a.normalized();
0642 Vector3 v1 = b.normalized();
0643 Scalar c = v1.dot(v0);
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653 if (c < Scalar(-1)+NumTraits<Scalar>::dummy_precision())
0654 {
0655 c = numext::maxi(c,Scalar(-1));
0656 Matrix<Scalar,2,3> m; m << v0.transpose(), v1.transpose();
0657 JacobiSVD<Matrix<Scalar,2,3> > svd(m, ComputeFullV);
0658 Vector3 axis = svd.matrixV().col(2);
0659
0660 Scalar w2 = (Scalar(1)+c)*Scalar(0.5);
0661 this->w() = sqrt(w2);
0662 this->vec() = axis * sqrt(Scalar(1) - w2);
0663 return derived();
0664 }
0665 Vector3 axis = v0.cross(v1);
0666 Scalar s = sqrt((Scalar(1)+c)*Scalar(2));
0667 Scalar invs = Scalar(1)/s;
0668 this->vec() = axis * invs;
0669 this->w() = s * Scalar(0.5);
0670
0671 return derived();
0672 }
0673
0674
0675
0676
0677
0678 template<typename Scalar, int Options>
0679 EIGEN_DEVICE_FUNC Quaternion<Scalar,Options> Quaternion<Scalar,Options>::UnitRandom()
0680 {
0681 EIGEN_USING_STD(sqrt)
0682 EIGEN_USING_STD(sin)
0683 EIGEN_USING_STD(cos)
0684 const Scalar u1 = internal::random<Scalar>(0, 1),
0685 u2 = internal::random<Scalar>(0, 2*EIGEN_PI),
0686 u3 = internal::random<Scalar>(0, 2*EIGEN_PI);
0687 const Scalar a = sqrt(Scalar(1) - u1),
0688 b = sqrt(u1);
0689 return Quaternion (a * sin(u2), a * cos(u2), b * sin(u3), b * cos(u3));
0690 }
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703 template<typename Scalar, int Options>
0704 template<typename Derived1, typename Derived2>
0705 EIGEN_DEVICE_FUNC Quaternion<Scalar,Options> Quaternion<Scalar,Options>::FromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b)
0706 {
0707 Quaternion quat;
0708 quat.setFromTwoVectors(a, b);
0709 return quat;
0710 }
0711
0712
0713
0714
0715
0716
0717
0718
0719 template <class Derived>
0720 EIGEN_DEVICE_FUNC inline Quaternion<typename internal::traits<Derived>::Scalar> QuaternionBase<Derived>::inverse() const
0721 {
0722
0723 Scalar n2 = this->squaredNorm();
0724 if (n2 > Scalar(0))
0725 return Quaternion<Scalar>(conjugate().coeffs() / n2);
0726 else
0727 {
0728
0729 return Quaternion<Scalar>(Coefficients::Zero());
0730 }
0731 }
0732
0733
0734 namespace internal {
0735 template<int Arch, class Derived, typename Scalar> struct quat_conj
0736 {
0737 EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived>& q){
0738 return Quaternion<Scalar>(q.w(),-q.x(),-q.y(),-q.z());
0739 }
0740 };
0741 }
0742
0743
0744
0745
0746
0747
0748
0749 template <class Derived>
0750 EIGEN_DEVICE_FUNC inline Quaternion<typename internal::traits<Derived>::Scalar>
0751 QuaternionBase<Derived>::conjugate() const
0752 {
0753 return internal::quat_conj<Architecture::Target, Derived,
0754 typename internal::traits<Derived>::Scalar>::run(*this);
0755
0756 }
0757
0758
0759
0760
0761 template <class Derived>
0762 template <class OtherDerived>
0763 EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar
0764 QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& other) const
0765 {
0766 EIGEN_USING_STD(atan2)
0767 Quaternion<Scalar> d = (*this) * other.conjugate();
0768 return Scalar(2) * atan2( d.vec().norm(), numext::abs(d.w()) );
0769 }
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779 template <class Derived>
0780 template <class OtherDerived>
0781 EIGEN_DEVICE_FUNC Quaternion<typename internal::traits<Derived>::Scalar>
0782 QuaternionBase<Derived>::slerp(const Scalar& t, const QuaternionBase<OtherDerived>& other) const
0783 {
0784 EIGEN_USING_STD(acos)
0785 EIGEN_USING_STD(sin)
0786 const Scalar one = Scalar(1) - NumTraits<Scalar>::epsilon();
0787 Scalar d = this->dot(other);
0788 Scalar absD = numext::abs(d);
0789
0790 Scalar scale0;
0791 Scalar scale1;
0792
0793 if(absD>=one)
0794 {
0795 scale0 = Scalar(1) - t;
0796 scale1 = t;
0797 }
0798 else
0799 {
0800
0801 Scalar theta = acos(absD);
0802 Scalar sinTheta = sin(theta);
0803
0804 scale0 = sin( ( Scalar(1) - t ) * theta) / sinTheta;
0805 scale1 = sin( ( t * theta) ) / sinTheta;
0806 }
0807 if(d<Scalar(0)) scale1 = -scale1;
0808
0809 return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
0810 }
0811
0812 namespace internal {
0813
0814
0815 template<typename Other>
0816 struct quaternionbase_assign_impl<Other,3,3>
0817 {
0818 typedef typename Other::Scalar Scalar;
0819 template<class Derived> EIGEN_DEVICE_FUNC static inline void run(QuaternionBase<Derived>& q, const Other& a_mat)
0820 {
0821 const typename internal::nested_eval<Other,2>::type mat(a_mat);
0822 EIGEN_USING_STD(sqrt)
0823
0824
0825 Scalar t = mat.trace();
0826 if (t > Scalar(0))
0827 {
0828 t = sqrt(t + Scalar(1.0));
0829 q.w() = Scalar(0.5)*t;
0830 t = Scalar(0.5)/t;
0831 q.x() = (mat.coeff(2,1) - mat.coeff(1,2)) * t;
0832 q.y() = (mat.coeff(0,2) - mat.coeff(2,0)) * t;
0833 q.z() = (mat.coeff(1,0) - mat.coeff(0,1)) * t;
0834 }
0835 else
0836 {
0837 Index i = 0;
0838 if (mat.coeff(1,1) > mat.coeff(0,0))
0839 i = 1;
0840 if (mat.coeff(2,2) > mat.coeff(i,i))
0841 i = 2;
0842 Index j = (i+1)%3;
0843 Index k = (j+1)%3;
0844
0845 t = sqrt(mat.coeff(i,i)-mat.coeff(j,j)-mat.coeff(k,k) + Scalar(1.0));
0846 q.coeffs().coeffRef(i) = Scalar(0.5) * t;
0847 t = Scalar(0.5)/t;
0848 q.w() = (mat.coeff(k,j)-mat.coeff(j,k))*t;
0849 q.coeffs().coeffRef(j) = (mat.coeff(j,i)+mat.coeff(i,j))*t;
0850 q.coeffs().coeffRef(k) = (mat.coeff(k,i)+mat.coeff(i,k))*t;
0851 }
0852 }
0853 };
0854
0855
0856 template<typename Other>
0857 struct quaternionbase_assign_impl<Other,4,1>
0858 {
0859 typedef typename Other::Scalar Scalar;
0860 template<class Derived> EIGEN_DEVICE_FUNC static inline void run(QuaternionBase<Derived>& q, const Other& vec)
0861 {
0862 q.coeffs() = vec;
0863 }
0864 };
0865
0866 }
0867
0868 }
0869
0870 #endif