mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-07-21 20:34:28 +08:00
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.
This commit is contained in:
parent
aeca7a63f4
commit
251ecc0ab9
@ -567,7 +567,7 @@ template<typename Derived> class MatrixBase
|
|||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EvalType cross(const MatrixBase<OtherDerived>& other) const;
|
EvalType cross(const MatrixBase<OtherDerived>& other) const;
|
||||||
EvalType someOrthogonal(void) const;
|
EvalType unitOrthogonal(void) const;
|
||||||
|
|
||||||
#ifdef EIGEN_MATRIXBASE_PLUGIN
|
#ifdef EIGEN_MATRIXBASE_PLUGIN
|
||||||
#include EIGEN_MATRIXBASE_PLUGIN
|
#include EIGEN_MATRIXBASE_PLUGIN
|
||||||
|
@ -47,7 +47,7 @@ MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Derived, int Size = Derived::SizeAtCompileTime>
|
template<typename Derived, int Size = Derived::SizeAtCompileTime>
|
||||||
struct ei_someOrthogonal_selector
|
struct ei_unitOrthogonal_selector
|
||||||
{
|
{
|
||||||
typedef typename ei_eval<Derived>::type VectorType;
|
typedef typename ei_eval<Derived>::type VectorType;
|
||||||
typedef typename ei_traits<Derived>::Scalar Scalar;
|
typedef typename ei_traits<Derived>::Scalar Scalar;
|
||||||
@ -66,7 +66,9 @@ struct ei_someOrthogonal_selector
|
|||||||
|| (!ei_isMuchSmallerThan(src.y(), src.z())))
|
|| (!ei_isMuchSmallerThan(src.y(), src.z())))
|
||||||
{
|
{
|
||||||
RealScalar invnm = Scalar(1)/src.template start<2>().norm();
|
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
|
/* 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.
|
* 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
|
else
|
||||||
{
|
{
|
||||||
RealScalar invnm = Scalar(1)/src.template end<2>().norm();
|
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
|
if( (Derived::SizeAtCompileTime!=Dynamic && Derived::SizeAtCompileTime>3)
|
||||||
|| (Derived::SizeAtCompileTime==Dynamic && src.size()>3))
|
|| (Derived::SizeAtCompileTime==Dynamic && src.size()>3) )
|
||||||
perp.end(src.size()-3).setZero();
|
perp.end(src.size()-3).setZero();
|
||||||
|
|
||||||
return perp;
|
return perp;
|
||||||
@ -86,26 +90,26 @@ struct ei_someOrthogonal_selector
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
struct ei_someOrthogonal_selector<Derived,2>
|
struct ei_unitOrthogonal_selector<Derived,2>
|
||||||
{
|
{
|
||||||
typedef typename ei_eval<Derived>::type VectorType;
|
typedef typename ei_eval<Derived>::type VectorType;
|
||||||
inline static VectorType run(const Derived& src)
|
inline static VectorType run(const Derived& src)
|
||||||
{ return VectorType(-ei_conj(src.y()), ei_conj(src.x())).normalized(); }
|
{ 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,
|
* 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()
|
* \sa cross()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
typename MatrixBase<Derived>::EvalType
|
typename MatrixBase<Derived>::EvalType
|
||||||
MatrixBase<Derived>::someOrthogonal() const
|
MatrixBase<Derived>::unitOrthogonal() const
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
||||||
return ei_someOrthogonal_selector<Derived>::run(derived());
|
return ei_unitOrthogonal_selector<Derived>::run(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // EIGEN_ORTHOMETHODS_H
|
#endif // EIGEN_ORTHOMETHODS_H
|
||||||
|
@ -58,9 +58,12 @@ template<typename Scalar> void geometry(void)
|
|||||||
(v0.cross(v1).cross(v0)).normalized();
|
(v0.cross(v1).cross(v0)).normalized();
|
||||||
VERIFY(m.isUnitary());
|
VERIFY(m.isUnitary());
|
||||||
|
|
||||||
// someOrthogonal
|
// unitOrthogonal
|
||||||
VERIFY_IS_MUCH_SMALLER_THAN(u0.someOrthogonal().dot(u0), Scalar(1));
|
VERIFY_IS_MUCH_SMALLER_THAN(u0.unitOrthogonal().dot(u0), Scalar(1));
|
||||||
VERIFY_IS_MUCH_SMALLER_THAN(v0.someOrthogonal().dot(v0), 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<Scalar>(-M_PI, M_PI), v0.normalized());
|
q1 = AngleAxis(ei_random<Scalar>(-M_PI, M_PI), v0.normalized());
|
||||||
q2 = AngleAxis(ei_random<Scalar>(-M_PI, M_PI), v1.normalized());
|
q2 = AngleAxis(ei_random<Scalar>(-M_PI, M_PI), v1.normalized());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user