Pcbnew: fix some issues with very small arcs (size a few internal units)

these very small arcs do not allow to calculate a reliable center position,
and therefore a reliable radius.
So seeing them as a very small segment fix plotting/drawing issues.
Fixes #15639
https://gitlab.com/kicad/code/kicad/-/issues/15639
This commit is contained in:
jean-pierre charras 2023-09-13 17:54:57 +02:00
parent acb2de0554
commit 2c10d5e3a0
4 changed files with 44 additions and 2 deletions

View File

@ -286,6 +286,19 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
{
const PCB_ARC* arc = static_cast<const PCB_ARC*>( aTrack );
if( arc->IsDegenerated() )
{
// Draw this very small arc like a track segment (a PCB_TRACE_T)
PCB_TRACK track( arc->GetParent() );
track.SetStart( arc->GetStart() );
track.SetEnd( arc->GetEnd() );
track.SetWidth( arc->GetWidth() );
track.SetLayer( arc->GetLayer() );
createTrack( &track, aDstContainer );
return;
}
VECTOR2D center( arc->GetCenter() );
EDA_ANGLE arc_angle = arc->GetAngle();
double radius = arc->GetRadius();

View File

@ -1171,6 +1171,16 @@ EDA_ANGLE PCB_ARC::GetArcAngleEnd() const
return angleEnd.Normalize();
}
bool PCB_ARC::IsDegenerated( int aThreshold ) const
{
// Too small arcs cannot be really handled: arc center (and arc radius)
// cannot be safely computed if the distance between mid and end points
// is too small (a few internal units)
return ( GetMid() - GetStart() ).EuclideanNorm() < aThreshold
|| ( GetMid() - GetEnd() ).EuclideanNorm() < aThreshold;
}
bool PCB_TRACK::cmp_tracks::operator() ( const PCB_TRACK* a, const PCB_TRACK* b ) const
{

View File

@ -352,6 +352,14 @@ public:
EDA_ITEM* Clone() const override;
/**
* @return true if the arc is too small to allow a safe calculation
* of center position and arc angles i.e if distance between m_Mid and each arc end
* is only a few internal units.
* @param aThreshold is the minimal dist in internal units. Default id 5 IU
*/
bool IsDegenerated( int aThreshold = 5 ) const;
protected:
virtual void swapData( BOARD_ITEM* aImage ) override;

View File

@ -645,8 +645,19 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
{
const PCB_ARC* arc = static_cast<const PCB_ARC*>( track );
aPlotter->ThickArc( arc->GetCenter(), arc->GetArcAngleStart(), arc->GetAngle(),
arc->GetRadius(), width, plotMode, &gbr_metadata );
// Too small arcs cannot be really handled: arc center (and arc radius)
// cannot be safely computed
if( !arc->IsDegenerated( 10 /* in IU */ ) )
{
aPlotter->ThickArc( arc->GetCenter(), arc->GetArcAngleStart(), arc->GetAngle(),
arc->GetRadius(), width, plotMode, &gbr_metadata );
}
else
{
// Approximate this very small arc by a segment.
aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode,
&gbr_metadata );
}
}
else
{