12 #include <Eigen/Geometry> 25 template<
typename QuatType>
void check_slerp(
const QuatType& q0,
const QuatType& q1)
31 Scalar largeEps = test_precision<Scalar>();
33 Scalar theta_tot = AA(q1*q0.inverse()).angle();
38 QuatType
q = q0.slerp(
t,q1);
39 Scalar theta = AA(q*q0.inverse()).angle();
41 if(theta_tot==0)
VERIFY(theta_tot==0);
42 else VERIFY(
abs(theta -
t * theta_tot) < largeEps);
46 template<
typename Scalar,
int Options>
void quaternion(
void)
57 Scalar largeEps = test_precision<Scalar>();
63 Vector3
v0 = Vector3::Random(),
64 v1 = Vector3::Random(),
65 v2 = Vector3::Random(),
66 v3 = Vector3::Random();
74 VERIFY_IS_APPROX(Quaternionx(Quaternionx::Identity()).coeffs(), q2.coeffs());
75 q1.coeffs().setRandom();
80 std::ostringstream
ss;
82 VERIFY(ss.str() ==
"0i + 0j + 0k + 1");
88 q1 = AngleAxisx(a, v0.normalized());
89 q2 = AngleAxisx(a,
v1.normalized());
92 Scalar refangle =
abs(AngleAxisx(q1.inverse()*q2).angle());
96 if((q1.coeffs()-q2.coeffs()).norm() >
Scalar(10)*largeEps)
104 q1.toRotationMatrix() * q2.toRotationMatrix() *
v2);
107 || !(q2 * q1 * v2).
isApprox(q1.toRotationMatrix() * q2.toRotationMatrix() *
v2));
109 q2 = q1.toRotationMatrix();
114 Quaternionx q3(rot1.transpose()*rot1);
119 AngleAxisx aa = AngleAxisx(q1);
124 if (
abs(aa.angle()) >
Scalar(5)*test_precision<Scalar>()
125 && (aa.axis() - v1.normalized()).norm() <
Scalar(1.99)
126 && (aa.axis() + v1.normalized()).norm() <
Scalar(1.99))
143 VERIFY_IS_APPROX( v2.normalized(),(Quaternionx::FromTwoVectors(v1, v2)*
v1).normalized());
144 VERIFY_IS_APPROX( v1.normalized(),(Quaternionx::FromTwoVectors(v1, v1)*
v1).normalized());
145 VERIFY_IS_APPROX(-v1.normalized(),(Quaternionx::FromTwoVectors(v1,-v1)*
v1).normalized());
164 Quaternionx *
q =
new Quaternionx;
167 q1 = Quaternionx::UnitRandom();
168 q2 = Quaternionx::UnitRandom();
171 q1 = AngleAxisx(
b, v1.normalized());
175 q1 = AngleAxisx(
b, v1.normalized());
176 q2 = AngleAxisx(-
b, -v1.normalized());
179 q1 = Quaternionx::UnitRandom();
180 q2.coeffs() = -q1.coeffs();
187 typedef Map<Quaternion<Scalar> > MQuaternionUA;
188 typedef Map<const Quaternion<Scalar> > MCQuaternionUA;
193 Vector3
v0 = Vector3::Random(),
194 v1 = Vector3::Random();
200 Scalar* array3unaligned = array3+1;
202 MQuaternionA mq1(array1);
203 MCQuaternionA mcq1(array1);
204 MQuaternionA mq2(array2);
205 MQuaternionUA mq3(array3unaligned);
206 MCQuaternionUA mcq3(array3unaligned);
209 mq1 = AngleAxisx(a, v0.normalized());
213 Quaternionx q1 = mq1;
214 Quaternionx q2 = mq2;
215 Quaternionx q3 = mq3;
216 Quaternionx q4 = MCQuaternionUA(array3unaligned);
240 VERIFY_IS_APPROX(mcq3.coeffs().x() + mcq3.coeffs().y() + mcq3.coeffs().z() + mcq3.coeffs().w(), mcq3.coeffs().sum());
241 VERIFY_IS_APPROX(mcq3.x() + mcq3.y() + mcq3.z() + mcq3.w(), mcq3.coeffs().sum());
243 const Quaternionx& cq3(q3);
244 VERIFY( &cq3.x() == &q3.x() );
245 const MQuaternionUA& cmq3(mq3);
246 VERIFY( &cmq3.x() == &mq3.x() );
268 Scalar* arrayunaligned = array3+1;
270 QuaternionA *q1 = ::new(reinterpret_cast<void*>(array1)) QuaternionA;
271 QuaternionUA *q2 = ::new(reinterpret_cast<void*>(array2)) QuaternionUA;
272 QuaternionUA *q3 = ::new(reinterpret_cast<void*>(arrayunaligned)) QuaternionUA;
274 q1->coeffs().setRandom();
296 #if EIGEN_HAS_RVALUE_REFERENCES 299 struct MovableClass {
302 MovableClass() =
default;
303 MovableClass(
const MovableClass&) =
default;
304 MovableClass(MovableClass&&) noexcept =
default;
305 MovableClass& operator=(
const MovableClass&) =
default;
306 MovableClass& operator=(MovableClass&&) =
default;
327 #ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
A matrix or vector expression mapping an existing array of data.
#define CALL_SUBTEST_3(FUNC)
Expression of the transpose of a matrix.
Quaternion< double > Quaterniond
const unsigned int LvalueBit
Jet< T, N > acos(const Jet< T, N > &f)
#define VERIFY_IS_APPROX(a, b)
#define CALL_SUBTEST_1(FUNC)
Array< int, Dynamic, 1 > v
Eigen::Triplet< double > T
Array< double, 1, 3 > e(1./3., 0.5, 2.)
EIGEN_DEVICE_FUNC const Scalar & q
static std::stringstream ss
#define VERIFY_IS_MUCH_SMALLER_THAN(a, b)
The quaternion class used to represent 3D orientations and rotations.
#define VERIFY_IS_NOT_APPROX(a, b)
void check_const_correctness(const PlainObjectType &)
#define CALL_SUBTEST_2(FUNC)
void quaternionAlignment(void)
Map< Matrix< T, Dynamic, Dynamic, ColMajor >, 0, OuterStride<> > matrix(T *data, int rows, int cols, int stride)
EIGEN_DEVICE_FUNC bool isApprox(const Scalar &x, const Scalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
void check_slerp(const QuatType &q0, const QuatType &q1)
Represents a 3D rotation as a rotation angle around an arbitrary 3D axis.
Quaternion< float > Quaternionf
EIGEN_DECLARE_TEST(geo_quaternion)