mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-07-21 12:24:25 +08:00
big rework of the Transform class:
* add Projective and AffineCompact modes as an optional third template argument * extend Transform::operator* to support more use cases
This commit is contained in:
parent
7718a8ed83
commit
3ac42fed94
@ -240,11 +240,10 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum TransformTraits {
|
enum TransformTraits {
|
||||||
Affine = 0x1,
|
Isometry = 0x1,
|
||||||
Isometry = 0x2,
|
Affine = 0x2,
|
||||||
AffineSquare = Affine|0x10,
|
AffineCompact = 0x10 | Affine,
|
||||||
AffineCompact = Affine|0x20,
|
Projective = 0x20
|
||||||
Projective = 0x30
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int EiArch_Generic = 0x0;
|
const int EiArch_Generic = 0x0;
|
||||||
|
@ -118,7 +118,7 @@ template<typename Lhs, typename Rhs> class Cross;
|
|||||||
template<typename Scalar> class Quaternion;
|
template<typename Scalar> class Quaternion;
|
||||||
template<typename Scalar> class Rotation2D;
|
template<typename Scalar> class Rotation2D;
|
||||||
template<typename Scalar> class AngleAxis;
|
template<typename Scalar> class AngleAxis;
|
||||||
template<typename Scalar,int Dim/*,int Mode=AffineSquare*/> class Transform;
|
template<typename Scalar,int Dim,int Mode=Affine> class Transform;
|
||||||
template <typename _Scalar, int _AmbientDim> class ParametrizedLine;
|
template <typename _Scalar, int _AmbientDim> class ParametrizedLine;
|
||||||
template <typename _Scalar, int _AmbientDim> class Hyperplane;
|
template <typename _Scalar, int _AmbientDim> class Hyperplane;
|
||||||
template<typename Scalar,int Dim> class Translation;
|
template<typename Scalar,int Dim> class Translation;
|
||||||
|
@ -100,6 +100,26 @@ template<typename MatrixType,int Direction> class Homogeneous
|
|||||||
return ei_homogeneous_left_product_impl<Homogeneous,Lhs>(lhs.derived(),rhs.m_matrix);
|
return ei_homogeneous_left_product_impl<Homogeneous,Lhs>(lhs.derived(),rhs.m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Scalar, int Dim, int Mode> friend
|
||||||
|
inline const ei_homogeneous_left_product_impl<Homogeneous,
|
||||||
|
typename Transform<Scalar,Dim,Mode>::AffinePart>
|
||||||
|
operator* (const Transform<Scalar,Dim,Mode>& tr, const Homogeneous& rhs)
|
||||||
|
{
|
||||||
|
ei_assert(Direction==Vertical);
|
||||||
|
return ei_homogeneous_left_product_impl<Homogeneous,typename Transform<Scalar,Dim,Mode>::AffinePart>
|
||||||
|
(tr.affine(),rhs.m_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Scalar, int Dim> friend
|
||||||
|
inline const ei_homogeneous_left_product_impl<Homogeneous,
|
||||||
|
typename Transform<Scalar,Dim,Projective>::MatrixType>
|
||||||
|
operator* (const Transform<Scalar,Dim,Projective>& tr, const Homogeneous& rhs)
|
||||||
|
{
|
||||||
|
ei_assert(Direction==Vertical);
|
||||||
|
return ei_homogeneous_left_product_impl<Homogeneous,typename Transform<Scalar,Dim,Projective>::MatrixType>
|
||||||
|
(tr.matrix(),rhs.m_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const typename MatrixType::Nested m_matrix;
|
const typename MatrixType::Nested m_matrix;
|
||||||
};
|
};
|
||||||
|
@ -99,8 +99,9 @@ class RotationBase
|
|||||||
inline RotationMatrixType operator*(const MatrixBase<OtherDerived>& l, const Derived& r)
|
inline RotationMatrixType operator*(const MatrixBase<OtherDerived>& l, const Derived& r)
|
||||||
{ return l.derived() * r.toRotationMatrix(); }
|
{ return l.derived() * r.toRotationMatrix(); }
|
||||||
|
|
||||||
/** \returns the concatenation of the rotation \c *this with an affine transformation \a t */
|
/** \returns the concatenation of the rotation \c *this with a transformation \a t */
|
||||||
inline Transform<Scalar,Dim> operator*(const Transform<Scalar,Dim>& t) const
|
template<int Mode>
|
||||||
|
inline Transform<Scalar,Dim,Mode> operator*(const Transform<Scalar,Dim,Mode>& t) const
|
||||||
{ return toRotationMatrix() * t; }
|
{ return toRotationMatrix() * t; }
|
||||||
|
|
||||||
template<typename OtherVectorType>
|
template<typename OtherVectorType>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -53,7 +53,7 @@ public:
|
|||||||
/** corresponding linear transformation matrix type */
|
/** corresponding linear transformation matrix type */
|
||||||
typedef Matrix<Scalar,Dim,Dim> LinearMatrixType;
|
typedef Matrix<Scalar,Dim,Dim> LinearMatrixType;
|
||||||
/** corresponding affine transformation type */
|
/** corresponding affine transformation type */
|
||||||
typedef Transform<Scalar,Dim> TransformType;
|
typedef Transform<Scalar,Dim> AffineTransformType;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -89,23 +89,23 @@ public:
|
|||||||
{ return Translation(m_coeffs + other.m_coeffs); }
|
{ return Translation(m_coeffs + other.m_coeffs); }
|
||||||
|
|
||||||
/** Concatenates a translation and a uniform scaling */
|
/** Concatenates a translation and a uniform scaling */
|
||||||
inline TransformType operator* (const UniformScaling<Scalar>& other) const;
|
inline AffineTransformType operator* (const UniformScaling<Scalar>& other) const;
|
||||||
|
|
||||||
/** Concatenates a translation and a linear transformation */
|
/** Concatenates a translation and a linear transformation */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
inline TransformType operator* (const MatrixBase<OtherDerived>& linear) const;
|
inline AffineTransformType operator* (const MatrixBase<OtherDerived>& linear) const;
|
||||||
|
|
||||||
/** Concatenates a translation and a rotation */
|
/** Concatenates a translation and a rotation */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline TransformType operator*(const RotationBase<Derived,Dim>& r) const
|
inline AffineTransformType operator*(const RotationBase<Derived,Dim>& r) const
|
||||||
{ return *this * r.toRotationMatrix(); }
|
{ return *this * r.toRotationMatrix(); }
|
||||||
|
|
||||||
/** \returns the concatenation of a linear transformation \a l with the translation \a t */
|
/** \returns the concatenation of a linear transformation \a l with the translation \a t */
|
||||||
// its a nightmare to define a templated friend function outside its declaration
|
// its a nightmare to define a templated friend function outside its declaration
|
||||||
template<typename OtherDerived> friend
|
template<typename OtherDerived> friend
|
||||||
inline TransformType operator*(const MatrixBase<OtherDerived>& linear, const Translation& t)
|
inline AffineTransformType operator*(const MatrixBase<OtherDerived>& linear, const Translation& t)
|
||||||
{
|
{
|
||||||
TransformType res;
|
AffineTransformType res;
|
||||||
res.matrix().setZero();
|
res.matrix().setZero();
|
||||||
res.linear() = linear.derived();
|
res.linear() = linear.derived();
|
||||||
res.translation() = linear.derived() * t.m_coeffs;
|
res.translation() = linear.derived() * t.m_coeffs;
|
||||||
@ -115,7 +115,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Concatenates a translation and an affine transformation */
|
/** Concatenates a translation and an affine transformation */
|
||||||
inline TransformType operator* (const TransformType& t) const;
|
template<int Mode>
|
||||||
|
inline Transform<Scalar,Dim,Mode> operator* (const Transform<Scalar,Dim,Mode>& t) const
|
||||||
|
{
|
||||||
|
Transform<Scalar,Dim,Mode> res = t;
|
||||||
|
res.pretranslate(m_coeffs);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/** Applies translation to vector */
|
/** Applies translation to vector */
|
||||||
inline VectorType operator* (const VectorType& other) const
|
inline VectorType operator* (const VectorType& other) const
|
||||||
@ -162,10 +168,10 @@ typedef Translation<double,3> Translation3d;
|
|||||||
//@}
|
//@}
|
||||||
|
|
||||||
template<typename Scalar, int Dim>
|
template<typename Scalar, int Dim>
|
||||||
inline typename Translation<Scalar,Dim>::TransformType
|
inline typename Translation<Scalar,Dim>::AffineTransformType
|
||||||
Translation<Scalar,Dim>::operator* (const UniformScaling<Scalar>& other) const
|
Translation<Scalar,Dim>::operator* (const UniformScaling<Scalar>& other) const
|
||||||
{
|
{
|
||||||
TransformType res;
|
AffineTransformType res;
|
||||||
res.matrix().setZero();
|
res.matrix().setZero();
|
||||||
res.linear().diagonal().fill(other.factor());
|
res.linear().diagonal().fill(other.factor());
|
||||||
res.translation() = m_coeffs;
|
res.translation() = m_coeffs;
|
||||||
@ -175,10 +181,10 @@ Translation<Scalar,Dim>::operator* (const UniformScaling<Scalar>& other) const
|
|||||||
|
|
||||||
template<typename Scalar, int Dim>
|
template<typename Scalar, int Dim>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
inline typename Translation<Scalar,Dim>::TransformType
|
inline typename Translation<Scalar,Dim>::AffineTransformType
|
||||||
Translation<Scalar,Dim>::operator* (const MatrixBase<OtherDerived>& linear) const
|
Translation<Scalar,Dim>::operator* (const MatrixBase<OtherDerived>& linear) const
|
||||||
{
|
{
|
||||||
TransformType res;
|
AffineTransformType res;
|
||||||
res.matrix().setZero();
|
res.matrix().setZero();
|
||||||
res.linear() = linear.derived();
|
res.linear() = linear.derived();
|
||||||
res.translation() = m_coeffs;
|
res.translation() = m_coeffs;
|
||||||
@ -187,13 +193,4 @@ Translation<Scalar,Dim>::operator* (const MatrixBase<OtherDerived>& linear) cons
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Scalar, int Dim>
|
|
||||||
inline typename Translation<Scalar,Dim>::TransformType
|
|
||||||
Translation<Scalar,Dim>::operator* (const TransformType& t) const
|
|
||||||
{
|
|
||||||
TransformType res = t;
|
|
||||||
res.pretranslate(m_coeffs);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EIGEN_TRANSLATION_H
|
#endif // EIGEN_TRANSLATION_H
|
||||||
|
@ -27,12 +27,11 @@
|
|||||||
#include <Eigen/LU>
|
#include <Eigen/LU>
|
||||||
#include <Eigen/SVD>
|
#include <Eigen/SVD>
|
||||||
|
|
||||||
template<typename Scalar> void transformations(void)
|
template<typename Scalar, int Mode> void transformations(void)
|
||||||
{
|
{
|
||||||
/* this test covers the following files:
|
/* this test covers the following files:
|
||||||
Cross.h Quaternion.h, Transform.cpp
|
Cross.h Quaternion.h, Transform.cpp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef Matrix<Scalar,2,2> Matrix2;
|
typedef Matrix<Scalar,2,2> Matrix2;
|
||||||
typedef Matrix<Scalar,3,3> Matrix3;
|
typedef Matrix<Scalar,3,3> Matrix3;
|
||||||
typedef Matrix<Scalar,4,4> Matrix4;
|
typedef Matrix<Scalar,4,4> Matrix4;
|
||||||
@ -41,8 +40,9 @@ template<typename Scalar> void transformations(void)
|
|||||||
typedef Matrix<Scalar,4,1> Vector4;
|
typedef Matrix<Scalar,4,1> Vector4;
|
||||||
typedef Quaternion<Scalar> Quaternionx;
|
typedef Quaternion<Scalar> Quaternionx;
|
||||||
typedef AngleAxis<Scalar> AngleAxisx;
|
typedef AngleAxis<Scalar> AngleAxisx;
|
||||||
typedef Transform<Scalar,2> Transform2;
|
typedef Transform<Scalar,2,Mode> Transform2;
|
||||||
typedef Transform<Scalar,3> Transform3;
|
typedef Transform<Scalar,3,Mode> Transform3;
|
||||||
|
typedef typename Transform3::MatrixType MatrixType;
|
||||||
typedef DiagonalMatrix<Scalar,2> AlignedScaling2;
|
typedef DiagonalMatrix<Scalar,2> AlignedScaling2;
|
||||||
typedef DiagonalMatrix<Scalar,3> AlignedScaling3;
|
typedef DiagonalMatrix<Scalar,3> AlignedScaling3;
|
||||||
typedef Translation<Scalar,2> Translation2;
|
typedef Translation<Scalar,2> Translation2;
|
||||||
@ -111,7 +111,7 @@ template<typename Scalar> void transformations(void)
|
|||||||
t0.scale(v0);
|
t0.scale(v0);
|
||||||
t1.prescale(v0);
|
t1.prescale(v0);
|
||||||
|
|
||||||
VERIFY_IS_APPROX( (t0 * Vector3(1,0,0)).norm(), v0.x());
|
VERIFY_IS_APPROX( (t0 * Vector3(1,0,0)).template start<3>().norm(), v0.x());
|
||||||
//VERIFY(!ei_isApprox((t1 * Vector3(1,0,0)).norm(), v0.x()));
|
//VERIFY(!ei_isApprox((t1 * Vector3(1,0,0)).norm(), v0.x()));
|
||||||
|
|
||||||
t0.setIdentity();
|
t0.setIdentity();
|
||||||
@ -124,7 +124,7 @@ template<typename Scalar> void transformations(void)
|
|||||||
t1.prescale(v1.cwise().inverse());
|
t1.prescale(v1.cwise().inverse());
|
||||||
t1.translate(-v0);
|
t1.translate(-v0);
|
||||||
|
|
||||||
VERIFY((t0.matrix() * t1.matrix()).isIdentity(test_precision<Scalar>()));
|
VERIFY((t0 * t1).matrix().isIdentity(test_precision<Scalar>()));
|
||||||
|
|
||||||
t1.fromPositionOrientationScale(v0, q1, v1);
|
t1.fromPositionOrientationScale(v0, q1, v1);
|
||||||
VERIFY_IS_APPROX(t1.matrix(), t0.matrix());
|
VERIFY_IS_APPROX(t1.matrix(), t0.matrix());
|
||||||
@ -146,7 +146,9 @@ template<typename Scalar> void transformations(void)
|
|||||||
Matrix4 mat4;
|
Matrix4 mat4;
|
||||||
mat4 << mat3 , Vector3::Zero() , Vector4::Zero().transpose();
|
mat4 << mat3 , Vector3::Zero() , Vector4::Zero().transpose();
|
||||||
Transform3 tmat3(mat3), tmat4(mat4);
|
Transform3 tmat3(mat3), tmat4(mat4);
|
||||||
|
if(Mode!=int(AffineCompact))
|
||||||
tmat4.matrix()(3,3) = Scalar(1);
|
tmat4.matrix()(3,3) = Scalar(1);
|
||||||
|
std::cerr << tmat3.matrix() << "\n\n" << tmat4.matrix() << "\n\n";
|
||||||
VERIFY_IS_APPROX(tmat3.matrix(), tmat4.matrix());
|
VERIFY_IS_APPROX(tmat3.matrix(), tmat4.matrix());
|
||||||
|
|
||||||
Scalar a3 = ei_random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
|
Scalar a3 = ei_random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
|
||||||
@ -157,7 +159,7 @@ template<typename Scalar> void transformations(void)
|
|||||||
t4 = aa3;
|
t4 = aa3;
|
||||||
VERIFY_IS_APPROX(t3.matrix(), t4.matrix());
|
VERIFY_IS_APPROX(t3.matrix(), t4.matrix());
|
||||||
t4.rotate(AngleAxisx(-a3,v3));
|
t4.rotate(AngleAxisx(-a3,v3));
|
||||||
VERIFY_IS_APPROX(t4.matrix(), Matrix4::Identity());
|
VERIFY_IS_APPROX(t4.matrix(), MatrixType::Identity());
|
||||||
t4 *= aa3;
|
t4 *= aa3;
|
||||||
VERIFY_IS_APPROX(t3.matrix(), t4.matrix());
|
VERIFY_IS_APPROX(t3.matrix(), t4.matrix());
|
||||||
|
|
||||||
@ -167,7 +169,7 @@ template<typename Scalar> void transformations(void)
|
|||||||
t4 = tv3;
|
t4 = tv3;
|
||||||
VERIFY_IS_APPROX(t5.matrix(), t4.matrix());
|
VERIFY_IS_APPROX(t5.matrix(), t4.matrix());
|
||||||
t4.translate(-v3);
|
t4.translate(-v3);
|
||||||
VERIFY_IS_APPROX(t4.matrix(), Matrix4::Identity());
|
VERIFY_IS_APPROX(t4.matrix(), MatrixType::Identity());
|
||||||
t4 *= tv3;
|
t4 *= tv3;
|
||||||
VERIFY_IS_APPROX(t5.matrix(), t4.matrix());
|
VERIFY_IS_APPROX(t5.matrix(), t4.matrix());
|
||||||
|
|
||||||
@ -176,12 +178,12 @@ template<typename Scalar> void transformations(void)
|
|||||||
t4 = sv3;
|
t4 = sv3;
|
||||||
VERIFY_IS_APPROX(t6.matrix(), t4.matrix());
|
VERIFY_IS_APPROX(t6.matrix(), t4.matrix());
|
||||||
t4.scale(v3.cwise().inverse());
|
t4.scale(v3.cwise().inverse());
|
||||||
VERIFY_IS_APPROX(t4.matrix(), Matrix4::Identity());
|
VERIFY_IS_APPROX(t4.matrix(), MatrixType::Identity());
|
||||||
t4 *= sv3;
|
t4 *= sv3;
|
||||||
VERIFY_IS_APPROX(t6.matrix(), t4.matrix());
|
VERIFY_IS_APPROX(t6.matrix(), t4.matrix());
|
||||||
|
|
||||||
// matrix * transform
|
// matrix * transform
|
||||||
VERIFY_IS_APPROX(Transform3(t3.matrix()*t4).matrix(), Transform3(t3*t4).matrix());
|
VERIFY_IS_APPROX((t3.matrix()*t4).matrix(), (t3*t4).matrix());
|
||||||
|
|
||||||
// chained Transform product
|
// chained Transform product
|
||||||
VERIFY_IS_APPROX(((t3*t4)*t5).matrix(), (t3*(t4*t5)).matrix());
|
VERIFY_IS_APPROX(((t3*t4)*t5).matrix(), (t3*(t4*t5)).matrix());
|
||||||
@ -282,14 +284,16 @@ template<typename Scalar> void transformations(void)
|
|||||||
// translation * vector
|
// translation * vector
|
||||||
t0.setIdentity();
|
t0.setIdentity();
|
||||||
t0.translate(v0);
|
t0.translate(v0);
|
||||||
VERIFY_IS_APPROX(t0 * v1, Translation3(v0) * v1);
|
VERIFY_IS_APPROX((t0 * v1).template start<3>(), Translation3(v0) * v1);
|
||||||
|
|
||||||
// AlignedScaling * vector
|
// AlignedScaling * vector
|
||||||
t0.setIdentity();
|
t0.setIdentity();
|
||||||
t0.scale(v0);
|
t0.scale(v0);
|
||||||
VERIFY_IS_APPROX(t0 * v1, AlignedScaling3(v0) * v1);
|
VERIFY_IS_APPROX((t0 * v1).template start<3>(), AlignedScaling3(v0) * v1);
|
||||||
|
|
||||||
// test transform inversion
|
// test transform inversion
|
||||||
|
if(Mode!=AffineCompact)
|
||||||
|
{
|
||||||
t0.setIdentity();
|
t0.setIdentity();
|
||||||
t0.translate(v0);
|
t0.translate(v0);
|
||||||
t0.linear().setRandom();
|
t0.linear().setRandom();
|
||||||
@ -297,6 +301,7 @@ template<typename Scalar> void transformations(void)
|
|||||||
t0.setIdentity();
|
t0.setIdentity();
|
||||||
t0.translate(v0).rotate(q1);
|
t0.translate(v0).rotate(q1);
|
||||||
VERIFY_IS_APPROX(t0.inverse(Isometry), t0.matrix().inverse());
|
VERIFY_IS_APPROX(t0.inverse(Isometry), t0.matrix().inverse());
|
||||||
|
}
|
||||||
|
|
||||||
// test extract rotation and aligned scaling
|
// test extract rotation and aligned scaling
|
||||||
// t0.setIdentity();
|
// t0.setIdentity();
|
||||||
@ -316,9 +321,9 @@ template<typename Scalar> void transformations(void)
|
|||||||
VERIFY_IS_APPROX(mat_rotation.determinant(), Scalar(1));
|
VERIFY_IS_APPROX(mat_rotation.determinant(), Scalar(1));
|
||||||
|
|
||||||
// test casting
|
// test casting
|
||||||
Transform<float,3> t1f = t1.template cast<float>();
|
Transform<float,3,Mode> t1f = t1.template cast<float>();
|
||||||
VERIFY_IS_APPROX(t1f.template cast<Scalar>(),t1);
|
VERIFY_IS_APPROX(t1f.template cast<Scalar>(),t1);
|
||||||
Transform<double,3> t1d = t1.template cast<double>();
|
Transform<double,3,Mode> t1d = t1.template cast<double>();
|
||||||
VERIFY_IS_APPROX(t1d.template cast<Scalar>(),t1);
|
VERIFY_IS_APPROX(t1d.template cast<Scalar>(),t1);
|
||||||
|
|
||||||
Translation3 tr1(v0);
|
Translation3 tr1(v0);
|
||||||
@ -343,12 +348,15 @@ template<typename Scalar> void transformations(void)
|
|||||||
VERIFY_IS_APPROX(r2d1f.template cast<Scalar>(),r2d1);
|
VERIFY_IS_APPROX(r2d1f.template cast<Scalar>(),r2d1);
|
||||||
Rotation2D<double> r2d1d = r2d1.template cast<double>();
|
Rotation2D<double> r2d1d = r2d1.template cast<double>();
|
||||||
VERIFY_IS_APPROX(r2d1d.template cast<Scalar>(),r2d1);
|
VERIFY_IS_APPROX(r2d1d.template cast<Scalar>(),r2d1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_geo_transformations()
|
void test_geo_transformations()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < g_repeat; i++) {
|
for(int i = 0; i < g_repeat; i++) {
|
||||||
CALL_SUBTEST( transformations<float>() );
|
// CALL_SUBTEST( transformations<float>() );
|
||||||
CALL_SUBTEST( transformations<double>() );
|
CALL_SUBTEST(( transformations<double,Affine>() ));
|
||||||
|
CALL_SUBTEST(( transformations<double,AffineCompact>() ));
|
||||||
|
CALL_SUBTEST(( transformations<double,Projective>() ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user