Browse Source

Treat straight arcs as segments

When an arc has a very small curvature, we should not waste time with
the arc collision mode and instead just use the segment collision as it
is effectively the same result

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19422
pcb_db
Seth Hillbrand 9 months ago
parent
commit
8724a7da09
  1. 2
      libs/kimath/include/geometry/shape_arc.h
  2. 9
      libs/kimath/src/geometry/shape_arc.cpp
  3. 14
      libs/kimath/src/geometry/shape_collisions.cpp
  4. 7
      pcbnew/pcb_track.cpp

2
libs/kimath/include/geometry/shape_arc.h

@ -175,6 +175,8 @@ public:
return true;
}
bool IsEffectiveLine() const;
void Move( const VECTOR2I& aVector ) override;
/**

9
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();

14
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() ) );

7
pcbnew/pcb_track.cpp

@ -1982,7 +1982,12 @@ std::shared_ptr<SHAPE> PCB_ARC::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING
if( IsSolderMaskLayer( aLayer ) )
width += 2 * GetSolderMaskExpansion();
return std::make_shared<SHAPE_ARC>( GetStart(), GetMid(), GetEnd(), width );
SHAPE_ARC arc( GetStart(), GetMid(), GetEnd(), width );
if( arc.IsEffectiveLine() )
return std::make_shared<SHAPE_SEGMENT>( GetStart(), GetEnd(), width );
return std::make_shared<SHAPE_ARC>( arc );
}

Loading…
Cancel
Save