Fix CIRCLE::Intersect( const SEG& aSeg ) and add unit tests

This commit is contained in:
Roberto Fernandez Bautista 2021-07-25 20:15:22 +01:00
parent 9c15ba9673
commit b6be10f05c
2 changed files with 79 additions and 15 deletions

View File

@ -272,20 +272,8 @@ std::vector<VECTOR2I> CIRCLE::Intersect( const SEG& aSeg ) const
for( VECTOR2I& intersection : IntersectLine( aSeg ) )
{
VECTOR2I delta = aSeg.B - aSeg.A;
if( delta.x > delta.y )
{
if( intersection.x >= std::min( aSeg.A.x, aSeg.B.x )
&& intersection.x <= std::max( aSeg.A.x, aSeg.B.x ) )
retval.push_back( intersection );
}
else
{
if( intersection.y >= std::min( aSeg.A.y, aSeg.B.y )
&& intersection.y <= std::max( aSeg.A.y, aSeg.B.y ) )
retval.push_back( intersection );
}
if( aSeg.Contains( intersection ) )
retval.push_back( intersection );
}
return retval;

View File

@ -327,6 +327,71 @@ struct SEG_SEG_VECPT_CASE
/**
* Test cases for #CIRCLE::Intersect( const SEG& aSeg )
*/
static const std::vector<SEG_SEG_VECPT_CASE> intersect_seg_cases = {
{
"two point aligned",
{ { 0, 0 }, 20 },
{ { 10, -40 }, {10, 40} },
{
{ 10, -17 },
{ 10, 17 },
},
},
{
"two point angled",
{ { 0, 0 }, 20 },
{ { -20, -40 }, {20, 40} },
{
{ 8, 17 },
{ -8, -17 },
},
},
{
"tangent",
{ { 0, 0 }, 20 },
{ { 20, 0 }, {20, 40} },
{
{ 20, 0 }
},
},
{
"no intersection",
{ { 0, 0 }, 20 },
{ { 25, 0 }, {25, 40} },
{
//no points
},
},
{
"no intersection: seg end points inside circle",
{ { 0, 0 }, 20 },
{ { 0, 10 }, {0, -10} },
{
//no points
},
},
};
// clang-format on
BOOST_AUTO_TEST_CASE( Intersect )
{
for( const auto& c : intersect_seg_cases )
{
BOOST_TEST_CONTEXT( c.m_case_name )
{
std::vector<VECTOR2I> ret = c.m_circle.Intersect( c.m_seg );
BOOST_CHECK_EQUAL( c.m_exp_result.size(), ret.size() );
KI_TEST::CheckUnorderedMatches( c.m_exp_result, ret, CompareVector2I );
}
}
}
// clang-format off
/**
* Test cases for #CIRCLE::IntersectLine( const SEG& aSeg )
*/
static const std::vector<SEG_SEG_VECPT_CASE> intersect_line_cases = {
{
"two point aligned",
@ -362,6 +427,15 @@ static const std::vector<SEG_SEG_VECPT_CASE> intersect_line_cases = {
//no points
},
},
{
"intersection, seg end points inside circle",
{ { 0, 0 }, 20 },
{ { 0, 10 }, {0, -10} },
{
{ 0, 20 },
{ 0, -20 }
},
},
};
// clang-format on
@ -372,13 +446,15 @@ BOOST_AUTO_TEST_CASE( IntersectLine )
{
BOOST_TEST_CONTEXT( c.m_case_name )
{
std::vector<VECTOR2I> ret = c.m_circle.Intersect( c.m_seg );
std::vector<VECTOR2I> ret = c.m_circle.IntersectLine( c.m_seg );
BOOST_CHECK_EQUAL( c.m_exp_result.size(), ret.size() );
KI_TEST::CheckUnorderedMatches( c.m_exp_result, ret, CompareVector2I );
}
}
}
/**
* Struct to hold test cases for two lines, a point and an expected returned circle
*/