Fix two bugs in RTree polygon collions special case.

1) Special case doesn't work for polygons with holes
2) Fix special case to handle intersecting lines where neither end is
   in the polygon.

Note that only (1) is required for the bug below.  (2) was just
discovered while implementing (1).

Fixes https://gitlab.com/kicad/code/kicad/issues/13779
This commit is contained in:
Jeff Young 2023-02-04 13:44:42 +00:00
parent 6b5eeeb861
commit a59c1afa53
1 changed files with 13 additions and 6 deletions

View File

@ -345,7 +345,7 @@ public:
// Special case the polygon case. Otherwise we'll call its Collide() method which will
// triangulate it as well and then do triangle/triangle collisions. This ends up being
// *much* slower than 4 calls to PointInside().
// *much* slower than 3 segment Collide()s and a PointInside().
auto polyVisitor =
[&]( ITEM_WITH_SHAPE* aItem ) -> bool
{
@ -355,10 +355,17 @@ public:
const SHAPE_LINE_CHAIN& outline = poly->Outline( 0 );
if( outline.PointInside( tri->GetPoint( 0 ) )
|| outline.PointInside( tri->GetPoint( 1 ) )
|| outline.PointInside( tri->GetPoint( 2 ) )
|| tri->PointInside( outline.CPoint( 0 ) ) )
for( int ii = 0; ii < (int) tri->GetSegmentCount(); ++ii )
{
if( outline.Collide( tri->GetSegment( ii ) ) )
{
collision = true;
return false;
}
}
// Also must check for poly being completely inside the triangle
if( tri->PointInside( outline.CPoint( 0 ) ) )
{
collision = true;
return false;
@ -379,7 +386,7 @@ public:
return true;
};
if( poly && poly->OutlineCount() == 1 )
if( poly && poly->OutlineCount() == 1 && poly->HoleCount( 0 ) == 0 )
this->m_tree[aLayer]->Search( min, max, polyVisitor );
else
this->m_tree[aLayer]->Search( min, max, visitor );