From 251ecc0ab9ee7bf923c5212ab93bdf02dc8156d7 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Sun, 24 Aug 2008 17:31:03 +0000 Subject: [PATCH] Rename someOrthogonal to unitOrthogonal. Fix a bug in it, with dyn-size vectors of size <=3. Update doc and test to reflect that it always returns a unit vector. --- Eigen/src/Core/MatrixBase.h | 2 +- Eigen/src/Geometry/OrthoMethods.h | 24 ++++++++++++++---------- test/geometry.cpp | 9 ++++++--- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index c563466b4..dbb481914 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -567,7 +567,7 @@ template class MatrixBase template EvalType cross(const MatrixBase& other) const; - EvalType someOrthogonal(void) const; + EvalType unitOrthogonal(void) const; #ifdef EIGEN_MATRIXBASE_PLUGIN #include EIGEN_MATRIXBASE_PLUGIN diff --git a/Eigen/src/Geometry/OrthoMethods.h b/Eigen/src/Geometry/OrthoMethods.h index 046ca0c88..9ca107541 100644 --- a/Eigen/src/Geometry/OrthoMethods.h +++ b/Eigen/src/Geometry/OrthoMethods.h @@ -47,7 +47,7 @@ MatrixBase::cross(const MatrixBase& other) const } template -struct ei_someOrthogonal_selector +struct ei_unitOrthogonal_selector { typedef typename ei_eval::type VectorType; typedef typename ei_traits::Scalar Scalar; @@ -66,7 +66,9 @@ struct ei_someOrthogonal_selector || (!ei_isMuchSmallerThan(src.y(), src.z()))) { RealScalar invnm = Scalar(1)/src.template start<2>().norm(); - perp.template start<3>() << -ei_conj(src.y())*invnm, ei_conj(src.x())*invnm, 0; + perp.coeffRef(0) = -ei_conj(src.y())*invnm; + perp.coeffRef(1) = ei_conj(src.x())*invnm; + perp.coeffRef(2) = 0; } /* if both x and y are close to zero, then the vector is close * to the z-axis, so it's far from colinear to the x-axis for instance. @@ -75,10 +77,12 @@ struct ei_someOrthogonal_selector else { RealScalar invnm = Scalar(1)/src.template end<2>().norm(); - perp.template start<3>() << 0, -ei_conj(src.z())*invnm, ei_conj(src.y())*invnm; + perp.coeffRef(0) = 0; + perp.coeffRef(1) = -ei_conj(src.z())*invnm; + perp.coeffRef(2) = ei_conj(src.y())*invnm; } - if (Derived::SizeAtCompileTime>3 - || (Derived::SizeAtCompileTime==Dynamic && src.size()>3)) + if( (Derived::SizeAtCompileTime!=Dynamic && Derived::SizeAtCompileTime>3) + || (Derived::SizeAtCompileTime==Dynamic && src.size()>3) ) perp.end(src.size()-3).setZero(); return perp; @@ -86,26 +90,26 @@ struct ei_someOrthogonal_selector }; template -struct ei_someOrthogonal_selector +struct ei_unitOrthogonal_selector { typedef typename ei_eval::type VectorType; inline static VectorType run(const Derived& src) { return VectorType(-ei_conj(src.y()), ei_conj(src.x())).normalized(); } }; -/** \returns an orthogonal vector of \c *this +/** \returns a unit vector which is orthogonal to \c *this * * The size of \c *this must be at least 2. If the size is exactly 2, - * then the returned vector is a counter clock wise rotation of \c *this, i.e., (-y,x). + * then the returned vector is a counter clock wise rotation of \c *this, i.e., (-y,x).normalized(). * * \sa cross() */ template typename MatrixBase::EvalType -MatrixBase::someOrthogonal() const +MatrixBase::unitOrthogonal() const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); - return ei_someOrthogonal_selector::run(derived()); + return ei_unitOrthogonal_selector::run(derived()); } #endif // EIGEN_ORTHOMETHODS_H diff --git a/test/geometry.cpp b/test/geometry.cpp index 82f0a2797..a3876c8d8 100644 --- a/test/geometry.cpp +++ b/test/geometry.cpp @@ -58,9 +58,12 @@ template void geometry(void) (v0.cross(v1).cross(v0)).normalized(); VERIFY(m.isUnitary()); - // someOrthogonal - VERIFY_IS_MUCH_SMALLER_THAN(u0.someOrthogonal().dot(u0), Scalar(1)); - VERIFY_IS_MUCH_SMALLER_THAN(v0.someOrthogonal().dot(v0), Scalar(1)); + // unitOrthogonal + VERIFY_IS_MUCH_SMALLER_THAN(u0.unitOrthogonal().dot(u0), Scalar(1)); + VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1)); + VERIFY_IS_APPROX(u0.unitOrthogonal().norm(), Scalar(1)); + VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), Scalar(1)); + q1 = AngleAxis(ei_random(-M_PI, M_PI), v0.normalized()); q2 = AngleAxis(ei_random(-M_PI, M_PI), v1.normalized());