PNS: Calculate diff pair primitive orientation using anchors only

The previous method fails if the primitive is an expanding or
contracting pair (diagonals going inward or outward) resulting in
incorrect orientation, which then leads to incorrect candidate
gateways being generated and no solution found.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/8185
This commit is contained in:
Jon Evans 2021-04-12 20:34:44 -04:00
parent 94fad2944d
commit 73fb85a352
1 changed files with 11 additions and 22 deletions

View File

@ -114,43 +114,32 @@ DIRECTION_45 DP_PRIMITIVE_PAIR::anchorDirection( const ITEM* aItem, const VECTOR
return DIRECTION_45( aItem->Anchor( 1 ) - aItem->Anchor( 0 ) ); return DIRECTION_45( aItem->Anchor( 1 ) - aItem->Anchor( 0 ) );
} }
void DP_PRIMITIVE_PAIR::CursorOrientation( const VECTOR2I& aCursorPos, VECTOR2I& aMidpoint, VECTOR2I& aDirection ) const void DP_PRIMITIVE_PAIR::CursorOrientation( const VECTOR2I& aCursorPos, VECTOR2I& aMidpoint,
VECTOR2I& aDirection ) const
{ {
assert( m_primP && m_primN ); assert( m_primP && m_primN );
VECTOR2I aP, aN, dir, midpoint; VECTOR2I aP, aN, dir, midpoint;
if ( m_primP->OfKind( ITEM::SEGMENT_T ) && m_primN->OfKind( ITEM::SEGMENT_T ) ) if( m_primP->OfKind( ITEM::SEGMENT_T ) && m_primN->OfKind( ITEM::SEGMENT_T ) )
{ {
aP = m_primP->Anchor( 1 ); aP = m_primP->Anchor( 1 );
aN = m_primN->Anchor( 1 ); aN = m_primN->Anchor( 1 );
midpoint = ( aP + aN ) / 2; midpoint = ( aP + aN ) / 2;
SEG s = static_cast <SEGMENT*>( m_primP )->Seg(); dir = ( aP - aN ).Perpendicular();
if ( s.B != s.A )
{
dir = s.B - s.A;
}
else
{
dir = VECTOR2I( 0, 1 );
}
dir = dir.Resize( ( aP - aN ).EuclideanNorm() );
} }
else else
{ {
aP = m_primP->Anchor( 0 ); aP = m_primP->Anchor( 0 );
aN = m_primN->Anchor( 0 ); aN = m_primN->Anchor( 0 );
midpoint = ( aP + aN ) / 2; midpoint = ( aP + aN ) / 2;
dir = ( aP - aN ).Perpendicular(); dir = ( aP - aN ).Perpendicular();
if ( dir.Dot( aCursorPos - midpoint ) < 0 ) if( dir.Dot( aCursorPos - midpoint ) < 0 )
dir = -dir; dir = -dir;
} }
aMidpoint = midpoint; aMidpoint = midpoint;
aDirection = dir; aDirection = dir;
} }