PNS: Make DIRECTION_45 North be up everywhere

Fixes https://gitlab.com/kicad/code/kicad/-/issues/6935
This commit is contained in:
Jon Evans 2021-01-06 21:47:06 -05:00
parent eef16fe717
commit 0234b7278a
2 changed files with 41 additions and 25 deletions

View File

@ -39,9 +39,10 @@ class DIRECTION_45
public:
/**
* Enum Directions
* Represents available directions - there are 8 of them, as on a rectilinear map (north = up) +
* an extra undefined direction, reserved for traces that don't respect 45-degree routing regime.
* NOTE: North represents "up" to the user looking at the application, which is the negative-y
* direction in the world coordinate space!
*/
enum Directions : int
{
@ -75,11 +76,13 @@ public:
/**
* Constructor
* @param aVec vector, whose direction will be translated into a DIRECTION_45.
* @param aVec vector in world space, whose direction will be translated into a DIRECTION_45.
*/
DIRECTION_45( const VECTOR2I &aVec, bool a90 = false ) :
m_90deg( a90 )
{
VECTOR2I vec( aVec );
vec.y = -vec.y;
construct_( aVec );
}
@ -90,8 +93,9 @@ public:
DIRECTION_45( const SEG& aSeg, bool a90 = false ) :
m_90deg( a90 )
{
construct_( aSeg.B - aSeg.A );
VECTOR2I vec( aSeg.B - aSeg.A );
vec.y = -vec.y;
construct_( vec );
}
/**
@ -101,7 +105,9 @@ public:
DIRECTION_45( const SHAPE_ARC& aArc, bool a90 = false ) :
m_90deg( a90 )
{
construct_( aArc.GetP1() - aArc.GetP0() );
VECTOR2I vec( aArc.GetP1() - aArc.GetP0() );
vec.y = -vec.y;
construct_( vec );
}
/**

View File

@ -897,17 +897,10 @@ bool LINE_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
// direction so that the posture solver is not biased.
SEG seg = static_cast<SEGMENT*>( aStartItem )->Seg();
// NOTE: have to flip this over at the moment because DIRECTION_45(SEG) assumes +y is
// North but a SEG will have -y be North in KiCad world coordinate system.
// This should probably be fixed in DIRECTION_45 but it's used in a lot of PNS code
// that would need to be checked carefully for such a change...
seg.A.y = -seg.A.y;
seg.B.y = -seg.B.y;
if( aP == seg.A )
lastSegDir = DIRECTION_45( seg );
else if( aP == seg.B )
lastSegDir = DIRECTION_45( seg.Reversed() );
else if( aP == seg.B )
lastSegDir = DIRECTION_45( seg );
}
else if( aStartItem && aStartItem->Kind() == ITEM::SOLID_T &&
static_cast<SOLID*>( aStartItem )->Parent()->Type() == PCB_PAD_T )
@ -917,6 +910,8 @@ bool LINE_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
initialDir = DIRECTION_45( static_cast<DIRECTION_45::Directions>( int( angle ) ) );
}
wxLogTrace( "PNS", "Posture: init %s, last seg %s", initialDir.Format(), lastSegDir.Format() );
m_postureSolver.Clear();
m_postureSolver.AddTrailPoint( aP );
m_postureSolver.SetTolerance( m_head.Width() );
@ -1100,8 +1095,6 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis
// TODO: lastDirSeg will be calculated incorrectly if we end on an arc
SEG lastDirSeg = ( !fixAll && l.SegmentCount() > 1 ) ? l.CSegment( -2 ) : l.CSegment( -1 );
lastDirSeg.A.y = -lastDirSeg.A.y;
lastDirSeg.B.y = -lastDirSeg.B.y;
DIRECTION_45 d_last( lastDirSeg );
int lastV;
@ -1589,6 +1582,7 @@ DIRECTION_45 POSTURE_SOLVER::GetPosture( const VECTOR2I& aP )
// in this case, we cancel any forced posture and restart the trail
if( m_forced && refLength < unlockDistanceFactor * m_tolerance )
{
wxLogTrace( "PNS", "Posture: Unlocked and reset" );
m_forced = false;
VECTOR2I start = p0;
m_trail.Clear();
@ -1613,15 +1607,8 @@ DIRECTION_45 POSTURE_SOLVER::GetPosture( const VECTOR2I& aP )
DIRECTION_45 diagDirection;
DIRECTION_45 newDirection = m_direction;
SEG seg = straight.CSegment( 0 );
seg.A.y = -seg.A.y;
seg.B.y = -seg.B.y;
straightDirection = DIRECTION_45( seg );
seg = diag.CSegment( 0 );
seg.A.y = -seg.A.y;
seg.B.y = -seg.B.y;
diagDirection = DIRECTION_45( seg );
straightDirection = DIRECTION_45( straight.CSegment( 0 ) );
diagDirection = DIRECTION_45( diag.CSegment( 0 ) );
if( !m_forced && areaOk && ratio > areaRatioThreshold + areaRatioEpsilon )
newDirection = diagDirection;
@ -1630,6 +1617,12 @@ DIRECTION_45 POSTURE_SOLVER::GetPosture( const VECTOR2I& aP )
else
newDirection = m_direction.IsDiagonal() ? diagDirection : straightDirection;
if( newDirection != m_direction )
{
wxLogTrace( "PNS", "Posture: direction update %s => %s", m_direction.Format(),
newDirection.Format() );
}
m_direction = newDirection;
// If we have a last segment, correct the direction relative to it. For segment exit, we want
@ -1638,10 +1631,20 @@ DIRECTION_45 POSTURE_SOLVER::GetPosture( const VECTOR2I& aP )
{
if( straightDirection == m_lastSegDirection )
{
if( m_direction != straightDirection )
{
wxLogTrace( "PNS", "Posture: forcing straight => %s", straightDirection.Format() );
}
m_direction = straightDirection;
}
else if( diagDirection == m_lastSegDirection )
{
if( m_direction != straightDirection )
{
wxLogTrace( "PNS", "Posture: forcing diagonal => %s", diagDirection.Format() );
}
m_direction = diagDirection;
}
else
@ -1651,6 +1654,7 @@ DIRECTION_45 POSTURE_SOLVER::GetPosture( const VECTOR2I& aP )
case DIRECTION_45::ANG_HALF_FULL:
// Force a better (acute) connection
m_direction = m_direction.IsDiagonal() ? straightDirection : diagDirection;
wxLogTrace( "PNS", "Posture: correcting half full => %s", m_direction.Format() );
break;
case DIRECTION_45::ANG_ACUTE:
@ -1660,7 +1664,10 @@ DIRECTION_45 POSTURE_SOLVER::GetPosture( const VECTOR2I& aP )
: diagDirection;
if( candidate.Angle( m_lastSegDirection ) == DIRECTION_45::ANG_RIGHT )
{
wxLogTrace( "PNS", "Posture: correcting right => %s", candidate.Format() );
m_direction = candidate;
}
break;
}
@ -1672,7 +1679,10 @@ DIRECTION_45 POSTURE_SOLVER::GetPosture( const VECTOR2I& aP )
: diagDirection;
if( candidate.Angle( m_lastSegDirection ) == DIRECTION_45::ANG_OBTUSE )
{
wxLogTrace( "PNS", "Posture: correcting obtuse => %s", candidate.Format() );
m_direction = candidate;
}
break;
}