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