From d6f4f3aca0c5dd6e9194bcbd87beb45b4d8c47d4 Mon Sep 17 00:00:00 2001 From: John Beard Date: Wed, 9 Jan 2019 12:01:00 +0000 Subject: [PATCH] Geom: Account for quadrant points in arc bbox calc This means arcs that pass though quadrant points (multiple of 0, 90, 180, 270 degrees) include these points in the bbox. --- common/geometry/shape_arc.cpp | 32 +++++++++++++++++++++++++++ qa/common/geometry/test_shape_arc.cpp | 7 +----- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/common/geometry/shape_arc.cpp b/common/geometry/shape_arc.cpp index 2a596b9b9d..136223d58d 100644 --- a/common/geometry/shape_arc.cpp +++ b/common/geometry/shape_arc.cpp @@ -22,6 +22,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include #include @@ -158,6 +159,37 @@ const BOX2I SHAPE_ARC::BBox( int aClearance ) const points.push_back( m_p0 ); points.push_back( GetP1() ); + double start_angle = GetStartAngle(); + double end_angle = start_angle + GetCentralAngle(); + + // we always count quadrants clockwise (increasing angle) + if( start_angle > end_angle ) + std::swap( start_angle, end_angle ); + + int quad_angle_start = std::ceil( start_angle / 90.0 ); + int quad_angle_end = std::floor( end_angle / 90.0 ); + + // count through quadrants included in arc + for( int quad_angle = quad_angle_start; quad_angle <= quad_angle_end; ++quad_angle ) + { + const int radius = GetRadius(); + VECTOR2I quad_pt = m_pc; + + switch( quad_angle % 4 ) + { + case 0: quad_pt += { radius, 0 }; break; + case 1: + case -3: quad_pt += { 0, radius }; break; + case 2: + case -2: quad_pt += { -radius, 0 }; break; + case 3: + case -1: quad_pt += { 0, -radius }; break; + default: assert( false ); + } + + points.push_back( quad_pt ); + } + bbox.Compute( points ); if( aClearance != 0 ) diff --git a/qa/common/geometry/test_shape_arc.cpp b/qa/common/geometry/test_shape_arc.cpp index 26b82234a8..9bcd5bd795 100644 --- a/qa/common/geometry/test_shape_arc.cpp +++ b/qa/common/geometry/test_shape_arc.cpp @@ -266,10 +266,7 @@ static const std::vector arc_cases = { }, }; -#ifdef HAVE_EXPECTED_FAILURES -// One of the bbox tests fails - -BOOST_AUTO_TEST_CASE( BasicCPAGeom, *boost::unit_test::expected_failures( 6 ) ) +BOOST_AUTO_TEST_CASE( BasicCPAGeom ) { for( const auto& c : arc_cases ) { @@ -284,6 +281,4 @@ BOOST_AUTO_TEST_CASE( BasicCPAGeom, *boost::unit_test::expected_failures( 6 ) ) } } -#endif // HAVE_EXPECTED_FAILURES - BOOST_AUTO_TEST_SUITE_END()