geometry: rework SHAPE_LINE_CHAIN::Intersect() to explicitly indicate touching vertices and remove references to SEGs from INTERSECTION structure
This commit is contained in:
parent
e2785b117b
commit
e7fe8c4ddb
|
@ -57,12 +57,20 @@ public:
|
|||
*/
|
||||
struct INTERSECTION
|
||||
{
|
||||
/// segment belonging from the (this) argument of Intersect()
|
||||
SEG our;
|
||||
/// segment belonging from the aOther argument of Intersect()
|
||||
SEG their;
|
||||
/// point of intersection between our and their.
|
||||
VECTOR2I p;
|
||||
/// index of the intersecting corner/segment in the 'our' (== this) line
|
||||
int index_our;
|
||||
/// index of the intersecting corner/segment in the 'their' (Intersect() method parameter) line
|
||||
int index_their;
|
||||
/// when true, the corner [index_our] of the 'our' line lies exactly on 'their' line
|
||||
bool is_corner_our;
|
||||
/// when true, the corner [index_their] of the 'their' line lies exactly on 'our' line.
|
||||
/// Note that when both is_corner_our and is_corner_their are set, the line chains touch with with corners
|
||||
bool is_corner_their;
|
||||
/// auxillary flag to avoid copying intersection info to intersection refining code, used by the refining
|
||||
/// code (e.g. hull handling stuff in the P&S) to reject false intersection points.
|
||||
bool valid;
|
||||
};
|
||||
|
||||
|
||||
|
@ -593,7 +601,7 @@ public:
|
|||
* sorted with increasing path lengths from the starting point of aChain.
|
||||
* @return number of intersections found
|
||||
*/
|
||||
int Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp ) const;
|
||||
int Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp, bool aExcludeColinearAndTouching = false ) const;
|
||||
|
||||
/**
|
||||
* Function PathLength()
|
||||
|
|
|
@ -749,8 +749,9 @@ int SHAPE_LINE_CHAIN::Intersect( const SEG& aSeg, INTERSECTIONS& aIp ) const
|
|||
if( p )
|
||||
{
|
||||
INTERSECTION is;
|
||||
is.our = CSegment( s );
|
||||
is.their = aSeg;
|
||||
is.valid = true;
|
||||
is.index_our = s;
|
||||
is.is_corner_our = is.is_corner_their = false;
|
||||
is.p = *p;
|
||||
aIp.push_back( is );
|
||||
}
|
||||
|
@ -772,16 +773,10 @@ static inline void addIntersection( SHAPE_LINE_CHAIN::INTERSECTIONS& aIps, int a
|
|||
|
||||
const auto& last = aIps.back();
|
||||
|
||||
if( ( (last.our.Index() + 1) % aPc) == aP.our.Index() && last.p == aP.p )
|
||||
return;
|
||||
|
||||
if( last.our.Index() == aP.our.Index() && last.p == aP.p )
|
||||
return;
|
||||
|
||||
aIps.push_back( aP );
|
||||
}
|
||||
|
||||
int SHAPE_LINE_CHAIN::Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp ) const
|
||||
int SHAPE_LINE_CHAIN::Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp, bool aExcludeColinearAndTouching ) const
|
||||
{
|
||||
BOX2I bb_other = aChain.BBox();
|
||||
|
||||
|
@ -798,27 +793,37 @@ int SHAPE_LINE_CHAIN::Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS&
|
|||
const SEG& b = aChain.CSegment( s2 );
|
||||
INTERSECTION is;
|
||||
|
||||
if( a.Collinear( b ) )
|
||||
{
|
||||
is.our = a;
|
||||
is.their = b;
|
||||
is.index_our = s1;
|
||||
is.index_their = s2;
|
||||
is.is_corner_our = false;
|
||||
is.is_corner_their = false;
|
||||
is.valid = true;
|
||||
|
||||
if( a.Contains( b.A ) ) { is.p = b.A; addIntersection(aIp, PointCount(), is); }
|
||||
if( a.Contains( b.B ) ) { is.p = b.B; addIntersection(aIp, PointCount(), is); }
|
||||
if( b.Contains( a.A ) ) { is.p = a.A; addIntersection(aIp, PointCount(), is); }
|
||||
if( b.Contains( a.B ) ) { is.p = a.B; addIntersection(aIp, PointCount(), is); }
|
||||
OPT_VECTOR2I p = a.Intersect( b );
|
||||
|
||||
bool coll = a.Collinear( b );
|
||||
|
||||
if( coll && ! aExcludeColinearAndTouching )
|
||||
{
|
||||
if( a.Contains( b.A ) ) { is.p = b.A; is.is_corner_their = true; addIntersection(aIp, PointCount(), is); }
|
||||
if( a.Contains( b.B ) ) { is.p = b.B; is.index_their++; is.is_corner_their = true; addIntersection(aIp, PointCount(), is); }
|
||||
if( b.Contains( a.A ) ) { is.p = a.A; is.is_corner_our = true; addIntersection(aIp, PointCount(), is); }
|
||||
if( b.Contains( a.B ) ) { is.p = a.B; is.index_our++; is.is_corner_our = true; addIntersection(aIp, PointCount(), is); }
|
||||
}
|
||||
else
|
||||
else if( p )
|
||||
{
|
||||
OPT_VECTOR2I p = a.Intersect( b );
|
||||
is.p = *p;
|
||||
is.is_corner_our = false;
|
||||
is.is_corner_their = false;
|
||||
|
||||
if( p )
|
||||
{
|
||||
is.p = *p;
|
||||
is.our = a;
|
||||
is.their = b;
|
||||
addIntersection(aIp, PointCount(), is);
|
||||
}
|
||||
int distA = ( b.A - *p ).EuclideanNorm();
|
||||
int distB = ( b.B - *p ).EuclideanNorm();
|
||||
|
||||
if ( p == a.A ) { is.is_corner_our = true; }
|
||||
if ( p == a.B ) { is.is_corner_our = true; is.index_our++; }
|
||||
if ( p == b.A ) { is.is_corner_their = true; }
|
||||
if ( p == b.B ) { is.is_corner_their = true; is.index_their++; }
|
||||
addIntersection(aIp, PointCount(), is);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -968,8 +973,8 @@ const OPT<SHAPE_LINE_CHAIN::INTERSECTION> SHAPE_LINE_CHAIN::SelfIntersecting() c
|
|||
if( s1 + 1 != s2 && CSegment( s1 ).Contains( s2a ) )
|
||||
{
|
||||
INTERSECTION is;
|
||||
is.our = CSegment( s1 );
|
||||
is.their = CSegment( s2 );
|
||||
is.index_our = s1;
|
||||
is.index_their = s2;
|
||||
is.p = s2a;
|
||||
return is;
|
||||
}
|
||||
|
@ -980,8 +985,8 @@ const OPT<SHAPE_LINE_CHAIN::INTERSECTION> SHAPE_LINE_CHAIN::SelfIntersecting() c
|
|||
!( IsClosed() && s1 == 0 && s2 == SegmentCount()-1 ) )
|
||||
{
|
||||
INTERSECTION is;
|
||||
is.our = CSegment( s1 );
|
||||
is.their = CSegment( s2 );
|
||||
is.index_our = s1;
|
||||
is.index_their = s2;
|
||||
is.p = s2b;
|
||||
return is;
|
||||
}
|
||||
|
@ -992,8 +997,8 @@ const OPT<SHAPE_LINE_CHAIN::INTERSECTION> SHAPE_LINE_CHAIN::SelfIntersecting() c
|
|||
if( p )
|
||||
{
|
||||
INTERSECTION is;
|
||||
is.our = CSegment( s1 );
|
||||
is.their = CSegment( s2 );
|
||||
is.index_our = s1;
|
||||
is.index_their = s2;
|
||||
is.p = *p;
|
||||
return is;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue