router: another attempt at improving 'kink' robustness of the hull generator

This commit is contained in:
Tomasz Wlostowski 2022-06-09 20:51:14 +02:00
parent 58f9b82c1e
commit f5fe1d5462
1 changed files with 59 additions and 15 deletions

View File

@ -23,6 +23,7 @@
#include "pns_line.h" #include "pns_line.h"
#include "pns_via.h" #include "pns_via.h"
#include "pns_router.h" #include "pns_router.h"
#include "pns_debug_decorator.h"
#include <geometry/shape_arc.h> #include <geometry/shape_arc.h>
#include <geometry/shape_segment.h> #include <geometry/shape_segment.h>
@ -143,18 +144,20 @@ const SHAPE_LINE_CHAIN ArcHull( const SHAPE_ARC& aSeg, int aClearance, int aWalk
static bool IsSegment45Degree( const SEG& aS ) static bool IsSegment45Degree( const SEG& aS )
{ {
double angle = 180.0 / M_PI VECTOR2I dir( aS.B - aS.A );
* atan2( (double) aS.B.y - (double) aS.A.y, (double) aS.B.x - (double) aS.A.x );
if( angle < 0 ) if( std::abs( dir.x ) <= 1 )
angle += 360.0; return true;
if( std::abs( dir.y ) <= 1 )
return true;
int delta = std::abs(dir.x) - std::abs(dir.y);
double angle_a = fabs( fmod( angle, 45.0 ) ); if( delta >= -1 && delta <= 1)
return true;
if( angle_a > 1.0 && angle_a < 44.0 ) return false;
return false;
return true;
} }
@ -166,7 +169,7 @@ template <typename T> int sgn(T val) {
const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance, const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance,
int aWalkaroundThickness ) int aWalkaroundThickness )
{ {
const int kinkThreshold = 10; const int kinkThreshold = aClearance / 10;
int cl = aClearance + aWalkaroundThickness / 2; int cl = aClearance + aWalkaroundThickness / 2;
double d = (double)aSeg.GetWidth() / 2.0 + cl; double d = (double)aSeg.GetWidth() / 2.0 + cl;
@ -178,15 +181,56 @@ const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance,
const VECTOR2I a = aSeg.GetSeg().A; const VECTOR2I a = aSeg.GetSeg().A;
VECTOR2I b = aSeg.GetSeg().B; VECTOR2I b = aSeg.GetSeg().B;
int len = aSeg.GetSeg().Length(); int len = aSeg.GetSeg().Length();
int w = b.x - a.x;
int h = b.y - a.y;
if ( !IsSegment45Degree( aSeg.GetSeg() ) && len <= kinkThreshold && len > 0 ) /*
auto dbg = ROUTER::GetInstance()->GetInterface()->GetDebugDecorator();
if( len < kinkThreshold )
{ {
PNS_DBG( dbg, AddShape, &aSeg, CYAN, 10000, wxString::Format( "kinky-seg 45 %d l %d dx %d dy %d", !!IsSegment45Degree( aSeg.GetSeg() ), len, w, h ) );
}
*/
int w = b.x - a.x; if ( !IsSegment45Degree( aSeg.GetSeg() ) )
int h = b.y - a.y; {
int ll = std::max( std::abs( w ), std::abs( h ) ); if ( len <= kinkThreshold && len > 0 )
{
int ll = std::max( std::abs( w ), std::abs( h ) );
b = a + VECTOR2I( sgn( w ) * ll, sgn( h ) * ll ); b = a + VECTOR2I( sgn( w ) * ll, sgn( h ) * ll );
}
}
else
{
if( len <= kinkThreshold )
{
int delta45 = std::abs( std::abs(w) - std::abs(h) );
if( std::abs(w) <= 1 ) // almost vertical
{
w = 0;
cl ++;
}
else if ( std::abs(h) <= 1 ) // almost horizontal
{
h = 0;
cl ++;
}
else if ( delta45 <= 2 ) // almost 45 degree
{
int newW = sgn( w ) * std::max( std::abs(w), std::abs( h ) );
int newH = sgn( h ) * std::max( std::abs(w), std::abs( h ) );
w = newW;
h = newH;
cl += 2;
//PNS_DBG( dbg, AddShape, &aSeg, CYAN, 10000, wxString::Format( "almostkinky45 45 %d l %d dx %d dy %d", !!IsSegment45Degree( aSeg.GetSeg() ), len, w, h ) );
}
b.x = a.x + w;
b.y = a.y + h;
}
} }
if( a == b ) if( a == b )