From cd145258392eeb277248cc8ddde0d32bdcdcf674 Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Tue, 27 Feb 2018 22:17:42 -0500 Subject: [PATCH] GerbView: More accurate selection of arc shapes --- gerbview/gerber_draw_item.cpp | 37 ++++++++++++++++++++++++++++++++++- include/trigo.h | 10 ++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/gerbview/gerber_draw_item.cpp b/gerbview/gerber_draw_item.cpp index d6df6d55b0..18c8ba8504 100644 --- a/gerbview/gerber_draw_item.cpp +++ b/gerbview/gerber_draw_item.cpp @@ -769,9 +769,44 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) const return poly.Contains( VECTOR2I( ref_pos ), 0 ); case GBR_SPOT_RECT: - case GBR_ARC: return GetBoundingBox().Contains( aRefPos ); + case GBR_ARC: + { + double radius = GetLineLength( m_Start, m_ArcCentre ); + VECTOR2D test_radius = VECTOR2D( ref_pos ) - VECTOR2D( m_ArcCentre ); + + // Are we within m_Size.x of the radius? + bool radius_hit = ( std::fabs( test_radius.EuclideanNorm() - radius) < m_Size.x ); + + if( radius_hit ) + { + // Now check that we are within the arc angle + + VECTOR2D start = VECTOR2D( m_Start ) - VECTOR2D( m_ArcCentre ); + VECTOR2D end = VECTOR2D( m_End ) - VECTOR2D( m_ArcCentre ); + + double start_angle = NormalizeAngleRadiansPos( start.Angle() ); + double end_angle = NormalizeAngleRadiansPos( end.Angle() ); + + if( m_Start == m_End ) + { + start_angle = 0; + end_angle = 2 * M_PI; + } + else if( end_angle < start_angle ) + { + end_angle += 2 * M_PI; + } + + double test_angle = NormalizeAngleRadiansPos( test_radius.Angle() ); + + return ( test_angle > start_angle && test_angle < end_angle ); + } + + return false; + } + case GBR_SPOT_MACRO: // Aperture macro polygons are already in absolute coordinates auto p = GetDcodeDescr()->GetMacro()->GetApertureMacroShape( this, m_Start ); diff --git a/include/trigo.h b/include/trigo.h index 5cb93f93b2..f8da175bf7 100644 --- a/include/trigo.h +++ b/include/trigo.h @@ -261,6 +261,16 @@ inline void NORMALIZE_ANGLE_DEGREES_POS( double& Angle ) Angle = NormalizeAngleDegreesPos( Angle ); } + +inline double NormalizeAngleRadiansPos( double Angle ) +{ + while( Angle < 0 ) + Angle += (2 * M_PI ); + while( Angle >= ( 2 * M_PI ) ) + Angle -= ( 2 * M_PI ); + return Angle; +} + /// Add two angles (keeping the result normalized). T2 is here // because most of the time it's an int (and templates don't promote in // that way)