diff --git a/libs/kimath/include/geometry/shape_arc.h b/libs/kimath/include/geometry/shape_arc.h index 6056188580..7cee47eeec 100644 --- a/libs/kimath/include/geometry/shape_arc.h +++ b/libs/kimath/include/geometry/shape_arc.h @@ -175,6 +175,8 @@ public: return true; } + bool IsEffectiveLine() const; + void Move( const VECTOR2I& aVector ) override; /** diff --git a/libs/kimath/src/geometry/shape_arc.cpp b/libs/kimath/src/geometry/shape_arc.cpp index 96794e2146..83648ee32b 100644 --- a/libs/kimath/src/geometry/shape_arc.cpp +++ b/libs/kimath/src/geometry/shape_arc.cpp @@ -241,6 +241,15 @@ SHAPE_ARC& SHAPE_ARC::ConstructFromStartEndCenter( const VECTOR2I& aStart, const } +bool SHAPE_ARC::IsEffectiveLine() const +{ + SEG v1 = SEG( m_start, m_mid ); + SEG v2 = SEG( m_mid, m_end ); + + return v1.ApproxCollinear( v2 ); +} + + bool SHAPE_ARC::Collide( const SEG& aSeg, int aClearance, int* aActual, VECTOR2I* aLocation ) const { VECTOR2I center = GetCenter(); diff --git a/libs/kimath/src/geometry/shape_collisions.cpp b/libs/kimath/src/geometry/shape_collisions.cpp index 96c94e1362..7e3896b181 100644 --- a/libs/kimath/src/geometry/shape_collisions.cpp +++ b/libs/kimath/src/geometry/shape_collisions.cpp @@ -651,6 +651,13 @@ static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_SEGMENT& aB, int aC aA.TypeName(), aB.TypeName() ) ); + // If the arc radius is too large, it is effectively a line segment + if( aA.IsEffectiveLine() ) + { + SHAPE_SEGMENT tmp( aA.GetP0(), aA.GetP1(), aA.GetWidth() ); + return Collide( tmp, aB, aClearance, aActual, aLocation, aMTV ); + } + bool rv = aA.Collide( aB.GetSeg(), aClearance + aB.GetWidth() / 2, aActual, aLocation ); if( rv && aActual ) @@ -663,6 +670,13 @@ static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_SEGMENT& aB, int aC static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_LINE_CHAIN_BASE& aB, int aClearance, int* aActual, VECTOR2I* aLocation, VECTOR2I* aMTV ) { + // If the arc radius is too large, it is effectively a line segment + if( aA.IsEffectiveLine() ) + { + SHAPE_SEGMENT tmp( aA.GetP0(), aA.GetP1(), aA.GetWidth() ); + return Collide( aB, tmp, aClearance, aActual, aLocation, aMTV ); + } + wxASSERT_MSG( !aMTV, wxString::Format( wxT( "MTV not implemented for %s : %s collisions" ), aA.TypeName(), aB.TypeName() ) ); diff --git a/pcbnew/pcb_track.cpp b/pcbnew/pcb_track.cpp index 27093b8de1..f65cf095de 100644 --- a/pcbnew/pcb_track.cpp +++ b/pcbnew/pcb_track.cpp @@ -1982,7 +1982,12 @@ std::shared_ptr PCB_ARC::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING if( IsSolderMaskLayer( aLayer ) ) width += 2 * GetSolderMaskExpansion(); - return std::make_shared( GetStart(), GetMid(), GetEnd(), width ); + SHAPE_ARC arc( GetStart(), GetMid(), GetEnd(), width ); + + if( arc.IsEffectiveLine() ) + return std::make_shared( GetStart(), GetEnd(), width ); + + return std::make_shared( arc ); }