From d5a0d894915c19199590b32149834351b60e2fd1 Mon Sep 17 00:00:00 2001 From: Antonio Sanchez Date: Wed, 30 Sep 2020 08:21:20 -0700 Subject: [PATCH] Fix alignedbox 32-bit precision test failure. The current `test/geo_alignedbox` tests fail on 32-bit arm due to small floating-point errors. In particular, the following is not guaranteed to hold: ``` IsometryTransform identity = IsometryTransform::Identity(); BoxType transformedC; transformedC.extend(c.transformed(identity)); VERIFY(transformedC.contains(c)); ``` since `c.transformed(identity)` is ever-so-slightly different from `c`. Instead, we replace this test with one that checks an identity transform is within floating-point precision of `c`. Also updated the condition on `AlignedBox::transform(...)` to only accept `Affine`, `AffineCompact`, and `Isometry` modes explicitly. Otherwise, invalid combinations of modes would also incorrectly pass the assertion. --- Eigen/src/Geometry/AlignedBox.h | 8 ++++---- test/geo_alignedbox.cpp | 20 +++++++------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/Eigen/src/Geometry/AlignedBox.h b/Eigen/src/Geometry/AlignedBox.h index f8fb423cb..02f21e3bc 100644 --- a/Eigen/src/Geometry/AlignedBox.h +++ b/Eigen/src/Geometry/AlignedBox.h @@ -46,7 +46,7 @@ #ifndef EIGEN_ALIGNEDBOX_H #define EIGEN_ALIGNEDBOX_H -namespace Eigen { +namespace Eigen { /** \geometry_module \ingroup Geometry_Module * @@ -267,7 +267,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) {return AlignedBox(m_min.cwiseMax(b.m_min), m_max.cwiseMin(b.m_max)); } /** Returns an AlignedBox that is the union of \a b and \c *this. - * \note Merging with an empty box may result in a box bigger than \c *this. + * \note Merging with an empty box may result in a box bigger than \c *this. * \sa extend(const AlignedBox&) */ EIGEN_DEVICE_FUNC inline AlignedBox merged(const AlignedBox& b) const { return AlignedBox(m_min.cwiseMin(b.m_min), m_max.cwiseMax(b.m_max)); } @@ -338,8 +338,8 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) template EIGEN_DEVICE_FUNC inline void transform(const Transform& transform) { - // Projective transform is not (yet) supported - EIGEN_STATIC_ASSERT(Mode != Projective, THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS); + // Only Affine and Isometry transforms are currently supported. + EIGEN_STATIC_ASSERT(Mode == Affine || Mode == AffineCompact || Mode == Isometry, THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS); // Method adapted from FCL src/shape/geometric_shapes_utility.cpp#computeBV(...) // https://github.com/flexible-collision-library/fcl/blob/fcl-0.4/src/shape/geometric_shapes_utility.cpp#L292 diff --git a/test/geo_alignedbox.cpp b/test/geo_alignedbox.cpp index 0a866a961..7ce640d81 100644 --- a/test/geo_alignedbox.cpp +++ b/test/geo_alignedbox.cpp @@ -47,7 +47,7 @@ template void alignedbox(const BoxType& _box) BoxType b0(dim); BoxType b1(VectorType::Random(dim),VectorType::Random(dim)); BoxType b2; - + kill_extra_precision(b1); kill_extra_precision(p0); kill_extra_precision(p1); @@ -69,7 +69,7 @@ template void alignedbox(const BoxType& _box) BoxType box2(VectorType::Random(dim)); box2.extend(VectorType::Random(dim)); - VERIFY(box1.intersects(box2) == !box1.intersection(box2).isEmpty()); + VERIFY(box1.intersects(box2) == !box1.intersection(box2).isEmpty()); // alignment -- make sure there is no memory alignment assertion BoxType *bp0 = new BoxType(dim); @@ -150,11 +150,9 @@ template void alignedboxTranslatable(const BoxType& _box) VERIFY_IS_APPROX((c.min)(), UnitX * Scalar(9)); VERIFY_IS_APPROX((c.max)(), Ones * Scalar(18) + UnitX * Scalar(9)); - // test for roundoff errors - IsometryTransform identity = IsometryTransform::Identity(); - BoxType transformedC; - transformedC.extend(c.transformed(identity)); - VERIFY(transformedC.contains(c)); + // Check identity transform within numerical precision. + BoxType transformedC = c.transformed(IsometryTransform::Identity()); + VERIFY_IS_APPROX(transformedC, c); for (size_t i = 0; i < 10; ++i) { @@ -335,10 +333,6 @@ template void alignedboxNonIntegralRotatabl const Index dim = _box.dim(); const VectorType Zero = VectorType::Zero(); const VectorType Ones = VectorType::Ones(); - const VectorType UnitX = VectorType::UnitX(); - const VectorType UnitY = VectorType::UnitY(); - // this is vector (0, 0, -1, -1, -1, ...), i.e. with zeros at first and second dimensions - const VectorType UnitZ = Ones - UnitX - UnitY; VectorType minPoint = -2 * Ones; minPoint[1] = 1; @@ -365,7 +359,7 @@ template void alignedboxNonIntegralRotatabl cornerBR = tf2 * cornerBR; cornerTL = tf2 * cornerTL; cornerTR = tf2 * cornerTR; - + VectorType minCorner = Ones * Scalar(-2); VectorType maxCorner = Zero; minCorner[0] = (min)((min)(cornerBL[0], cornerBR[0]), (min)(cornerTL[0], cornerTR[0])); @@ -471,7 +465,7 @@ template void alignedboxNonIntegralRotatabl template void alignedboxCastTests(const BoxType& _box) { - // casting + // casting typedef typename BoxType::Scalar Scalar; typedef Matrix VectorType;