int SHAPE_LINE_CHAIN::Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp ) const { BOX2I bb_other = aChain.BBox(); for( int s1 = 0; s1 < SegmentCount(); s1++ ) { const SEG& a = CSegment( s1 ); const BOX2I bb_cur( a.A, a.B - a.A ); if( !bb_other.Intersects( bb_cur ) ) continue; for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ ) { const SEG& b = aChain.CSegment( s2 ); INTERSECTION is; if( a.Collinear( b ) ) { is.our = a; is.their = b; if( a.Contains( b.A ) ) { is.p = b.A; aIp.push_back( is ); } if( a.Contains( b.B ) ) { is.p = b.B; aIp.push_back( is ); } if( b.Contains( a.A ) ) { is.p = a.A; aIp.push_back( is ); } if( b.Contains( a.B ) ) { is.p = a.B; aIp.push_back( is ); } } else { OPT_VECTOR2I p = a.Intersect( b ); if( p ) { is.p = *p; is.our = a; is.their = b; aIp.push_back( is ); } } } } return aIp.size(); }
bool SHAPE_POLY_SET::pointInPolygon( const VECTOR2I& aP, const SHAPE_LINE_CHAIN& aPath ) const { int result = 0; int cnt = aPath.PointCount(); if ( !aPath.BBox().Contains( aP ) ) // test with bounding box first return false; if( cnt < 3 ) return false; VECTOR2I ip = aPath.CPoint( 0 ); for( int i = 1; i <= cnt; ++i ) { VECTOR2I ipNext = ( i == cnt ? aPath.CPoint( 0 ) : aPath.CPoint( i ) ); if( ipNext.y == aP.y ) { if( ( ipNext.x == aP.x ) || ( ip.y == aP.y && ( ( ipNext.x > aP.x ) == ( ip.x < aP.x ) ) ) ) return true; } if( ( ip.y < aP.y ) != ( ipNext.y < aP.y ) ) { if( ip.x >= aP.x ) { if( ipNext.x > aP.x ) result = 1 - result; else { int64_t d = (int64_t)( ip.x - aP.x ) * (int64_t)( ipNext.y - aP.y ) - (int64_t)( ipNext.x - aP.x ) * (int64_t)( ip.y - aP.y ); if( !d ) return true; if( ( d > 0 ) == ( ipNext.y > ip.y ) ) result = 1 - result; } } else { if( ipNext.x > aP.x ) { int64_t d = (int64_t)( ip.x - aP.x ) * (int64_t)( ipNext.y - aP.y ) - (int64_t)( ipNext.x - aP.x ) * (int64_t)( ip.y - aP.y ); if( !d ) return true; if( ( d > 0 ) == ( ipNext.y > ip.y ) ) result = 1 - result; } } } ip = ipNext; } return result ? true : false; }