POLY_GRID_PARTITION: fixed incorrect point-in-polygon test in some corner cases
Fixes: lp:1787236 * https://bugs.launchpad.net/kicad/+bug/1787236
This commit is contained in:
parent
3da86dc24b
commit
f85dc57642
|
@ -43,7 +43,7 @@
|
||||||
class POLY_GRID_PARTITION
|
class POLY_GRID_PARTITION
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
enum HASH_FLAG
|
enum HASH_FLAG
|
||||||
{
|
{
|
||||||
LEAD_H = 1,
|
LEAD_H = 1,
|
||||||
LEAD_V = 2,
|
LEAD_V = 2,
|
||||||
|
@ -195,7 +195,12 @@ private:
|
||||||
auto dir = edge.B - edge.A;
|
auto dir = edge.B - edge.A;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
if( edgeSet[edge] == 1 )
|
|
||||||
|
if ( dir.y == 0 )
|
||||||
|
{
|
||||||
|
flags = 0;
|
||||||
|
}
|
||||||
|
else if( edgeSet[edge] == 1 )
|
||||||
{
|
{
|
||||||
if( dir.Dot( ref_h ) < 0 )
|
if( dir.Dot( ref_h ) < 0 )
|
||||||
{
|
{
|
||||||
|
@ -210,6 +215,9 @@ private:
|
||||||
|
|
||||||
m_flags.push_back( flags );
|
m_flags.push_back( flags );
|
||||||
|
|
||||||
|
if( edge.A.y == edge.B.y )
|
||||||
|
continue;
|
||||||
|
|
||||||
std::set<int> indices;
|
std::set<int> indices;
|
||||||
|
|
||||||
indices.insert( m_gridSize * poly2gridY( edge.A.y ) + poly2gridX( edge.A.x ) );
|
indices.insert( m_gridSize * poly2gridY( edge.A.y ) + poly2gridX( edge.A.x ) );
|
||||||
|
@ -374,12 +382,12 @@ public:
|
||||||
build( aPolyOutline, gridSize );
|
build( aPolyOutline, gridSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
int containsPoint( const VECTOR2I& aP ) // const
|
int containsPoint( const VECTOR2I& aP, bool debug = false ) const
|
||||||
{
|
{
|
||||||
const auto gridPoint = poly2grid( aP );
|
const auto gridPoint = poly2grid( aP );
|
||||||
|
|
||||||
if( !m_bbox.Contains( aP ) )
|
if( !m_bbox.Contains( aP ) )
|
||||||
return false;
|
return 0;
|
||||||
|
|
||||||
SCAN_STATE state;
|
SCAN_STATE state;
|
||||||
const EDGE_LIST& cell = m_grid[ m_gridSize * gridPoint.y + gridPoint.x ];
|
const EDGE_LIST& cell = m_grid[ m_gridSize * gridPoint.y + gridPoint.x ];
|
||||||
|
@ -414,13 +422,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( state.nearest < 0 )
|
if( state.nearest < 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if( state.dist_max == 0 )
|
if( state.dist_max == 0 )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
// special case for diagonal 'slits', e.g. two segments that partially overlap each other.
|
||||||
if( state.nearest_prev >= 0 && state.dist_max == state.dist_prev )
|
if( state.nearest_prev >= 0 && state.dist_max == state.dist_prev )
|
||||||
{
|
{
|
||||||
int d = std::abs( state.nearest_prev - state.nearest );
|
int d = std::abs( state.nearest_prev - state.nearest );
|
||||||
|
@ -429,12 +438,8 @@ public:
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if( d > 1 )
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( state.dist_max > 0 )
|
if( state.dist_max > 0 )
|
||||||
{
|
{
|
||||||
return m_flags[state.nearest] & LEAD_H ? 1 : 0;
|
return m_flags[state.nearest] & LEAD_H ? 1 : 0;
|
||||||
|
|
Loading…
Reference in New Issue