From bfca6f083f3a906ba17ebcf8430b2de264747181 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 3 Sep 2015 23:05:01 +0200 Subject: [PATCH] Bounding box for arc contains only the arc itself (excluding the center point) (GAL). --- pcbnew/class_drawsegment.cpp | 164 ++++++++++++++++++++--------------- pcbnew/class_drawsegment.h | 6 ++ 2 files changed, 98 insertions(+), 72 deletions(-) diff --git a/pcbnew/class_drawsegment.cpp b/pcbnew/class_drawsegment.cpp index e804a0607e..f9bce50676 100644 --- a/pcbnew/class_drawsegment.cpp +++ b/pcbnew/class_drawsegment.cpp @@ -428,78 +428,8 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const break; case S_ARC: - { - bbox.Merge( m_End ); - // TODO perhaps the above line can be replaced with this one, so we do not include the center - //bbox.SetOrigin( m_End ); - wxPoint end = m_End; - RotatePoint( &end, m_Start, -m_Angle ); - bbox.Merge( end ); - - // Determine the starting quarter - // 0 right-bottom - // 1 left-bottom - // 2 left-top - // 3 right-top - unsigned int quarter = 0; // assume right-bottom - - if( m_End.x < m_Start.x ) - { - if( m_End.y <= m_Start.y ) - quarter = 2; - else // ( m_End.y > m_Start.y ) - quarter = 1; - } - else if( m_End.x >= m_Start.x ) - { - if( m_End.y < m_Start.y ) - quarter = 3; - else if( m_End.x == m_Start.x ) - quarter = 1; - } - - int radius = GetRadius(); - int angle = (int) GetArcAngleStart() % 900 + m_Angle; - bool directionCW = ( m_Angle > 0 ); // Is the direction of arc clockwise? - - // Make the angle positive, so we go clockwise and merge points belonging to the arc - if( !directionCW ) - { - angle = 900 - angle; - quarter = ( quarter + 3 ) % 4; // -1 modulo arithmetic - } - - while( angle > 900 ) - { - switch( quarter ) - { - case 0: - bbox.Merge( wxPoint( m_Start.x, m_Start.y + radius ) ); // down - break; - - case 1: - bbox.Merge( wxPoint( m_Start.x - radius, m_Start.y ) ); // left - break; - - case 2: - bbox.Merge( wxPoint( m_Start.x, m_Start.y - radius ) ); // up - break; - - case 3: - bbox.Merge( wxPoint( m_Start.x + radius, m_Start.y ) ); // right - break; - } - - if( directionCW ) - ++quarter; - else - quarter += 3; // -1 modulo arithmetic - - quarter %= 4; - angle -= 900; - } - } - break; + computeArcBBox( bbox ); + break; case S_POLYGON: { @@ -687,3 +617,93 @@ EDA_ITEM* DRAWSEGMENT::Clone() const { return new DRAWSEGMENT( *this ); } + + +const BOX2I DRAWSEGMENT::ViewBBox() const +{ + // For arcs - do not include the center point in the bounding box, + // it is redundant for displaying an arc + if( m_Shape == S_ARC ) + { + EDA_RECT bbox; + bbox.SetOrigin( m_End ); + computeArcBBox( bbox ); + return BOX2I( bbox.GetOrigin(), bbox.GetSize() ); + } + + return EDA_ITEM::ViewBBox(); +} + + +void DRAWSEGMENT::computeArcBBox( EDA_RECT& aBBox ) const +{ + aBBox.Merge( m_End ); + // TODO perhaps the above line can be replaced with this one, so we do not include the center + //aBBox.SetOrigin( m_End ); + wxPoint end = m_End; + RotatePoint( &end, m_Start, -m_Angle ); + aBBox.Merge( end ); + + // Determine the starting quarter + // 0 right-bottom + // 1 left-bottom + // 2 left-top + // 3 right-top + unsigned int quarter = 0; // assume right-bottom + + if( m_End.x < m_Start.x ) + { + if( m_End.y <= m_Start.y ) + quarter = 2; + else // ( m_End.y > m_Start.y ) + quarter = 1; + } + else if( m_End.x >= m_Start.x ) + { + if( m_End.y < m_Start.y ) + quarter = 3; + else if( m_End.x == m_Start.x ) + quarter = 1; + } + + int radius = GetRadius(); + int angle = (int) GetArcAngleStart() % 900 + m_Angle; + bool directionCW = ( m_Angle > 0 ); // Is the direction of arc clockwise? + + // Make the angle positive, so we go clockwise and merge points belonging to the arc + if( !directionCW ) + { + angle = 900 - angle; + quarter = ( quarter + 3 ) % 4; // -1 modulo arithmetic + } + + while( angle > 900 ) + { + switch( quarter ) + { + case 0: + aBBox.Merge( wxPoint( m_Start.x, m_Start.y + radius ) ); // down + break; + + case 1: + aBBox.Merge( wxPoint( m_Start.x - radius, m_Start.y ) ); // left + break; + + case 2: + aBBox.Merge( wxPoint( m_Start.x, m_Start.y - radius ) ); // up + break; + + case 3: + aBBox.Merge( wxPoint( m_Start.x + radius, m_Start.y ) ); // right + break; + } + + if( directionCW ) + ++quarter; + else + quarter += 3; // -1 modulo arithmetic + + quarter %= 4; + angle -= 900; + } +} diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h index d294e22316..411a5a2306 100644 --- a/pcbnew/class_drawsegment.h +++ b/pcbnew/class_drawsegment.h @@ -59,6 +59,9 @@ protected: std::vector m_BezierPoints; std::vector m_PolyPoints; + // Computes the bounding box for an arc + void computeArcBBox( EDA_RECT& aBBox ) const; + public: DRAWSEGMENT( BOARD_ITEM* aParent = NULL, KICAD_T idtype = PCB_LINE_T ); @@ -242,6 +245,9 @@ public: virtual EDA_ITEM* Clone() const; + /// @copydoc VIEW_ITEM::ViewBBox() + virtual const BOX2I ViewBBox() const; + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override #endif