diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h index 32d1499c6..babfc86a9 100644 --- a/Eigen/src/Geometry/Quaternion.h +++ b/Eigen/src/Geometry/Quaternion.h @@ -271,6 +271,8 @@ public: explicit inline Quaternion(const Quaternion& other) { m_coeffs = other.coeffs().template cast(); } + static Quaternion UniformRandom(); + template static Quaternion FromTwoVectors(const MatrixBase& a, const MatrixBase& b); @@ -609,6 +611,26 @@ inline Derived& QuaternionBase::setFromTwoVectors(const MatrixBase +Quaternion Quaternion::UniformRandom() +{ + const Scalar u1 = internal::random(0,1), + u2 = internal::random(0, 2*M_PI), + u3 = internal::random(0, 2*M_PI); + const Scalar a = std::sqrt (1 - u1), + b = std::sqrt (u1); + return Quaternion (a * std::sin (u2), + a * std::cos (u2), + b * std::sin (u3), + b * std::cos (u3)); +} + /** Returns a quaternion representing a rotation between * the two arbitrary vectors \a a and \a b. In other words, the built diff --git a/test/geo_quaternion.cpp b/test/geo_quaternion.cpp index 25130c19a..7c06473a5 100644 --- a/test/geo_quaternion.cpp +++ b/test/geo_quaternion.cpp @@ -50,7 +50,6 @@ template void quaternion(void) using std::abs; typedef Matrix Vector3; typedef Matrix Matrix3; - typedef Matrix Vector4; typedef Quaternion Quaternionx; typedef AngleAxis AngleAxisx; @@ -157,8 +156,8 @@ template void quaternion(void) Quaternionx *q = new Quaternionx; delete q; - q1 = AngleAxisx(a, v0.normalized()); - q2 = AngleAxisx(b, v1.normalized()); + q1 = Quaternionx::UniformRandom (); + q2 = Quaternionx::UniformRandom (); check_slerp(q1,q2); q1 = AngleAxisx(b, v1.normalized()); @@ -169,7 +168,7 @@ template void quaternion(void) q2 = AngleAxisx(-b, -v1.normalized()); check_slerp(q1,q2); - q1.coeffs() = Vector4::Random().normalized(); + q1 = Quaternionx::UniformRandom (); q2.coeffs() = -q1.coeffs(); check_slerp(q1,q2); }