Sort potential start candidates by distance from cursor.

Fixes https://gitlab.com/kicad/code/kicad/issues/1926
This commit is contained in:
Jeff Young 2020-11-10 23:12:28 +00:00
parent 7e556ed91d
commit ce3b2921bd
1 changed files with 28 additions and 21 deletions

View File

@ -110,10 +110,7 @@ void TOOL_BASE::Reset( RESET_REASON aReason )
ITEM* TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer, bool aIgnorePads, ITEM* TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer, bool aIgnorePads,
const std::vector<ITEM*> aAvoidItems ) const std::vector<ITEM*> aAvoidItems )
{ {
int tl = getView()->GetTopLayer(); int tl = aLayer > 0 ? aLayer : getView()->GetTopLayer();
if( aLayer > 0 )
tl = aLayer;
static const int candidateCount = 5; static const int candidateCount = 5;
ITEM* prioritized[candidateCount]; ITEM* prioritized[candidateCount];
@ -152,25 +149,37 @@ ITEM* TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer, b
if( item->OfKind( ITEM::SOLID_T ) && aIgnorePads ) if( item->OfKind( ITEM::SOLID_T ) && aIgnorePads )
continue; continue;
SEG::ecoord itemDist = ( item->Shape()->Centre() - aWhere ).SquaredEuclideanNorm(); SEG::ecoord d = ( item->Shape()->Centre() - aWhere ).SquaredEuclideanNorm();
if( !prioritized[2] || itemDist < dist[2] ) if( d < dist[2] )
{ {
prioritized[2] = item; prioritized[2] = item;
dist[2] = itemDist; dist[2] = d;
} }
if( item->Layers().Overlaps( tl ) && itemDist < dist[0] )
if( item->Layers().Overlaps( tl ) && d < dist[0] )
{ {
prioritized[0] = item; prioritized[0] = item;
dist[0] = itemDist; dist[0] = d;
} }
} }
else else // ITEM::SEGMENT_T | ITEM::ARC_T
{
LINKED_ITEM* li = static_cast<LINKED_ITEM*>( item );
SEG::ecoord d = std::min( ( li->Anchor( 0 ) - aWhere ).SquaredEuclideanNorm(),
( li->Anchor( 1 ) - aWhere ).SquaredEuclideanNorm() );
if( d < dist[3] )
{ {
if( !prioritized[3] )
prioritized[3] = item; prioritized[3] = item;
if( item->Layers().Overlaps( tl ) ) dist[3] = d;
}
if( item->Layers().Overlaps( tl ) && d < dist[1] )
{
prioritized[1] = item; prioritized[1] = item;
dist[1] = d;
}
} }
} }
// Allow unconnected items as last resort in RM_MarkObstacles mode // Allow unconnected items as last resort in RM_MarkObstacles mode
@ -383,17 +392,15 @@ const VECTOR2I TOOL_BASE::snapToItem( bool aEnabled, ITEM* aItem, VECTOR2I aP)
case ITEM::ARC_T: case ITEM::ARC_T:
{ {
LINKED_ITEM* li = static_cast<LINKED_ITEM*>( aItem ); LINKED_ITEM* li = static_cast<LINKED_ITEM*>( aItem );
int w = li->Width(); VECTOR2I A = li->Anchor( 0 );
auto A = li->Anchor( 0 ); VECTOR2I B = li->Anchor( 1 );
auto B = li->Anchor( 1 ); SEG::ecoord w_sq = SEG::Square( li->Width() / 2 );
SEG::ecoord distA_sq = ( aP - A ).SquaredEuclideanNorm();
SEG::ecoord distB_sq = ( aP - B ).SquaredEuclideanNorm();
if( ( aP - A ).EuclideanNorm() < w / 2 ) if( distA_sq < w_sq || distB_sq < w_sq )
{ {
anchor = A; anchor = distA_sq < distB_sq ? A : B;
}
else if( ( aP - B ).EuclideanNorm() < w / 2 )
{
anchor = B;
} }
else // TODO(snh): Clean this up else // TODO(snh): Clean this up
{ {