From fd2f399c1839fedc63ea8abe47feae6e42b6ad96 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 26 Mar 2012 18:30:04 +0200 Subject: [PATCH] fix bug #439: add Quaternion::FromTwoVectors() static constructor --- Eigen/src/Geometry/Quaternion.h | 24 ++++++++++++++++++++++++ test/geo_quaternion.cpp | 11 +++++++++++ 2 files changed, 35 insertions(+) diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h index 2da0a541f..0b001ef07 100644 --- a/Eigen/src/Geometry/Quaternion.h +++ b/Eigen/src/Geometry/Quaternion.h @@ -284,6 +284,9 @@ public: explicit inline Quaternion(const Quaternion& other) { m_coeffs = other.coeffs().template cast(); } + template + static Quaternion FromTwoVectors(const MatrixBase& a, const MatrixBase& b); + inline Coefficients& coeffs() { return m_coeffs;} inline const Coefficients& coeffs() const { return m_coeffs;} @@ -624,6 +627,27 @@ inline Derived& QuaternionBase::setFromTwoVectors(const MatrixBase +template +Quaternion Quaternion::FromTwoVectors(const MatrixBase& a, const MatrixBase& b) +{ + Quaternion quat; + quat.setFromTwoVectors(a, b); + return quat; +} + + /** \returns the multiplicative inverse of \c *this * Note that in most cases, i.e., if you simply want the opposite rotation, * and/or the quaternion is normalized, then it is enough to use the conjugate. diff --git a/test/geo_quaternion.cpp b/test/geo_quaternion.cpp index 7adbe0b3d..b73ae9cd4 100644 --- a/test/geo_quaternion.cpp +++ b/test/geo_quaternion.cpp @@ -142,6 +142,17 @@ template void quaternion(void) VERIFY_IS_APPROX(-v3.normalized(),(q2.setFromTwoVectors(v1,-v3)*v1).normalized()); } + // from two vector creation static function + VERIFY_IS_APPROX( v2.normalized(),(Quaternionx::FromTwoVectors(v1, v2)*v1).normalized()); + VERIFY_IS_APPROX( v1.normalized(),(Quaternionx::FromTwoVectors(v1, v1)*v1).normalized()); + VERIFY_IS_APPROX(-v1.normalized(),(Quaternionx::FromTwoVectors(v1,-v1)*v1).normalized()); + if (internal::is_same::value) + { + v3 = (v1.array()+eps).matrix(); + VERIFY_IS_APPROX( v3.normalized(),(Quaternionx::FromTwoVectors(v1, v3)*v1).normalized()); + VERIFY_IS_APPROX(-v3.normalized(),(Quaternionx::FromTwoVectors(v1,-v3)*v1).normalized()); + } + // inverse and conjugate VERIFY_IS_APPROX(q1 * (q1.inverse() * v1), v1); VERIFY_IS_APPROX(q1 * (q1.conjugate() * v1), v1);