router: another attempt at improving 'kink' robustness of the hull generator
This commit is contained in:
parent
58f9b82c1e
commit
f5fe1d5462
|
@ -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 )
|
||||||
|
|
Loading…
Reference in New Issue