Better support for arcs in tuning patterns.

This commit is contained in:
Alex Shvartzkop 2024-01-31 23:38:05 +03:00
parent 7d1888c756
commit 1122d80388
3 changed files with 45 additions and 12 deletions

View File

@ -116,6 +116,8 @@ public:
const BOX2I BBox( int aClearance = 0 ) const override; const BOX2I BBox( int aClearance = 0 ) const override;
VECTOR2I NearestPoint( const VECTOR2I& aP ) const;
bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr, bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr,
VECTOR2I* aLocation = nullptr ) const override; VECTOR2I* aLocation = nullptr ) const override;
bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr, bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr,

View File

@ -370,6 +370,29 @@ bool SHAPE_ARC::IsClockwise() const
} }
VECTOR2I SHAPE_ARC::NearestPoint( const VECTOR2I& aP ) const
{
const static int s_epsilon = 8;
CIRCLE fullCircle( GetCenter(), GetRadius() );
VECTOR2I nearestPt = fullCircle.NearestPoint( aP );
if( ( nearestPt - m_start ).SquaredEuclideanNorm() <= s_epsilon )
return m_start;
if( ( nearestPt - m_end ).SquaredEuclideanNorm() <= s_epsilon )
return m_end;
if( sliceContainsPoint( nearestPt ) )
return nearestPt;
if( ( aP - m_start ).SquaredEuclideanNorm() <= ( aP - m_end ).SquaredEuclideanNorm() )
return m_start;
else
return m_end;
}
bool SHAPE_ARC::Collide( const VECTOR2I& aP, int aClearance, int* aActual, bool SHAPE_ARC::Collide( const VECTOR2I& aP, int aClearance, int* aActual,
VECTOR2I* aLocation ) const VECTOR2I* aLocation ) const
{ {

View File

@ -597,9 +597,22 @@ static VECTOR2I snapToNearestTrack( const VECTOR2I& aP, BOARD* aBoard, NETINFO_I
if( aNet && track->GetNet() != aNet ) if( aNet && track->GetNet() != aNet )
continue; continue;
SEG seg( track->GetStart(), track->GetEnd() ); VECTOR2I nearest;
if( track->Type() == PCB_ARC_T )
{
PCB_ARC* pcbArc = static_cast<PCB_ARC*>( track );
SHAPE_ARC arc( pcbArc->GetStart(), pcbArc->GetMid(), pcbArc->GetEnd(),
pcbArc->GetWidth() );
nearest = arc.NearestPoint( aP );
}
else
{
SEG seg( track->GetStart(), track->GetEnd() );
nearest = seg.NearestPoint( aP );
}
VECTOR2I nearest = seg.NearestPoint( aP );
SEG::ecoord dist_sq = ( nearest - aP ).SquaredEuclideanNorm(); SEG::ecoord dist_sq = ( nearest - aP ).SquaredEuclideanNorm();
if( dist_sq < minDist_sq ) if( dist_sq < minDist_sq )
@ -807,21 +820,16 @@ static PNS::LINKED_ITEM* pickSegment( PNS::ROUTER* aRouter, const VECTOR2I& aWhe
if( item->Kind() & PNS::ITEM::ARC_T ) if( item->Kind() & PNS::ITEM::ARC_T )
{ {
SEG::ecoord d0 = ( item->Anchor( 0 ) - aWhere ).SquaredEuclideanNorm(); PNS::ARC* pnsArc = static_cast<PNS::ARC*>( item );
SEG::ecoord d1 = ( item->Anchor( 1 ) - aWhere ).SquaredEuclideanNorm();
VECTOR2I nearest = pnsArc->Arc().NearestPoint( aWhere );
SEG::ecoord d0 = ( nearest - aWhere ).SquaredEuclideanNorm();
if( d0 <= dist[1] ) if( d0 <= dist[1] )
{ {
prioritized[1] = linked; prioritized[1] = linked;
dist[1] = d0; dist[1] = d0;
point[1] = item->Anchor( 0 ); point[1] = nearest;
}
if( d1 <= dist[1] )
{
prioritized[1] = linked;
dist[1] = d1;
point[1] = item->Anchor( 1 );
} }
} }
else if( item->Kind() & PNS::ITEM::SEGMENT_T ) else if( item->Kind() & PNS::ITEM::SEGMENT_T )