From f8f21ea81c8526d98d28a7749539f40b9e9f42f1 Mon Sep 17 00:00:00 2001 From: Tomasz Wlostowski Date: Wed, 19 Feb 2020 18:11:33 +0100 Subject: [PATCH] geometry: SHAPE_LINE_CHAIN::Intersect should report each unique intersection only once --- libs/kimath/src/geometry/shape_line_chain.cpp | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/libs/kimath/src/geometry/shape_line_chain.cpp b/libs/kimath/src/geometry/shape_line_chain.cpp index cb79fa4d45..29dc624a15 100644 --- a/libs/kimath/src/geometry/shape_line_chain.cpp +++ b/libs/kimath/src/geometry/shape_line_chain.cpp @@ -33,8 +33,17 @@ #include // for BOX2I #include // for rescale #include // for VECTOR2, VECTOR2I + class SHAPE; +SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN( const std::vector& aV) + : SHAPE( SH_LINE_CHAIN ), m_closed( false ), m_width( 0 ) +{ + for(int i = 0; i < aV.size(); i+= 2 ) + { + Append( aV[i], aV[i+1] ); + } +} ClipperLib::Path SHAPE_LINE_CHAIN::convertToClipper( bool aRequiredOrientation ) const { @@ -478,6 +487,24 @@ int SHAPE_LINE_CHAIN::Intersect( const SEG& aSeg, INTERSECTIONS& aIp ) const return aIp.size(); } +static inline void addIntersection( SHAPE_LINE_CHAIN::INTERSECTIONS& aIps, int aPc, const SHAPE_LINE_CHAIN::INTERSECTION& aP ) +{ + if( aIps.size() == 0 ) + { + aIps.push_back( aP ); + return; + } + + 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 { @@ -501,10 +528,10 @@ int SHAPE_LINE_CHAIN::Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& 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 ); } + 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); } } else { @@ -515,7 +542,7 @@ int SHAPE_LINE_CHAIN::Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& is.p = *p; is.our = a; is.their = b; - aIp.push_back( is ); + addIntersection(aIp, PointCount(), is); } } }