Loading common/drawpanel_gal.cpp +0 −11 Original line number Original line Diff line number Diff line Loading @@ -121,11 +121,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) ) m_pendingRefresh = false; m_pendingRefresh = false; m_lastRefresh = wxGetLocalTimeMillis(); m_lastRefresh = wxGetLocalTimeMillis(); #ifdef __WXDEBUG__ prof_counter time; prof_start( &time, false ); #endif /* __WXDEBUG__ */ m_gal->BeginDrawing(); m_gal->BeginDrawing(); m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) ); m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) ); m_gal->ClearScreen(); m_gal->ClearScreen(); Loading @@ -138,12 +133,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) ) m_gal->DrawCursor( m_viewControls->GetCursorPosition() ); m_gal->DrawCursor( m_viewControls->GetCursorPosition() ); m_gal->EndDrawing(); m_gal->EndDrawing(); #ifdef __WXDEBUG__ prof_end( &time ); wxLogDebug( wxT( "EDA_DRAW_PANEL_GAL::Refresh: %.0f ms (%.0f fps)" ), static_cast<double>( time.value ) / 1000.0, 1000000.0 / static_cast<double>( time.value ) ); #endif /* __WXDEBUG__ */ } } Loading common/geometry/seg.cpp +63 −61 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,7 @@ template <typename T> int sgn(T val) { return ( T( 0 ) < val ) - ( val < T( 0 ) ); return ( T( 0 ) < val ) - ( val < T( 0 ) ); } } bool SEG::PointCloserThan( const VECTOR2I& aP, int dist ) const bool SEG::PointCloserThan( const VECTOR2I& aP, int dist ) const { { VECTOR2I d = b - a; VECTOR2I d = b - a; Loading @@ -37,13 +38,11 @@ bool SEG::PointCloserThan (const VECTOR2I& aP, int dist) const SEG::ecoord l_squared = d.Dot( d ); SEG::ecoord l_squared = d.Dot( d ); SEG::ecoord t = d.Dot( aP - a ); SEG::ecoord t = d.Dot( aP - a ); if( t <= 0 || !l_squared ) if( t <= 0 || !l_squared ) return ( aP - a ).SquaredEuclideanNorm() < dist_sq; return ( aP - a ).SquaredEuclideanNorm() < dist_sq; else if( t >= l_squared ) else if( t >= l_squared ) return ( aP - b ).SquaredEuclideanNorm() < dist_sq; return ( aP - b ).SquaredEuclideanNorm() < dist_sq; int dxdy = abs( d.x ) - abs( d.y ); int dxdy = abs( d.x ) - abs( d.y ); if( ( dxdy >= -1 && dxdy <= 1 ) || abs( d.x ) <= 1 || abs( d.y ) <= 1 ) if( ( dxdy >= -1 && dxdy <= 1 ) || abs( d.x ) <= 1 || abs( d.y ) <= 1 ) Loading Loading @@ -71,6 +70,7 @@ bool SEG::PointCloserThan (const VECTOR2I& aP, int dist) const return ( nearest - aP ).SquaredEuclideanNorm() <= dist_sq; return ( nearest - aP ).SquaredEuclideanNorm() <= dist_sq; } } SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const { { // fixme: rather inefficient.... // fixme: rather inefficient.... Loading @@ -88,9 +88,11 @@ SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const ecoord m = VECTOR2I::ECOORD_MAX; ecoord m = VECTOR2I::ECOORD_MAX; for( int i = 0; i < 4; i++ ) for( int i = 0; i < 4; i++ ) m = std::min( m, pts[i].SquaredEuclideanNorm() ); m = std::min( m, pts[i].SquaredEuclideanNorm() ); return m; return m; } } OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines ) const OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines ) const { { const VECTOR2I e ( b - a ); const VECTOR2I e ( b - a ); Loading @@ -110,7 +112,6 @@ OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines if ( !aLines && aIgnoreEndpoints && ( q == 0 || q == d ) && ( p == 0 || p == d ) ) if ( !aLines && aIgnoreEndpoints && ( q == 0 || q == d ) && ( p == 0 || p == d ) ) return OPT_VECTOR2I(); return OPT_VECTOR2I(); VECTOR2I ip( aSeg.a.x + rescale( q, (ecoord)f.x, d ), VECTOR2I ip( aSeg.a.x + rescale( q, (ecoord)f.x, d ), aSeg.a.y + rescale( q, (ecoord)f.y, d ) ); aSeg.a.y + rescale( q, (ecoord)f.y, d ) ); Loading @@ -123,11 +124,13 @@ bool SEG::ccw ( const VECTOR2I& a, const VECTOR2I& b, const VECTOR2I &c ) const return (ecoord)( c.y - a.y ) * ( b.x - a.x ) > (ecoord)( b.y - a.y ) * ( c.x - a.x ); return (ecoord)( c.y - a.y ) * ( b.x - a.x ) > (ecoord)( b.y - a.y ) * ( c.x - a.x ); } } bool SEG::Collide( const SEG& aSeg, int aClearance ) const bool SEG::Collide( const SEG& aSeg, int aClearance ) const { { // check for intersection // check for intersection // fixme: move to a method // fixme: move to a method if( ccw(a,aSeg.a,aSeg.b) != ccw(b,aSeg.a,aSeg.b) && ccw(a,b,aSeg.a) != ccw(a,b,aSeg.b) ) if( ccw( a, aSeg.a, aSeg.b ) != ccw( b, aSeg.a, aSeg.b ) && ccw( a, b, aSeg.a ) != ccw( a, b, aSeg.b ) ) return true; return true; #define CHK(_seg, _pt) \ #define CHK(_seg, _pt) \ Loading @@ -137,14 +140,13 @@ bool SEG::Collide( const SEG& aSeg, int aClearance ) const CHK( *this, aSeg.b ); CHK( *this, aSeg.b ); CHK( aSeg, a ); CHK( aSeg, a ); CHK( aSeg, b ); CHK( aSeg, b ); #undef CHK #undef CHK return false; return false; } } bool SEG::Contains( const VECTOR2I& aP ) const bool SEG::Contains( const VECTOR2I& aP ) const { { return PointCloserThan( aP, 1 ); return PointCloserThan( aP, 1 ); } } common/geometry/shape_collisions.cpp +71 −48 Original line number Original line Diff line number Diff line Loading @@ -31,7 +31,8 @@ typedef VECTOR2I::extended_type ecoord; typedef VECTOR2I::extended_type ecoord; static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { ecoord min_dist = clearance + a.GetRadius() + b.GetRadius(); ecoord min_dist = clearance + a.GetRadius() + b.GetRadius(); ecoord min_dist_sq = min_dist * min_dist; ecoord min_dist_sq = min_dist * min_dist; Loading @@ -49,7 +50,8 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int cl return true; return true; } } static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { const VECTOR2I c = b.GetCenter(); const VECTOR2I c = b.GetCenter(); const VECTOR2I p0 = a.GetPosition(); const VECTOR2I p0 = a.GetPosition(); Loading Loading @@ -82,7 +84,6 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle const SEG seg( vts[i], vts[i+1] ); const SEG seg( vts[i], vts[i+1] ); ecoord dist_sq = seg.SquaredDistance( c ); ecoord dist_sq = seg.SquaredDistance( c ); if( dist_sq < min_dist_sq ) if( dist_sq < min_dist_sq ) { { if( !needMTV ) if( !needMTV ) Loading Loading @@ -112,7 +113,9 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle return true; return true; } } static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { for( int s = 0; s < b.SegmentCount(); s++ ) for( int s = 0; s < b.SegmentCount(); s++ ) { { Loading @@ -123,7 +126,9 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, i return false; return false; } } static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { for( int i = 0; i < b.SegmentCount(); i++ ) for( int i = 0; i < b.SegmentCount(); i++ ) if( a.Collide( b.CSegment(i), clearance ) ) if( a.Collide( b.CSegment(i), clearance ) ) Loading @@ -132,7 +137,8 @@ static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b } } static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { for( int s = 0; s < b.SegmentCount(); s++ ) for( int s = 0; s < b.SegmentCount(); s++ ) { { Loading @@ -145,7 +151,6 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int } } bool CollideShapes( const SHAPE* a, const SHAPE* b, int clearance, bool needMTV, VECTOR2I& aMTV ) bool CollideShapes( const SHAPE* a, const SHAPE* b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { switch( a->Type() ) switch( a->Type() ) Loading @@ -154,9 +159,13 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) switch( b->Type() ) { { case SH_CIRCLE: case SH_CIRCLE: return Collide( *static_cast<const SHAPE_RECT *> (a), *static_cast<const SHAPE_CIRCLE *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( a ), *static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_RECT *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( a ), *static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV ); default: default: break; break; } } Loading @@ -165,11 +174,17 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) switch( b->Type() ) { { case SH_RECT: case SH_RECT: return Collide( *static_cast<const SHAPE_RECT *> (b), *static_cast<const SHAPE_CIRCLE *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( b ), *static_cast<const SHAPE_CIRCLE*>( a ), clearance, needMTV, aMTV ); case SH_CIRCLE: case SH_CIRCLE: return Collide( *static_cast<const SHAPE_CIRCLE *> (a), *static_cast<const SHAPE_CIRCLE *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( a ), *static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_CIRCLE *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( a ), *static_cast<const SHAPE_LINE_CHAIN *>( b ), clearance, needMTV, aMTV ); default: default: break; break; } } Loading @@ -178,14 +193,21 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) switch( b->Type() ) { { case SH_RECT: case SH_RECT: return Collide( *static_cast<const SHAPE_RECT *> (b), *static_cast<const SHAPE_LINE_CHAIN *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( b ), *static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV ); case SH_CIRCLE: case SH_CIRCLE: return Collide( *static_cast<const SHAPE_CIRCLE *> (b), *static_cast<const SHAPE_LINE_CHAIN *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( b ), *static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_LINE_CHAIN *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_LINE_CHAIN*>( a ), *static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV ); default: default: break; break; } } default: default: break; break; } } Loading @@ -193,6 +215,7 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV bool unsupported_collision = true; bool unsupported_collision = true; assert( unsupported_collision == false ); assert( unsupported_collision == false ); return false; return false; } } Loading @@ -202,9 +225,9 @@ bool SHAPE::Collide ( const SHAPE *aShape, int aClerance, VECTOR2I& aMTV ) const return CollideShapes( this, aShape, aClerance, true, aMTV); return CollideShapes( this, aShape, aClerance, true, aMTV); } } bool SHAPE::Collide ( const SHAPE* aShape, int aClerance ) const bool SHAPE::Collide ( const SHAPE* aShape, int aClerance ) const { { VECTOR2I dummy; VECTOR2I dummy; return CollideShapes( this, aShape, aClerance, false, dummy ); return CollideShapes( this, aShape, aClerance, false, dummy ); } } common/geometry/shape_index.cpp +0 −1 Original line number Original line Diff line number Diff line Loading @@ -30,4 +30,3 @@ const SHAPE* shapeFunctor( SHAPE* aItem ) { { return aItem; return aItem; } } common/geometry/shape_line_chain.cpp +225 −170 Original line number Original line Diff line number Diff line Loading @@ -34,12 +34,14 @@ bool SHAPE_LINE_CHAIN::Collide ( const VECTOR2I& aP, int aClearance ) const return false; return false; } } bool SHAPE_LINE_CHAIN::Collide( const BOX2I& aBox, int aClearance ) const bool SHAPE_LINE_CHAIN::Collide( const BOX2I& aBox, int aClearance ) const { { assert( false ); assert( false ); return false; return false; } } bool SHAPE_LINE_CHAIN::Collide( const SEG& aSeg, int aClearance ) const bool SHAPE_LINE_CHAIN::Collide( const SEG& aSeg, int aClearance ) const { { BOX2I box_a( aSeg.a, aSeg.b - aSeg.a ); BOX2I box_a( aSeg.a, aSeg.b - aSeg.a ); Loading @@ -58,6 +60,7 @@ bool SHAPE_LINE_CHAIN::Collide ( const SEG& aSeg, int aClearance ) const return true; return true; } } } } return false; return false; } } Loading @@ -76,53 +79,61 @@ int SHAPE_LINE_CHAIN::Length() const int l = 0; int l = 0; for( int i = 0; i < SegmentCount(); i++ ) for( int i = 0; i < SegmentCount(); i++ ) l += CSegment( i ).Length(); l += CSegment( i ).Length(); return l; return l; } } void SHAPE_LINE_CHAIN::Replace( int start_index, int end_index, const VECTOR2I& aP) void SHAPE_LINE_CHAIN::Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP ) { { if(end_index < 0) if( aEndIndex < 0 ) end_index += PointCount(); aEndIndex += PointCount(); if(start_index < 0) if( aStartIndex < 0 ) start_index += PointCount(); aStartIndex += PointCount(); if (start_index == end_index) if( aStartIndex == aEndIndex ) m_points [start_index] = aP; m_points [aStartIndex] = aP; else { else m_points.erase (m_points.begin() + start_index + 1, m_points.begin() + end_index + 1); { m_points [start_index] = aP; m_points.erase( m_points.begin() + aStartIndex + 1, m_points.begin() + aEndIndex + 1 ); m_points[aStartIndex] = aP; } } } } void SHAPE_LINE_CHAIN::Replace( int start_index, int end_index, const SHAPE_LINE_CHAIN& aLine) void SHAPE_LINE_CHAIN::Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine ) { { if(end_index < 0) if( aEndIndex < 0 ) end_index += PointCount(); aEndIndex += PointCount(); if(start_index < 0) if( aStartIndex < 0 ) start_index += PointCount(); aStartIndex += PointCount(); m_points.erase (m_points.begin() + start_index, m_points.begin() + end_index + 1); m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 ); m_points.insert (m_points.begin() + start_index, aLine.m_points.begin(), aLine.m_points.end()); m_points.insert( m_points.begin() + aStartIndex, aLine.m_points.begin(), aLine.m_points.end() ); } } void SHAPE_LINE_CHAIN::Remove( int start_index, int end_index) void SHAPE_LINE_CHAIN::Remove( int aStartIndex, int aEndIndex ) { { if(end_index < 0) if(aEndIndex < 0) end_index += PointCount(); aEndIndex += PointCount(); if(start_index < 0) if(aStartIndex < 0) start_index += PointCount(); aStartIndex += PointCount(); m_points.erase (m_points.begin() + start_index, m_points.begin() + end_index + 1); m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 ); } } int SHAPE_LINE_CHAIN::Distance( const VECTOR2I& aP ) const int SHAPE_LINE_CHAIN::Distance( const VECTOR2I& aP ) const { { int d = INT_MAX; int d = INT_MAX; for( int s = 0; s < SegmentCount(); s++ ) for( int s = 0; s < SegmentCount(); s++ ) d = min( d, CSegment( s ).Distance( aP ) ); d = min( d, CSegment( s ).Distance( aP ) ); return d; return d; } } int SHAPE_LINE_CHAIN::Split( const VECTOR2I& aP ) int SHAPE_LINE_CHAIN::Split( const VECTOR2I& aP ) { { int ii = -1; int ii = -1; Loading Loading @@ -150,41 +161,49 @@ int SHAPE_LINE_CHAIN::Split( const VECTOR2I & aP ) if( ii >= 0 ) if( ii >= 0 ) { { m_points.insert( m_points.begin() + ii + 1, aP ); m_points.insert( m_points.begin() + ii + 1, aP ); return ii + 1; return ii + 1; } } return -1; return -1; } } int SHAPE_LINE_CHAIN::Find( const VECTOR2I& aP ) const int SHAPE_LINE_CHAIN::Find( const VECTOR2I& aP ) const { { for( int s = 0; s< PointCount(); s++ ) for( int s = 0; s< PointCount(); s++ ) if( CPoint( s ) == aP ) if( CPoint( s ) == aP ) return s; return s; return -1; return -1; } } const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int start_index, int end_index ) const const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int aStartIndex, int aEndIndex ) const { { SHAPE_LINE_CHAIN rv; SHAPE_LINE_CHAIN rv; if(end_index < 0) if( aEndIndex < 0 ) end_index += PointCount(); aEndIndex += PointCount(); if(start_index < 0) if( aStartIndex < 0 ) start_index += PointCount(); aStartIndex += PointCount(); for(int i = start_index; i<= end_index; i++) for( int i = aStartIndex; i <= aEndIndex; i++ ) rv.Append( m_points[i] ); rv.Append( m_points[i] ); return rv; return rv; } } struct compareOriginDistance { struct compareOriginDistance { compareOriginDistance( VECTOR2I& aOrigin ): compareOriginDistance( VECTOR2I& aOrigin ): m_origin( aOrigin ) {}; m_origin( aOrigin ) {}; bool operator()(const SHAPE_LINE_CHAIN::Intersection &a, const SHAPE_LINE_CHAIN::Intersection& b) bool operator()( const SHAPE_LINE_CHAIN::Intersection& aA, const SHAPE_LINE_CHAIN::Intersection& aB ) { { return (m_origin - a.p).EuclideanNorm() < (m_origin - b.p).EuclideanNorm(); return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm(); } } VECTOR2I m_origin; VECTOR2I m_origin; Loading @@ -208,8 +227,10 @@ int SHAPE_LINE_CHAIN::Intersect ( const SEG& aSeg, Intersections& aIp ) const compareOriginDistance comp( aSeg.a ); compareOriginDistance comp( aSeg.a ); sort( aIp.begin(), aIp.end(), comp ); sort( aIp.begin(), aIp.end(), comp ); return aIp.size(); return aIp.size(); }; } 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 ) const { { Loading @@ -228,14 +249,15 @@ BOX2I bb_other = aChain.BBox(); const SEG& b = aChain.CSegment( s2 ); const SEG& b = aChain.CSegment( s2 ); Intersection is; Intersection is; if( a.Collinear( b ) ) if( a.Collinear( b ) ) { { if( a.Contains( b.a ) ) { is.p = b.a; aIp.push_back( is ); } 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( 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.a ) ) { is.p = a.a; aIp.push_back( is ); } if( b.Contains( a.b ) ) { is.p = a.b; aIp.push_back( is ); } if( b.Contains( a.b ) ) { is.p = a.b; aIp.push_back( is ); } } else { } else { OPT_VECTOR2I p = a.Intersect( b ); OPT_VECTOR2I p = a.Intersect( b ); if( p ) if( p ) Loading @@ -252,6 +274,7 @@ BOX2I bb_other = aChain.BBox(); return aIp.size(); return aIp.size(); for( int s1 = 0; s1 < SegmentCount(); s1++ ) for( int s1 = 0; s1 < SegmentCount(); s1++ ) { for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ ) for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ ) { { const SEG& a = CSegment( s1 ); const SEG& a = CSegment( s1 ); Loading @@ -265,7 +288,8 @@ BOX2I bb_other = aChain.BBox(); is.our = a; is.our = a; is.their = b; is.their = b; aIp.push_back( is ); aIp.push_back( is ); } else if (a.Collinear(b)) } else if( a.Collinear( b ) ) { { if( a.a != b.a && a.a != b.b && b.Contains( a.a ) ) if( a.a != b.a && a.a != b.b && b.Contains( a.a ) ) { { Loading @@ -284,9 +308,12 @@ BOX2I bb_other = aChain.BBox(); } } } } } return aIp.size(); return aIp.size(); } } int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const { { int sum = 0; int sum = 0; Loading @@ -294,6 +321,7 @@ int SHAPE_LINE_CHAIN::PathLength (const VECTOR2I& aP ) const { { const SEG seg = CSegment( i ); const SEG seg = CSegment( i ); int d = seg.Distance( aP ); int d = seg.Distance( aP ); if( d <= 1 ) if( d <= 1 ) { { sum += ( aP - seg.a ).EuclideanNorm(); sum += ( aP - seg.a ).EuclideanNorm(); Loading @@ -302,29 +330,36 @@ int SHAPE_LINE_CHAIN::PathLength (const VECTOR2I& aP ) const else else sum += seg.Length(); sum += seg.Length(); } } return -1; return -1; } } bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const { { if( !m_closed || SegmentCount() < 3 ) if( !m_closed || SegmentCount() < 3 ) return false; return false; int cur = CSegment(0).Side( aP ); int cur = CSegment(0).Side( aP ); if( cur == 0 ) if( cur == 0 ) return false; return false; for( int i = 1; i < SegmentCount(); i++ ) for( int i = 1; i < SegmentCount(); i++ ) { { const SEG s = CSegment( i ); const SEG s = CSegment( i ); if( aP == s.a || aP == s.b ) // edge does not belong to the interior! if( aP == s.a || aP == s.b ) // edge does not belong to the interior! return false; return false; if( s.Side(aP) != cur ) if( s.Side(aP) != cur ) return false; return false; } } return true; return true; } } bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP ) const bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP ) const { { if( SegmentCount() < 1 ) if( SegmentCount() < 1 ) Loading @@ -333,18 +368,22 @@ bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP) const for( int i = 1; i < SegmentCount(); i++ ) for( int i = 1; i < SegmentCount(); i++ ) { { const SEG s = CSegment( i ); const SEG s = CSegment( i ); if( s.a == aP || s.b == aP ) if( s.a == aP || s.b == aP ) return true; return true; if( s.Distance(aP) <= 1 ) if( s.Distance(aP) <= 1 ) return true; return true; } } return false; return false; } } const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersecting() const const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersecting() const { { for( int s1 = 0; s1 < SegmentCount(); s1++ ) for( int s1 = 0; s1 < SegmentCount(); s1++ ) { for( int s2 = s1 + 1; s2 < SegmentCount(); s2++ ) for( int s2 = s1 + 1; s2 < SegmentCount(); s2++ ) { { const VECTOR2I s2a = CSegment( s2 ).a, s2b = CSegment( s2 ).b; const VECTOR2I s2a = CSegment( s2 ).a, s2b = CSegment( s2 ).b; Loading @@ -355,14 +394,17 @@ const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersectin is.their = CSegment( s2 ); is.their = CSegment( s2 ); is.p = s2a; is.p = s2a; return is; return is; } else if (CSegment(s1).Contains(s2b)) { } else if( CSegment( s1 ).Contains(s2b ) ) { Intersection is; Intersection is; is.our = CSegment( s1 ); is.our = CSegment( s1 ); is.their = CSegment( s2 ); is.their = CSegment( s2 ); is.p = s2b; is.p = s2b; return is; return is; } } else { else { OPT_VECTOR2I p = CSegment( s1 ).Intersect( CSegment( s2 ), true ); OPT_VECTOR2I p = CSegment( s1 ).Intersect( CSegment( s2 ), true ); if( p ) if( p ) Loading @@ -375,6 +417,8 @@ const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersectin } } } } } } } return optional<Intersection>(); return optional<Intersection>(); } } Loading @@ -386,9 +430,12 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() if( PointCount() < 2 ) if( PointCount() < 2 ) { { return *this; return *this; } else if (PointCount() == 2) { } else if( PointCount() == 2 ) { if( m_points[0] == m_points[1] ) if( m_points[0] == m_points[1] ) m_points.erase( m_points.end() ); m_points.erase( m_points.end() ); return *this; return *this; } } Loading @@ -401,6 +448,7 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() int j = i + 1; int j = i + 1; while( j < np && CPoint(i) == CPoint( j ) ) while( j < np && CPoint(i) == CPoint( j ) ) j++; j++; pts_unique.push_back( CPoint( i ) ); pts_unique.push_back( CPoint( i ) ); i = j; i = j; } } Loading @@ -415,27 +463,32 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() const VECTOR2I p0 = pts_unique[i]; const VECTOR2I p0 = pts_unique[i]; const VECTOR2I p1 = pts_unique[i+1]; const VECTOR2I p1 = pts_unique[i+1]; int n = i; int n = i; while( n < np - 2 && SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1 ) while( n < np - 2 && SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1 ) n++; n++; m_points.push_back( p0 ); m_points.push_back( p0 ); if( n > i ) if( n > i ) i = n; i = n; if( n == np ) if( n == np ) { { m_points.push_back( pts_unique[n - 1] ); m_points.push_back( pts_unique[n - 1] ); return *this; return *this; } } i++; i++; } } if( np > 1 ) if( np > 1 ) m_points.push_back( pts_unique[np - 2] ); m_points.push_back( pts_unique[np - 2] ); m_points.push_back( pts_unique[np - 1] ); m_points.push_back( pts_unique[np - 1] ); return *this; return *this; } } const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint( const VECTOR2I& aP ) const const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint( const VECTOR2I& aP ) const { { int min_d = INT_MAX; int min_d = INT_MAX; Loading @@ -449,9 +502,11 @@ const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint(const VECTOR2I& aP) const nearest = i; nearest = i; } } } } return CSegment( nearest ).NearestPoint( aP ); return CSegment( nearest ).NearestPoint( aP ); } } const string SHAPE_LINE_CHAIN::Format() const const string SHAPE_LINE_CHAIN::Format() const { { stringstream ss; stringstream ss; Loading Loading
common/drawpanel_gal.cpp +0 −11 Original line number Original line Diff line number Diff line Loading @@ -121,11 +121,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) ) m_pendingRefresh = false; m_pendingRefresh = false; m_lastRefresh = wxGetLocalTimeMillis(); m_lastRefresh = wxGetLocalTimeMillis(); #ifdef __WXDEBUG__ prof_counter time; prof_start( &time, false ); #endif /* __WXDEBUG__ */ m_gal->BeginDrawing(); m_gal->BeginDrawing(); m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) ); m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) ); m_gal->ClearScreen(); m_gal->ClearScreen(); Loading @@ -138,12 +133,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) ) m_gal->DrawCursor( m_viewControls->GetCursorPosition() ); m_gal->DrawCursor( m_viewControls->GetCursorPosition() ); m_gal->EndDrawing(); m_gal->EndDrawing(); #ifdef __WXDEBUG__ prof_end( &time ); wxLogDebug( wxT( "EDA_DRAW_PANEL_GAL::Refresh: %.0f ms (%.0f fps)" ), static_cast<double>( time.value ) / 1000.0, 1000000.0 / static_cast<double>( time.value ) ); #endif /* __WXDEBUG__ */ } } Loading
common/geometry/seg.cpp +63 −61 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,7 @@ template <typename T> int sgn(T val) { return ( T( 0 ) < val ) - ( val < T( 0 ) ); return ( T( 0 ) < val ) - ( val < T( 0 ) ); } } bool SEG::PointCloserThan( const VECTOR2I& aP, int dist ) const bool SEG::PointCloserThan( const VECTOR2I& aP, int dist ) const { { VECTOR2I d = b - a; VECTOR2I d = b - a; Loading @@ -37,13 +38,11 @@ bool SEG::PointCloserThan (const VECTOR2I& aP, int dist) const SEG::ecoord l_squared = d.Dot( d ); SEG::ecoord l_squared = d.Dot( d ); SEG::ecoord t = d.Dot( aP - a ); SEG::ecoord t = d.Dot( aP - a ); if( t <= 0 || !l_squared ) if( t <= 0 || !l_squared ) return ( aP - a ).SquaredEuclideanNorm() < dist_sq; return ( aP - a ).SquaredEuclideanNorm() < dist_sq; else if( t >= l_squared ) else if( t >= l_squared ) return ( aP - b ).SquaredEuclideanNorm() < dist_sq; return ( aP - b ).SquaredEuclideanNorm() < dist_sq; int dxdy = abs( d.x ) - abs( d.y ); int dxdy = abs( d.x ) - abs( d.y ); if( ( dxdy >= -1 && dxdy <= 1 ) || abs( d.x ) <= 1 || abs( d.y ) <= 1 ) if( ( dxdy >= -1 && dxdy <= 1 ) || abs( d.x ) <= 1 || abs( d.y ) <= 1 ) Loading Loading @@ -71,6 +70,7 @@ bool SEG::PointCloserThan (const VECTOR2I& aP, int dist) const return ( nearest - aP ).SquaredEuclideanNorm() <= dist_sq; return ( nearest - aP ).SquaredEuclideanNorm() <= dist_sq; } } SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const { { // fixme: rather inefficient.... // fixme: rather inefficient.... Loading @@ -88,9 +88,11 @@ SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const ecoord m = VECTOR2I::ECOORD_MAX; ecoord m = VECTOR2I::ECOORD_MAX; for( int i = 0; i < 4; i++ ) for( int i = 0; i < 4; i++ ) m = std::min( m, pts[i].SquaredEuclideanNorm() ); m = std::min( m, pts[i].SquaredEuclideanNorm() ); return m; return m; } } OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines ) const OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines ) const { { const VECTOR2I e ( b - a ); const VECTOR2I e ( b - a ); Loading @@ -110,7 +112,6 @@ OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines if ( !aLines && aIgnoreEndpoints && ( q == 0 || q == d ) && ( p == 0 || p == d ) ) if ( !aLines && aIgnoreEndpoints && ( q == 0 || q == d ) && ( p == 0 || p == d ) ) return OPT_VECTOR2I(); return OPT_VECTOR2I(); VECTOR2I ip( aSeg.a.x + rescale( q, (ecoord)f.x, d ), VECTOR2I ip( aSeg.a.x + rescale( q, (ecoord)f.x, d ), aSeg.a.y + rescale( q, (ecoord)f.y, d ) ); aSeg.a.y + rescale( q, (ecoord)f.y, d ) ); Loading @@ -123,11 +124,13 @@ bool SEG::ccw ( const VECTOR2I& a, const VECTOR2I& b, const VECTOR2I &c ) const return (ecoord)( c.y - a.y ) * ( b.x - a.x ) > (ecoord)( b.y - a.y ) * ( c.x - a.x ); return (ecoord)( c.y - a.y ) * ( b.x - a.x ) > (ecoord)( b.y - a.y ) * ( c.x - a.x ); } } bool SEG::Collide( const SEG& aSeg, int aClearance ) const bool SEG::Collide( const SEG& aSeg, int aClearance ) const { { // check for intersection // check for intersection // fixme: move to a method // fixme: move to a method if( ccw(a,aSeg.a,aSeg.b) != ccw(b,aSeg.a,aSeg.b) && ccw(a,b,aSeg.a) != ccw(a,b,aSeg.b) ) if( ccw( a, aSeg.a, aSeg.b ) != ccw( b, aSeg.a, aSeg.b ) && ccw( a, b, aSeg.a ) != ccw( a, b, aSeg.b ) ) return true; return true; #define CHK(_seg, _pt) \ #define CHK(_seg, _pt) \ Loading @@ -137,14 +140,13 @@ bool SEG::Collide( const SEG& aSeg, int aClearance ) const CHK( *this, aSeg.b ); CHK( *this, aSeg.b ); CHK( aSeg, a ); CHK( aSeg, a ); CHK( aSeg, b ); CHK( aSeg, b ); #undef CHK #undef CHK return false; return false; } } bool SEG::Contains( const VECTOR2I& aP ) const bool SEG::Contains( const VECTOR2I& aP ) const { { return PointCloserThan( aP, 1 ); return PointCloserThan( aP, 1 ); } }
common/geometry/shape_collisions.cpp +71 −48 Original line number Original line Diff line number Diff line Loading @@ -31,7 +31,8 @@ typedef VECTOR2I::extended_type ecoord; typedef VECTOR2I::extended_type ecoord; static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { ecoord min_dist = clearance + a.GetRadius() + b.GetRadius(); ecoord min_dist = clearance + a.GetRadius() + b.GetRadius(); ecoord min_dist_sq = min_dist * min_dist; ecoord min_dist_sq = min_dist * min_dist; Loading @@ -49,7 +50,8 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int cl return true; return true; } } static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { const VECTOR2I c = b.GetCenter(); const VECTOR2I c = b.GetCenter(); const VECTOR2I p0 = a.GetPosition(); const VECTOR2I p0 = a.GetPosition(); Loading Loading @@ -82,7 +84,6 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle const SEG seg( vts[i], vts[i+1] ); const SEG seg( vts[i], vts[i+1] ); ecoord dist_sq = seg.SquaredDistance( c ); ecoord dist_sq = seg.SquaredDistance( c ); if( dist_sq < min_dist_sq ) if( dist_sq < min_dist_sq ) { { if( !needMTV ) if( !needMTV ) Loading Loading @@ -112,7 +113,9 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle return true; return true; } } static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { for( int s = 0; s < b.SegmentCount(); s++ ) for( int s = 0; s < b.SegmentCount(); s++ ) { { Loading @@ -123,7 +126,9 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, i return false; return false; } } static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { for( int i = 0; i < b.SegmentCount(); i++ ) for( int i = 0; i < b.SegmentCount(); i++ ) if( a.Collide( b.CSegment(i), clearance ) ) if( a.Collide( b.CSegment(i), clearance ) ) Loading @@ -132,7 +137,8 @@ static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b } } static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { for( int s = 0; s < b.SegmentCount(); s++ ) for( int s = 0; s < b.SegmentCount(); s++ ) { { Loading @@ -145,7 +151,6 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int } } bool CollideShapes( const SHAPE* a, const SHAPE* b, int clearance, bool needMTV, VECTOR2I& aMTV ) bool CollideShapes( const SHAPE* a, const SHAPE* b, int clearance, bool needMTV, VECTOR2I& aMTV ) { { switch( a->Type() ) switch( a->Type() ) Loading @@ -154,9 +159,13 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) switch( b->Type() ) { { case SH_CIRCLE: case SH_CIRCLE: return Collide( *static_cast<const SHAPE_RECT *> (a), *static_cast<const SHAPE_CIRCLE *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( a ), *static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_RECT *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( a ), *static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV ); default: default: break; break; } } Loading @@ -165,11 +174,17 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) switch( b->Type() ) { { case SH_RECT: case SH_RECT: return Collide( *static_cast<const SHAPE_RECT *> (b), *static_cast<const SHAPE_CIRCLE *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( b ), *static_cast<const SHAPE_CIRCLE*>( a ), clearance, needMTV, aMTV ); case SH_CIRCLE: case SH_CIRCLE: return Collide( *static_cast<const SHAPE_CIRCLE *> (a), *static_cast<const SHAPE_CIRCLE *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( a ), *static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_CIRCLE *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( a ), *static_cast<const SHAPE_LINE_CHAIN *>( b ), clearance, needMTV, aMTV ); default: default: break; break; } } Loading @@ -178,14 +193,21 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) switch( b->Type() ) { { case SH_RECT: case SH_RECT: return Collide( *static_cast<const SHAPE_RECT *> (b), *static_cast<const SHAPE_LINE_CHAIN *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( b ), *static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV ); case SH_CIRCLE: case SH_CIRCLE: return Collide( *static_cast<const SHAPE_CIRCLE *> (b), *static_cast<const SHAPE_LINE_CHAIN *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( b ), *static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_LINE_CHAIN *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_LINE_CHAIN*>( a ), *static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV ); default: default: break; break; } } default: default: break; break; } } Loading @@ -193,6 +215,7 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV bool unsupported_collision = true; bool unsupported_collision = true; assert( unsupported_collision == false ); assert( unsupported_collision == false ); return false; return false; } } Loading @@ -202,9 +225,9 @@ bool SHAPE::Collide ( const SHAPE *aShape, int aClerance, VECTOR2I& aMTV ) const return CollideShapes( this, aShape, aClerance, true, aMTV); return CollideShapes( this, aShape, aClerance, true, aMTV); } } bool SHAPE::Collide ( const SHAPE* aShape, int aClerance ) const bool SHAPE::Collide ( const SHAPE* aShape, int aClerance ) const { { VECTOR2I dummy; VECTOR2I dummy; return CollideShapes( this, aShape, aClerance, false, dummy ); return CollideShapes( this, aShape, aClerance, false, dummy ); } }
common/geometry/shape_index.cpp +0 −1 Original line number Original line Diff line number Diff line Loading @@ -30,4 +30,3 @@ const SHAPE* shapeFunctor( SHAPE* aItem ) { { return aItem; return aItem; } }
common/geometry/shape_line_chain.cpp +225 −170 Original line number Original line Diff line number Diff line Loading @@ -34,12 +34,14 @@ bool SHAPE_LINE_CHAIN::Collide ( const VECTOR2I& aP, int aClearance ) const return false; return false; } } bool SHAPE_LINE_CHAIN::Collide( const BOX2I& aBox, int aClearance ) const bool SHAPE_LINE_CHAIN::Collide( const BOX2I& aBox, int aClearance ) const { { assert( false ); assert( false ); return false; return false; } } bool SHAPE_LINE_CHAIN::Collide( const SEG& aSeg, int aClearance ) const bool SHAPE_LINE_CHAIN::Collide( const SEG& aSeg, int aClearance ) const { { BOX2I box_a( aSeg.a, aSeg.b - aSeg.a ); BOX2I box_a( aSeg.a, aSeg.b - aSeg.a ); Loading @@ -58,6 +60,7 @@ bool SHAPE_LINE_CHAIN::Collide ( const SEG& aSeg, int aClearance ) const return true; return true; } } } } return false; return false; } } Loading @@ -76,53 +79,61 @@ int SHAPE_LINE_CHAIN::Length() const int l = 0; int l = 0; for( int i = 0; i < SegmentCount(); i++ ) for( int i = 0; i < SegmentCount(); i++ ) l += CSegment( i ).Length(); l += CSegment( i ).Length(); return l; return l; } } void SHAPE_LINE_CHAIN::Replace( int start_index, int end_index, const VECTOR2I& aP) void SHAPE_LINE_CHAIN::Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP ) { { if(end_index < 0) if( aEndIndex < 0 ) end_index += PointCount(); aEndIndex += PointCount(); if(start_index < 0) if( aStartIndex < 0 ) start_index += PointCount(); aStartIndex += PointCount(); if (start_index == end_index) if( aStartIndex == aEndIndex ) m_points [start_index] = aP; m_points [aStartIndex] = aP; else { else m_points.erase (m_points.begin() + start_index + 1, m_points.begin() + end_index + 1); { m_points [start_index] = aP; m_points.erase( m_points.begin() + aStartIndex + 1, m_points.begin() + aEndIndex + 1 ); m_points[aStartIndex] = aP; } } } } void SHAPE_LINE_CHAIN::Replace( int start_index, int end_index, const SHAPE_LINE_CHAIN& aLine) void SHAPE_LINE_CHAIN::Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine ) { { if(end_index < 0) if( aEndIndex < 0 ) end_index += PointCount(); aEndIndex += PointCount(); if(start_index < 0) if( aStartIndex < 0 ) start_index += PointCount(); aStartIndex += PointCount(); m_points.erase (m_points.begin() + start_index, m_points.begin() + end_index + 1); m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 ); m_points.insert (m_points.begin() + start_index, aLine.m_points.begin(), aLine.m_points.end()); m_points.insert( m_points.begin() + aStartIndex, aLine.m_points.begin(), aLine.m_points.end() ); } } void SHAPE_LINE_CHAIN::Remove( int start_index, int end_index) void SHAPE_LINE_CHAIN::Remove( int aStartIndex, int aEndIndex ) { { if(end_index < 0) if(aEndIndex < 0) end_index += PointCount(); aEndIndex += PointCount(); if(start_index < 0) if(aStartIndex < 0) start_index += PointCount(); aStartIndex += PointCount(); m_points.erase (m_points.begin() + start_index, m_points.begin() + end_index + 1); m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 ); } } int SHAPE_LINE_CHAIN::Distance( const VECTOR2I& aP ) const int SHAPE_LINE_CHAIN::Distance( const VECTOR2I& aP ) const { { int d = INT_MAX; int d = INT_MAX; for( int s = 0; s < SegmentCount(); s++ ) for( int s = 0; s < SegmentCount(); s++ ) d = min( d, CSegment( s ).Distance( aP ) ); d = min( d, CSegment( s ).Distance( aP ) ); return d; return d; } } int SHAPE_LINE_CHAIN::Split( const VECTOR2I& aP ) int SHAPE_LINE_CHAIN::Split( const VECTOR2I& aP ) { { int ii = -1; int ii = -1; Loading Loading @@ -150,41 +161,49 @@ int SHAPE_LINE_CHAIN::Split( const VECTOR2I & aP ) if( ii >= 0 ) if( ii >= 0 ) { { m_points.insert( m_points.begin() + ii + 1, aP ); m_points.insert( m_points.begin() + ii + 1, aP ); return ii + 1; return ii + 1; } } return -1; return -1; } } int SHAPE_LINE_CHAIN::Find( const VECTOR2I& aP ) const int SHAPE_LINE_CHAIN::Find( const VECTOR2I& aP ) const { { for( int s = 0; s< PointCount(); s++ ) for( int s = 0; s< PointCount(); s++ ) if( CPoint( s ) == aP ) if( CPoint( s ) == aP ) return s; return s; return -1; return -1; } } const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int start_index, int end_index ) const const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int aStartIndex, int aEndIndex ) const { { SHAPE_LINE_CHAIN rv; SHAPE_LINE_CHAIN rv; if(end_index < 0) if( aEndIndex < 0 ) end_index += PointCount(); aEndIndex += PointCount(); if(start_index < 0) if( aStartIndex < 0 ) start_index += PointCount(); aStartIndex += PointCount(); for(int i = start_index; i<= end_index; i++) for( int i = aStartIndex; i <= aEndIndex; i++ ) rv.Append( m_points[i] ); rv.Append( m_points[i] ); return rv; return rv; } } struct compareOriginDistance { struct compareOriginDistance { compareOriginDistance( VECTOR2I& aOrigin ): compareOriginDistance( VECTOR2I& aOrigin ): m_origin( aOrigin ) {}; m_origin( aOrigin ) {}; bool operator()(const SHAPE_LINE_CHAIN::Intersection &a, const SHAPE_LINE_CHAIN::Intersection& b) bool operator()( const SHAPE_LINE_CHAIN::Intersection& aA, const SHAPE_LINE_CHAIN::Intersection& aB ) { { return (m_origin - a.p).EuclideanNorm() < (m_origin - b.p).EuclideanNorm(); return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm(); } } VECTOR2I m_origin; VECTOR2I m_origin; Loading @@ -208,8 +227,10 @@ int SHAPE_LINE_CHAIN::Intersect ( const SEG& aSeg, Intersections& aIp ) const compareOriginDistance comp( aSeg.a ); compareOriginDistance comp( aSeg.a ); sort( aIp.begin(), aIp.end(), comp ); sort( aIp.begin(), aIp.end(), comp ); return aIp.size(); return aIp.size(); }; } 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 ) const { { Loading @@ -228,14 +249,15 @@ BOX2I bb_other = aChain.BBox(); const SEG& b = aChain.CSegment( s2 ); const SEG& b = aChain.CSegment( s2 ); Intersection is; Intersection is; if( a.Collinear( b ) ) if( a.Collinear( b ) ) { { if( a.Contains( b.a ) ) { is.p = b.a; aIp.push_back( is ); } 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( 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.a ) ) { is.p = a.a; aIp.push_back( is ); } if( b.Contains( a.b ) ) { is.p = a.b; aIp.push_back( is ); } if( b.Contains( a.b ) ) { is.p = a.b; aIp.push_back( is ); } } else { } else { OPT_VECTOR2I p = a.Intersect( b ); OPT_VECTOR2I p = a.Intersect( b ); if( p ) if( p ) Loading @@ -252,6 +274,7 @@ BOX2I bb_other = aChain.BBox(); return aIp.size(); return aIp.size(); for( int s1 = 0; s1 < SegmentCount(); s1++ ) for( int s1 = 0; s1 < SegmentCount(); s1++ ) { for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ ) for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ ) { { const SEG& a = CSegment( s1 ); const SEG& a = CSegment( s1 ); Loading @@ -265,7 +288,8 @@ BOX2I bb_other = aChain.BBox(); is.our = a; is.our = a; is.their = b; is.their = b; aIp.push_back( is ); aIp.push_back( is ); } else if (a.Collinear(b)) } else if( a.Collinear( b ) ) { { if( a.a != b.a && a.a != b.b && b.Contains( a.a ) ) if( a.a != b.a && a.a != b.b && b.Contains( a.a ) ) { { Loading @@ -284,9 +308,12 @@ BOX2I bb_other = aChain.BBox(); } } } } } return aIp.size(); return aIp.size(); } } int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const { { int sum = 0; int sum = 0; Loading @@ -294,6 +321,7 @@ int SHAPE_LINE_CHAIN::PathLength (const VECTOR2I& aP ) const { { const SEG seg = CSegment( i ); const SEG seg = CSegment( i ); int d = seg.Distance( aP ); int d = seg.Distance( aP ); if( d <= 1 ) if( d <= 1 ) { { sum += ( aP - seg.a ).EuclideanNorm(); sum += ( aP - seg.a ).EuclideanNorm(); Loading @@ -302,29 +330,36 @@ int SHAPE_LINE_CHAIN::PathLength (const VECTOR2I& aP ) const else else sum += seg.Length(); sum += seg.Length(); } } return -1; return -1; } } bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const { { if( !m_closed || SegmentCount() < 3 ) if( !m_closed || SegmentCount() < 3 ) return false; return false; int cur = CSegment(0).Side( aP ); int cur = CSegment(0).Side( aP ); if( cur == 0 ) if( cur == 0 ) return false; return false; for( int i = 1; i < SegmentCount(); i++ ) for( int i = 1; i < SegmentCount(); i++ ) { { const SEG s = CSegment( i ); const SEG s = CSegment( i ); if( aP == s.a || aP == s.b ) // edge does not belong to the interior! if( aP == s.a || aP == s.b ) // edge does not belong to the interior! return false; return false; if( s.Side(aP) != cur ) if( s.Side(aP) != cur ) return false; return false; } } return true; return true; } } bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP ) const bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP ) const { { if( SegmentCount() < 1 ) if( SegmentCount() < 1 ) Loading @@ -333,18 +368,22 @@ bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP) const for( int i = 1; i < SegmentCount(); i++ ) for( int i = 1; i < SegmentCount(); i++ ) { { const SEG s = CSegment( i ); const SEG s = CSegment( i ); if( s.a == aP || s.b == aP ) if( s.a == aP || s.b == aP ) return true; return true; if( s.Distance(aP) <= 1 ) if( s.Distance(aP) <= 1 ) return true; return true; } } return false; return false; } } const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersecting() const const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersecting() const { { for( int s1 = 0; s1 < SegmentCount(); s1++ ) for( int s1 = 0; s1 < SegmentCount(); s1++ ) { for( int s2 = s1 + 1; s2 < SegmentCount(); s2++ ) for( int s2 = s1 + 1; s2 < SegmentCount(); s2++ ) { { const VECTOR2I s2a = CSegment( s2 ).a, s2b = CSegment( s2 ).b; const VECTOR2I s2a = CSegment( s2 ).a, s2b = CSegment( s2 ).b; Loading @@ -355,14 +394,17 @@ const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersectin is.their = CSegment( s2 ); is.their = CSegment( s2 ); is.p = s2a; is.p = s2a; return is; return is; } else if (CSegment(s1).Contains(s2b)) { } else if( CSegment( s1 ).Contains(s2b ) ) { Intersection is; Intersection is; is.our = CSegment( s1 ); is.our = CSegment( s1 ); is.their = CSegment( s2 ); is.their = CSegment( s2 ); is.p = s2b; is.p = s2b; return is; return is; } } else { else { OPT_VECTOR2I p = CSegment( s1 ).Intersect( CSegment( s2 ), true ); OPT_VECTOR2I p = CSegment( s1 ).Intersect( CSegment( s2 ), true ); if( p ) if( p ) Loading @@ -375,6 +417,8 @@ const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersectin } } } } } } } return optional<Intersection>(); return optional<Intersection>(); } } Loading @@ -386,9 +430,12 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() if( PointCount() < 2 ) if( PointCount() < 2 ) { { return *this; return *this; } else if (PointCount() == 2) { } else if( PointCount() == 2 ) { if( m_points[0] == m_points[1] ) if( m_points[0] == m_points[1] ) m_points.erase( m_points.end() ); m_points.erase( m_points.end() ); return *this; return *this; } } Loading @@ -401,6 +448,7 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() int j = i + 1; int j = i + 1; while( j < np && CPoint(i) == CPoint( j ) ) while( j < np && CPoint(i) == CPoint( j ) ) j++; j++; pts_unique.push_back( CPoint( i ) ); pts_unique.push_back( CPoint( i ) ); i = j; i = j; } } Loading @@ -415,27 +463,32 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() const VECTOR2I p0 = pts_unique[i]; const VECTOR2I p0 = pts_unique[i]; const VECTOR2I p1 = pts_unique[i+1]; const VECTOR2I p1 = pts_unique[i+1]; int n = i; int n = i; while( n < np - 2 && SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1 ) while( n < np - 2 && SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1 ) n++; n++; m_points.push_back( p0 ); m_points.push_back( p0 ); if( n > i ) if( n > i ) i = n; i = n; if( n == np ) if( n == np ) { { m_points.push_back( pts_unique[n - 1] ); m_points.push_back( pts_unique[n - 1] ); return *this; return *this; } } i++; i++; } } if( np > 1 ) if( np > 1 ) m_points.push_back( pts_unique[np - 2] ); m_points.push_back( pts_unique[np - 2] ); m_points.push_back( pts_unique[np - 1] ); m_points.push_back( pts_unique[np - 1] ); return *this; return *this; } } const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint( const VECTOR2I& aP ) const const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint( const VECTOR2I& aP ) const { { int min_d = INT_MAX; int min_d = INT_MAX; Loading @@ -449,9 +502,11 @@ const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint(const VECTOR2I& aP) const nearest = i; nearest = i; } } } } return CSegment( nearest ).NearestPoint( aP ); return CSegment( nearest ).NearestPoint( aP ); } } const string SHAPE_LINE_CHAIN::Format() const const string SHAPE_LINE_CHAIN::Format() const { { stringstream ss; stringstream ss; Loading