From f2925dc6cbd147b66fb712ba0c695b4955f5b914 Mon Sep 17 00:00:00 2001 From: Roberto Fernandez Bautista Date: Sun, 11 Jul 2021 22:35:53 +0100 Subject: [PATCH] Added a few more test cases --- qa/libs/kimath/geometry/test_shape_arc.cpp | 124 +++++++++++++++++++++ qa/pns/playground.cpp | 60 +++++----- qa/pns/pns_log_viewer.cpp | 10 ++ 3 files changed, 168 insertions(+), 26 deletions(-) diff --git a/qa/libs/kimath/geometry/test_shape_arc.cpp b/qa/libs/kimath/geometry/test_shape_arc.cpp index c787ebea1f..e309fba28a 100644 --- a/qa/libs/kimath/geometry/test_shape_arc.cpp +++ b/qa/libs/kimath/geometry/test_shape_arc.cpp @@ -21,6 +21,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include #include @@ -626,6 +627,129 @@ BOOST_AUTO_TEST_CASE( CollidePt ) } +struct ARC_DATA_MM +{ + // Coordinates and dimensions in millimeters + double m_center_x; + double m_center_y; + double m_start_x; + double m_start_y; + double m_center_angle; + double m_width; + + SHAPE_ARC GenerateArc() const + { + SHAPE_ARC arc( VECTOR2D( PcbMillimeter2iu( m_center_x ), PcbMillimeter2iu( m_center_y ) ), + VECTOR2D( PcbMillimeter2iu( m_start_x ), PcbMillimeter2iu( m_start_y ) ), + m_center_angle, PcbMillimeter2iu( m_width ) ); + + return arc; + } +}; + + +struct ARC_ARC_COLLIDE_CASE +{ + std::string m_ctx_name; + ARC_DATA_MM m_arc1; + ARC_DATA_MM m_arc2; + int m_clearance; + bool m_exp_result; +}; + + +static const std::vector arc_arc_collide_cases = { + { "case 1: No intersection", + { 73.843527, 74.355869, 71.713528, 72.965869, -76.36664803, 0.2 }, + { 71.236473, 74.704131, 73.366472, 76.094131, -76.36664803, 0.2 }, + 0, + false }, + { "case 2: No intersection", + { 82.542335, 74.825975, 80.413528, 73.435869, -76.4, 0.2 }, + { 76.491192, 73.839894, 78.619999, 75.23, -76.4, 0.2 }, + 0, + false }, + { "case 3: No intersection", + { 89.318807, 74.810106, 87.19, 73.42, -76.4, 0.2 }, + { 87.045667, 74.632941, 88.826472, 75.794131, -267.9, 0.2 }, + 0, + false }, + { "case 4: Co-centered not intersecting", + { 94.665667, 73.772941, 96.446472, 74.934131, -267.9, 0.2 }, + { 94.665667, 73.772941, 93.6551, 73.025482, -255.5, 0.2 }, + 0, + false }, + { "case 5: Not intersecting, but end points very close", + { 72.915251, 80.493054, 73.570159, 81.257692, -260.5, 0.2 }, + { 73.063537, 82.295989, 71.968628, 81.581351, -255.5, 0.2 }, + 0, + false }, + { "case 6: Coincident centers, colliding due to arc thickness", + { 79.279991, 80.67988, 80.3749, 81.394518, -255.5, 0.2 }, + { 79.279991, 80.67988, 80.3749, 81.694518, -255.5, 0.2 }, + 0, + true }, + { "case 7: Single intersection", + { 88.495265, 81.766089, 90.090174, 82.867869, -255.5, 0.2 }, + { 86.995265, 81.387966, 89.090174, 82.876887, -255.5, 0.2 }, + 0, + true }, + { "case 8: Double intersection", + { 96.149734, 81.792126, 94.99, 83.37, -347.2, 0.2 }, + { 94.857156, 81.240589, 95.91, 83.9, -288.5, 0.2 }, + 0, + true }, + { "case 9: Endpoints within arc width", + { 72.915251, 86.493054, 73.970159, 87.257692, -260.5, 0.2 }, + { 73.063537, 88.295989, 71.968628, 87.581351, -255.5, 0.2 }, + 0, + true }, + { "case 10: Endpoints close, outside, no collision", + { 78.915251, 86.393054, 79.970159, 87.157692, 99.5, 0.2 }, + { 79.063537, 88.295989, 77.968628, 87.581351, -255.5, 0.2 }, + 0, + false }, + { "case 11: Endpoints close, inside, collision due to arc width", + { 85.915251, 86.993054, 86.970159, 87.757692, 99.5, 0.2 }, + { 86.063537, 88.295989, 84.968628, 87.581351, -255.5, 0.2 }, + 0, + true }, +}; + + +BOOST_AUTO_TEST_CASE( CollideArc ) +{ + for( const auto& c : arc_arc_collide_cases ) + { + BOOST_TEST_CONTEXT( c.m_ctx_name ) + { + SHAPE_ARC arc1( c.m_arc1.GenerateArc() ); + SHAPE_ARC arc2( c.m_arc2.GenerateArc() ); + + int actual = 0; + VECTOR2I location; + + bool result = static_cast( &arc1 )->Collide( &arc2, c.m_clearance, &actual, + &location ); + + BOOST_CHECK_EQUAL( result, c.m_exp_result ); + + // Test conversion to polygon + /* + SHAPE_POLY_SET poly; + + TransformArcToPolygon( poly, wxPoint( arc1.GetP0() ), wxPoint( arc1.GetArcMid() ), + wxPoint( arc1.GetP1() ), arc1.GetWidth() * 2, + SHAPE_ARC::DefaultAccuracyForPCB(), ERROR_OUTSIDE ); + + bool result2 = poly.Collide( &arc1, arc1.GetWidth(), &actual, &location); + + BOOST_CHECK_EQUAL( result2, false );*/ + } + } +} + + struct ARC_TO_POLYLINE_CASE { std::string m_ctx_name; diff --git a/qa/pns/playground.cpp b/qa/pns/playground.cpp index 5d0eecc084..867460a3f8 100644 --- a/qa/pns/playground.cpp +++ b/qa/pns/playground.cpp @@ -101,8 +101,8 @@ static int arclineIntersect( const SHAPE_ARC& a, const SEG& s, VECTOR2D* pts ) overlay->AnnotatedPoint( s.B, 200000 ); overlay->SetStrokeColor( YELLOW ); overlay->AnnotatedPoint( c, 200000 ); - - + + overlay->SetStrokeColor( WHITE ); overlay->Arc( a ); overlay->SetStrokeColor( DARKGRAY ); @@ -270,33 +270,39 @@ int playground_main_func( int argc, char* argv[] ) struct ARC_DATA { - double sx, sy, ex, ey, ca, w; + double cx, cy, sx, sy, ca, w; }; - const ARC_DATA test_data [] = + const ARC_DATA test_data [] = { {73.843527, 74.355869, 71.713528, 72.965869, -76.36664803, 0.2}, {71.236473, 74.704131, 73.366472, 76.094131, -76.36664803, 0.2}, {82.542335, 74.825975, 80.413528, 73.435869, -76.4, 0.2}, {76.491192, 73.839894, 78.619999, 75.23, -76.4, 0.2}, - {94.665667, 73.772941, 96.446472, 74.934131, -267.9, 0.2}, - {94.750009, 73.74012, 93.6551, 73.025482, -255.5, 0.2}, {89.318807, 74.810106, 87.19, 73.42, -76.4, 0.2}, {87.045667, 74.632941, 88.826472, 75.794131, -267.9, 0.2}, - {79.279991, 80.67988, 80.3749, 81.394518, -255.5, 0.2}, - {79.279991, 80.688898, 80.3749, 81.403536, -255.5, 0.2}, - {72.87525, 80.173054, 73.970159, 80.887692, -255.5, 0.2}, + {94.665667, 73.772941, 96.446472, 74.934131, -267.9, 0.2}, + {94.750009, 73.74012, 93.6551, 73.025482, -255.5, 0.2}, + {72.915251, 80.493054, 73.570159, 81.257692, -260.5, 0.2}, // end points clearance false positive {73.063537, 82.295989, 71.968628, 81.581351, -255.5, 0.2}, + {79.279991, 80.67988, 80.3749, 81.394518, -255.5, 0.2}, + {79.279991, 80.67988, 80.3749, 81.694518, -255.5, 0.2 }, {88.495265, 81.766089, 90.090174, 82.867869, -255.5, 0.2}, {86.995265, 81.387966, 89.090174, 82.876887, -255.5, 0.2}, {96.149734, 81.792126, 94.99, 83.37, -347.2, 0.2}, - {94.857156, 81.240589, 95.91, 83.9, -288.5, 0.2} + {94.857156, 81.240589, 95.91, 83.9, -288.5, 0.2}, + {72.915251, 86.493054, 73.970159, 87.257692, -260.5, 0.2}, // end points clearance #1 + {73.063537, 88.295989, 71.968628, 87.581351, -255.5, 0.2}, + {78.915251, 86.393054, 79.970159, 87.157692, 99.5, 0.2}, // end points clearance #2 - false positive + {79.063537, 88.295989, 77.968628, 87.581351, -255.5, 0.2}, + {85.915251, 86.993054, 86.970159, 87.757692, 99.5, 0.2}, // intersection - false negative + {86.063537, 88.295989, 84.968628, 87.581351, -255.5, 0.2}, }; overlay = frame->GetOverlay(); - + overlay->SetIsFill(false); overlay->SetLineWidth(10000); @@ -309,8 +315,9 @@ int playground_main_func( int argc, char* argv[] ) { const ARC_DATA& d = test_data[i]; - SHAPE_ARC arc( VECTOR2D( Millimeter2iu( d.sx ), Millimeter2iu( d.sy ) ), - VECTOR2D( Millimeter2iu( d.ex ), Millimeter2iu( d.ey ) ), d.ca, d.w ); + SHAPE_ARC arc( VECTOR2D( Millimeter2iu( d.cx ), Millimeter2iu( d.cy ) ), + VECTOR2D( Millimeter2iu( d.sx ), Millimeter2iu( d.sy ) ), d.ca, + Millimeter2iu( d.w ) ); arcs.push_back( arc ); @@ -325,28 +332,25 @@ int playground_main_func( int argc, char* argv[] ) LABEL_MANAGER labelMgr( frame->GetPanel()->GetGAL() ); frame->GetPanel()->GetView()->SetViewport( BOX2D( vp.GetOrigin(), vp.GetSize() ) ); - overlay->SetStrokeColor( WHITE ); - overlay->SetLineWidth( 10000.0 ); - overlay->SetStrokeColor( WHITE ); - for(int i = 0; i < arcs.size(); i+= 2) { SEG closestDist; VECTOR2D ips[2]; - bool collides = collideArc2Arc( arcs[i], arcs[i+1], INT_MAX, closestDist ); + bool collides = collideArc2Arc( arcs[i], arcs[i+1], 0, closestDist ); int ni = intersectArc2Arc( arcs[i], arcs[i+1], ips ); - overlay->SetStrokeColor( WHITE ); - overlay->Arc( arcs[i] ); - overlay->Arc( arcs[i+1] ); - + overlay->SetLineWidth( 10000.0 ); overlay->SetStrokeColor( CYAN ); - overlay->AnnotatedPoint( arcs[i].GetArcMid(), 20000 ); - overlay->AnnotatedPoint( arcs[i+1].GetArcMid(), 20000 ); - overlay->SetStrokeColor( MAGENTA ); + overlay->AnnotatedPoint( arcs[i].GetP0(), arcs[i].GetWidth() / 2 ); + overlay->AnnotatedPoint( arcs[i + 1].GetP0(), arcs[i + 1].GetWidth() / 2 ); + overlay->AnnotatedPoint( arcs[i].GetArcMid(), arcs[i].GetWidth() / 2 ); + overlay->AnnotatedPoint( arcs[i + 1].GetArcMid(), arcs[i + 1].GetWidth() / 2 ); + overlay->AnnotatedPoint( arcs[i].GetP1(), arcs[i].GetWidth() / 2 ); + overlay->AnnotatedPoint( arcs[i + 1].GetP1(), arcs[i + 1].GetWidth() / 2 ); + overlay->SetStrokeColor( GREEN ); for(int j = 0; j < ni; j++ ) - overlay->AnnotatedPoint( ips[j], 200000 ); + overlay->AnnotatedPoint( ips[j], arcs[i].GetWidth() ); if( collides ) { @@ -354,6 +358,10 @@ int playground_main_func( int argc, char* argv[] ) overlay->Line(closestDist.A, closestDist.B); } + overlay->SetStrokeColor( RED ); + overlay->Arc( arcs[i] ); + overlay->SetStrokeColor( MAGENTA ); + overlay->Arc( arcs[i + 1] ); } diff --git a/qa/pns/pns_log_viewer.cpp b/qa/pns/pns_log_viewer.cpp index 0cb521b6d9..c8981f9f70 100644 --- a/qa/pns/pns_log_viewer.cpp +++ b/qa/pns/pns_log_viewer.cpp @@ -254,7 +254,17 @@ void PNS_LOG_VIEWER_OVERLAY::Arc( const SHAPE_ARC& arc ) double start_angle = DEG2RAD( arc.GetStartAngle() ); double angle = DEG2RAD( arc.GetCentralAngle() ); + KIGFX::VIEW_OVERLAY::SetLineWidth( arc.GetWidth() / 10 ); KIGFX::VIEW_OVERLAY::Arc( arc.GetCenter(), radius, start_angle, start_angle + angle ); + + COLOR4D prevStrokeCol = KIGFX::VIEW_OVERLAY::GetStrokeColor(); + COLOR4D lightStrokeCol = prevStrokeCol.WithAlpha(0.5); + KIGFX::VIEW_OVERLAY::SetStrokeColor( lightStrokeCol ); + + KIGFX::VIEW_OVERLAY::SetLineWidth( arc.GetWidth() ); + KIGFX::VIEW_OVERLAY::Arc( arc.GetCenter(), radius, start_angle, start_angle + angle ); + + KIGFX::VIEW_OVERLAY::SetStrokeColor( prevStrokeCol ); } void PNS_LOG_VIEWER_OVERLAY::DrawAnnotations()