Bounding box for arc contains only the arc itself (excluding the center point) (GAL).

This commit is contained in:
Maciej Suminski 2015-09-03 23:05:01 +02:00
parent 0a56afe566
commit bfca6f083f
2 changed files with 98 additions and 72 deletions

View File

@ -428,77 +428,7 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const
break; break;
case S_ARC: case S_ARC:
{ computeArcBBox( bbox );
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; break;
case S_POLYGON: case S_POLYGON:
@ -687,3 +617,93 @@ EDA_ITEM* DRAWSEGMENT::Clone() const
{ {
return new DRAWSEGMENT( *this ); 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;
}
}

View File

@ -59,6 +59,9 @@ protected:
std::vector<wxPoint> m_BezierPoints; std::vector<wxPoint> m_BezierPoints;
std::vector<wxPoint> m_PolyPoints; std::vector<wxPoint> m_PolyPoints;
// Computes the bounding box for an arc
void computeArcBBox( EDA_RECT& aBBox ) const;
public: public:
DRAWSEGMENT( BOARD_ITEM* aParent = NULL, KICAD_T idtype = PCB_LINE_T ); DRAWSEGMENT( BOARD_ITEM* aParent = NULL, KICAD_T idtype = PCB_LINE_T );
@ -242,6 +245,9 @@ public:
virtual EDA_ITEM* Clone() const; virtual EDA_ITEM* Clone() const;
/// @copydoc VIEW_ITEM::ViewBBox()
virtual const BOX2I ViewBBox() const;
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
#endif #endif