From 1122d80388793846ea6eb8455b476a8acd7622be Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop Date: Wed, 31 Jan 2024 23:38:05 +0300 Subject: [PATCH] Better support for arcs in tuning patterns. --- libs/kimath/include/geometry/shape_arc.h | 2 ++ libs/kimath/src/geometry/shape_arc.cpp | 23 +++++++++++++++++ pcbnew/generators/pcb_tuning_pattern.cpp | 32 +++++++++++++++--------- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/libs/kimath/include/geometry/shape_arc.h b/libs/kimath/include/geometry/shape_arc.h index 526b494802..ce306c44fd 100644 --- a/libs/kimath/include/geometry/shape_arc.h +++ b/libs/kimath/include/geometry/shape_arc.h @@ -116,6 +116,8 @@ public: 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, VECTOR2I* aLocation = nullptr ) const override; bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr, diff --git a/libs/kimath/src/geometry/shape_arc.cpp b/libs/kimath/src/geometry/shape_arc.cpp index 2257620961..f59b42be5a 100644 --- a/libs/kimath/src/geometry/shape_arc.cpp +++ b/libs/kimath/src/geometry/shape_arc.cpp @@ -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, VECTOR2I* aLocation ) const { diff --git a/pcbnew/generators/pcb_tuning_pattern.cpp b/pcbnew/generators/pcb_tuning_pattern.cpp index a73a60cafc..75245da07a 100644 --- a/pcbnew/generators/pcb_tuning_pattern.cpp +++ b/pcbnew/generators/pcb_tuning_pattern.cpp @@ -597,9 +597,22 @@ static VECTOR2I snapToNearestTrack( const VECTOR2I& aP, BOARD* aBoard, NETINFO_I if( aNet && track->GetNet() != aNet ) continue; - SEG seg( track->GetStart(), track->GetEnd() ); + VECTOR2I nearest; + + if( track->Type() == PCB_ARC_T ) + { + PCB_ARC* pcbArc = static_cast( 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(); 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 ) { - SEG::ecoord d0 = ( item->Anchor( 0 ) - aWhere ).SquaredEuclideanNorm(); - SEG::ecoord d1 = ( item->Anchor( 1 ) - aWhere ).SquaredEuclideanNorm(); + PNS::ARC* pnsArc = static_cast( item ); + + VECTOR2I nearest = pnsArc->Arc().NearestPoint( aWhere ); + SEG::ecoord d0 = ( nearest - aWhere ).SquaredEuclideanNorm(); if( d0 <= dist[1] ) { prioritized[1] = linked; dist[1] = d0; - point[1] = item->Anchor( 0 ); - } - - if( d1 <= dist[1] ) - { - prioritized[1] = linked; - dist[1] = d1; - point[1] = item->Anchor( 1 ); + point[1] = nearest; } } else if( item->Kind() & PNS::ITEM::SEGMENT_T )