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>();
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))
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();
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