mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-13 17:53:11 +02:00
Fix hit-testing for rounded corner rectangles.
This commit is contained in:
parent
adbc80aade
commit
01f6776226
@ -1382,6 +1382,15 @@ bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||
|
||||
return poly.Collide( aPosition, maxdist );
|
||||
}
|
||||
else if( m_cornerRadius > 0 )
|
||||
{
|
||||
ROUNDRECT rr( SHAPE_RECT( GetStart(), GetRectangleWidth(), GetRectangleHeight() ), m_cornerRadius );
|
||||
SHAPE_POLY_SET poly;
|
||||
rr.TransformToPolygon( poly );
|
||||
|
||||
if( poly.CollideEdge( aPosition, nullptr, maxdist ) )
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<VECTOR2I> pts = GetRectCorners();
|
||||
@ -1393,13 +1402,13 @@ bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if( IsHatchedFill() && GetHatching().Collide( aPosition, maxdist ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( IsHatchedFill() && GetHatching().Collide( aPosition, maxdist ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
case SHAPE_T::POLY:
|
||||
if( IsFilledForHitTesting() )
|
||||
{
|
||||
@ -1441,6 +1450,40 @@ bool EDA_SHAPE::hitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
|
||||
|
||||
BOX2I bbox = getBoundingBox();
|
||||
|
||||
auto checkOutline =
|
||||
[&]( const SHAPE_LINE_CHAIN& outline )
|
||||
{
|
||||
int count = (int) outline.GetPointCount();
|
||||
|
||||
for( int ii = 0; ii < count; ii++ )
|
||||
{
|
||||
VECTOR2I vertex = outline.GetPoint( ii );
|
||||
|
||||
// Test if the point is within aRect
|
||||
if( arect.Contains( vertex ) )
|
||||
return true;
|
||||
|
||||
if( ii + 1 < count )
|
||||
{
|
||||
VECTOR2I vertexNext = outline.GetPoint( ii + 1 );
|
||||
|
||||
// Test if this edge intersects aRect
|
||||
if( arect.Intersects( vertex, vertexNext ) )
|
||||
return true;
|
||||
}
|
||||
else if( outline.IsClosed() )
|
||||
{
|
||||
VECTOR2I vertexNext = outline.GetPoint( 0 );
|
||||
|
||||
// Test if this edge intersects aRect
|
||||
if( arect.Intersects( vertex, vertexNext ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
switch( m_shape )
|
||||
{
|
||||
case SHAPE_T::CIRCLE:
|
||||
@ -1487,6 +1530,17 @@ bool EDA_SHAPE::hitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
|
||||
{
|
||||
return arect.Contains( bbox );
|
||||
}
|
||||
else if( m_cornerRadius > 0 )
|
||||
{
|
||||
ROUNDRECT rr( SHAPE_RECT( GetStart(), GetRectangleWidth(), GetRectangleHeight() ), m_cornerRadius );
|
||||
SHAPE_POLY_SET poly;
|
||||
rr.TransformToPolygon( poly );
|
||||
|
||||
// Account for the width of the line
|
||||
arect.Inflate( GetWidth() / 2 );
|
||||
|
||||
return checkOutline( poly.Outline( 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<VECTOR2I> pts = GetRectCorners();
|
||||
@ -1528,34 +1582,8 @@ bool EDA_SHAPE::hitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
|
||||
|
||||
for( int ii = 0; ii < m_poly.OutlineCount(); ++ii )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN& poly = m_poly.Outline( ii );
|
||||
int count = (int) poly.GetPointCount();
|
||||
|
||||
for( int jj = 0; jj < count; jj++ )
|
||||
{
|
||||
VECTOR2I vertex = poly.GetPoint( jj );
|
||||
|
||||
// Test if the point is within aRect
|
||||
if( arect.Contains( vertex ) )
|
||||
return true;
|
||||
|
||||
if( jj + 1 < count )
|
||||
{
|
||||
VECTOR2I vertexNext = poly.GetPoint( jj + 1 );
|
||||
|
||||
// Test if this edge intersects aRect
|
||||
if( arect.Intersects( vertex, vertexNext ) )
|
||||
return true;
|
||||
}
|
||||
else if( poly.IsClosed() )
|
||||
{
|
||||
VECTOR2I vertexNext = poly.GetPoint( 0 );
|
||||
|
||||
// Test if this edge intersects aRect
|
||||
if( arect.Intersects( vertex, vertexNext ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if( checkOutline( m_poly.Outline( ii ) ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user