mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-01-24 14:45:14 +08:00
remove the conceptualy broken "NoShear" transformation traits,
and rename NonAfine => Projective, GenericAffine => Affine, NoScaling => Isometry
This commit is contained in:
parent
6825c8dd6b
commit
49ff9b204c
@ -229,14 +229,11 @@ class Hyperplane
|
||||
}
|
||||
|
||||
template<typename XprType>
|
||||
inline Hyperplane& transform(const MatrixBase<XprType>& mat, TransformTraits traits = GenericAffine)
|
||||
inline Hyperplane& transform(const MatrixBase<XprType>& mat, TransformTraits traits = Affine)
|
||||
{
|
||||
if (traits==GenericAffine)
|
||||
if (traits==Affine)
|
||||
normal() = mat.inverse().transpose() * normal();
|
||||
else if (traits==NoShear)
|
||||
normal() = (mat.colwise().norm2().cwise().inverse().eval().asDiagonal()
|
||||
* mat.transpose()).transpose() * normal();
|
||||
else if (traits==NoScaling)
|
||||
else if (traits==Isometry)
|
||||
normal() = mat * normal();
|
||||
else
|
||||
{
|
||||
@ -246,7 +243,7 @@ class Hyperplane
|
||||
}
|
||||
|
||||
inline Hyperplane& transform(const Transform<Scalar,AmbientDimAtCompileTime>& t,
|
||||
TransformTraits traits = GenericAffine)
|
||||
TransformTraits traits = Affine)
|
||||
{
|
||||
transform(t.linear(), traits);
|
||||
offset() -= t.translation().dot(normal());
|
||||
|
@ -27,10 +27,9 @@
|
||||
|
||||
/** Represents some traits of a transformation */
|
||||
enum TransformTraits {
|
||||
NoScaling, ///< the transformation is a concatenation of translations, rotations
|
||||
NoShear, ///< the transformation is a concatenation of translations, rotations and scalings
|
||||
GenericAffine, ///< the transformation is affine (linear transformation + translation)
|
||||
NonAffine ///< the transformation might not be affine
|
||||
Isometry, ///< the transformation is a concatenation of translations and rotations
|
||||
Affine, ///< the transformation is affine (linear transformation + translation)
|
||||
Projective ///< the transformation might not be affine
|
||||
};
|
||||
|
||||
// Note that we have to pass Dim and HDim because it is not allowed to use a template
|
||||
@ -231,13 +230,13 @@ public:
|
||||
template<typename Derived>
|
||||
inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
|
||||
|
||||
LinearMatrixType extractRotation(TransformTraits traits = GenericAffine) const;
|
||||
LinearMatrixType extractRotation(TransformTraits traits = Affine) const;
|
||||
|
||||
template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
|
||||
Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
|
||||
const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale);
|
||||
|
||||
inline const MatrixType inverse(TransformTraits traits = GenericAffine) const;
|
||||
inline const MatrixType inverse(TransformTraits traits = Affine) const;
|
||||
|
||||
const Scalar* data() const { return m_matrix.data(); }
|
||||
Scalar* data() { return m_matrix.data(); }
|
||||
@ -545,9 +544,8 @@ inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const RotationBase
|
||||
*
|
||||
* \param traits allows to optimize the extraction process when the transformion
|
||||
* is known to be not a general aafine transformation. The possible values are:
|
||||
* - GenericAffine which use a QR decomposition (default),
|
||||
* - NoShear which is the most probable case and very fast,
|
||||
* - NoScaling which simply returns the linear part !
|
||||
* - Affine which use a QR decomposition (default),
|
||||
* - Isometry which simply returns the linear part !
|
||||
*
|
||||
* \warning this function consider the scaling is positive
|
||||
*
|
||||
@ -560,8 +558,8 @@ template<typename Scalar, int Dim>
|
||||
typename Transform<Scalar,Dim>::LinearMatrixType
|
||||
Transform<Scalar,Dim>::extractRotation(TransformTraits traits) const
|
||||
{
|
||||
ei_assert(traits!=NonAffine && "you cannot extract a rotation from a non affine transformation");
|
||||
if (traits == GenericAffine)
|
||||
ei_assert(traits!=Projective && "you cannot extract a rotation from a non affine transformation");
|
||||
if (traits == Affine)
|
||||
{
|
||||
// FIXME maybe QR should be fixed to return a R matrix with a positive diagonal ??
|
||||
QR<LinearMatrixType> qr(linear());
|
||||
@ -572,18 +570,11 @@ Transform<Scalar,Dim>::extractRotation(TransformTraits traits) const
|
||||
matQ.col(i) = -matQ.col(i);
|
||||
return matQ;
|
||||
}
|
||||
else if (traits == NoShear)
|
||||
{
|
||||
// extract linear = rotation * scaling
|
||||
// => rotation = linear * inv(Scaling)
|
||||
VectorType invScaling = linear().colwise().norm().cwise().inverse();
|
||||
return linear() * invScaling.asDiagonal();
|
||||
}
|
||||
else if (traits == NoScaling) // though that's stupid let's handle it !
|
||||
else if (traits == Isometry) // though that's stupid let's handle it !
|
||||
return linear();
|
||||
else
|
||||
{
|
||||
ei_assert("invalid traits value in Transform::inverse()");
|
||||
ei_assert("invalid traits value in Transform::extractRotation()");
|
||||
return LinearMatrixType();
|
||||
}
|
||||
}
|
||||
@ -610,12 +601,10 @@ Transform<Scalar,Dim>::fromPositionOrientationScale(const MatrixBase<PositionDer
|
||||
*
|
||||
* \param traits allows to optimize the inversion process when the transformion
|
||||
* is known to be not a general transformation. The possible values are:
|
||||
* - NonAffine if the transformation is not necessarily affines, i.e., if the
|
||||
* - Projective if the transformation is not necessarily affine, i.e., if the
|
||||
* last row is not guaranteed to be [0 ... 0 1]
|
||||
* - GenericAffine is the default, the last row is assumed to be [0 ... 0 1]
|
||||
* - NoShear if the transformation is only a concatenations of translations,
|
||||
* rotations, and scalings.
|
||||
* - NoScaling if the transformation is only a concatenations of translations
|
||||
* - Affine is the default, the last row is assumed to be [0 ... 0 1]
|
||||
* - Isometry if the transformation is only a concatenations of translations
|
||||
* and rotations.
|
||||
*
|
||||
* \warning unless \a traits is always set to NoShear or NoScaling, this function
|
||||
@ -628,31 +617,18 @@ template<typename Scalar, int Dim>
|
||||
inline const typename Transform<Scalar,Dim>::MatrixType
|
||||
Transform<Scalar,Dim>::inverse(TransformTraits traits) const
|
||||
{
|
||||
if (traits == NonAffine)
|
||||
if (traits == Projective)
|
||||
{
|
||||
return m_matrix.inverse();
|
||||
}
|
||||
else
|
||||
{
|
||||
MatrixType res;
|
||||
if (traits == GenericAffine)
|
||||
if (traits == Affine)
|
||||
{
|
||||
res.template corner<Dim,Dim>(TopLeft) = linear().inverse();
|
||||
}
|
||||
else if (traits == NoShear)
|
||||
{
|
||||
// extract linear = rotation * scaling
|
||||
// then inv(linear) = inv(scaling) * inv(rotation)
|
||||
// = inv(scaling) * trans(rotation)
|
||||
// = inv(scaling) * trans(inv(scaling)) * trans(A)
|
||||
// = inv(scaling) * inv(scaling) * trans(A)
|
||||
// = inv(scaling)^2 * trans(A)
|
||||
// = scaling^-2 * trans(A)
|
||||
// with scaling[i] = A.col(i).norm()
|
||||
VectorType invScaling2 = linear().colwise().norm2().cwise().inverse();
|
||||
res.template corner<Dim,Dim>(TopLeft) = (invScaling2.asDiagonal() * linear().transpose()).lazy();
|
||||
}
|
||||
else if (traits == NoScaling)
|
||||
else if (traits == Isometry)
|
||||
{
|
||||
res.template corner<Dim,Dim>(TopLeft) = linear().transpose();
|
||||
}
|
||||
|
@ -265,19 +265,15 @@ template<typename Scalar> void geometry(void)
|
||||
t0.setIdentity();
|
||||
t0.translate(v0);
|
||||
t0.linear().setRandom();
|
||||
VERIFY_IS_APPROX(t0.inverse(GenericAffine), t0.matrix().inverse());
|
||||
t0.setIdentity();
|
||||
t0.translate(v0).rotate(q1).scale(v1);
|
||||
VERIFY_IS_APPROX(t0.inverse(NoShear), t0.matrix().inverse());
|
||||
VERIFY_IS_APPROX(t0.inverse(Affine), t0.matrix().inverse());
|
||||
t0.setIdentity();
|
||||
t0.translate(v0).rotate(q1);
|
||||
VERIFY_IS_APPROX(t0.inverse(NoScaling), t0.matrix().inverse());
|
||||
VERIFY_IS_APPROX(t0.inverse(Isometry), t0.matrix().inverse());
|
||||
|
||||
// test extract rotation
|
||||
t0.setIdentity();
|
||||
t0.translate(v0).rotate(q1).scale(v1);
|
||||
VERIFY_IS_APPROX(t0.extractRotation(GenericAffine) * v1, Matrix3(q1) * v1);
|
||||
VERIFY_IS_APPROX(t0.extractRotation(NoShear) * v1, Matrix3(q1) * v1);
|
||||
VERIFY_IS_APPROX(t0.extractRotation(Affine) * v1, Matrix3(q1) * v1);
|
||||
}
|
||||
|
||||
void test_geometry()
|
||||
|
@ -71,19 +71,14 @@ template<typename HyperplaneType> void hyperplane(const HyperplaneType& _plane)
|
||||
pl2 = pl1;
|
||||
VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot).absDistance(rot * p1), Scalar(1) );
|
||||
pl2 = pl1;
|
||||
VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot,NoScaling).absDistance(rot * p1), Scalar(1) );
|
||||
VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot,Isometry).absDistance(rot * p1), Scalar(1) );
|
||||
pl2 = pl1;
|
||||
VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*scaling).absDistance((rot*scaling) * p1), Scalar(1) );
|
||||
pl2 = pl1;
|
||||
VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*scaling, NoShear).absDistance((rot*scaling) * p1), Scalar(1) );
|
||||
pl2 = pl1;
|
||||
VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*scaling*translation)
|
||||
.absDistance((rot*scaling*translation) * p1), Scalar(1) );
|
||||
pl2 = pl1;
|
||||
VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*scaling*translation,NoShear)
|
||||
.absDistance((rot*scaling*translation) * p1), Scalar(1) );
|
||||
pl2 = pl1;
|
||||
VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*translation,NoScaling)
|
||||
VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*translation,Isometry)
|
||||
.absDistance((rot*translation) * p1), Scalar(1) );
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user