router: support for non-90 degree pad orientations
This commit is contained in:
parent
4abcc159d2
commit
7724c581fd
|
@ -30,6 +30,7 @@
|
|||
#include <geometry/shape_circle.h>
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <geometry/shape_segment.h>
|
||||
#include <geometry/shape_convex.h>
|
||||
|
||||
typedef VECTOR2I::extended_type ecoord;
|
||||
|
||||
|
@ -165,6 +166,32 @@ static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN& aB,
|
|||
}
|
||||
|
||||
|
||||
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_CONVEX& aB, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
bool found;
|
||||
const SHAPE_LINE_CHAIN& lc( aB.Vertices() );
|
||||
|
||||
found = lc.Distance( aA.GetCenter() ) <= aClearance + aA.GetRadius();
|
||||
|
||||
if( !aNeedMTV || !found )
|
||||
return found;
|
||||
|
||||
SHAPE_CIRCLE cmoved( aA );
|
||||
VECTOR2I f_total( 0, 0 );
|
||||
|
||||
for( int s = 0; s < lc.SegmentCount(); s++ )
|
||||
{
|
||||
VECTOR2I f = pushoutForce( cmoved, lc.CSegment( s ), aClearance );
|
||||
cmoved.SetCenter( cmoved.GetCenter() + f );
|
||||
f_total += f;
|
||||
}
|
||||
|
||||
aMTV = f_total;
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_SEGMENT& aSeg, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
|
@ -189,6 +216,20 @@ static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_LINE_CHAIN&
|
|||
}
|
||||
|
||||
|
||||
static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_CONVEX& aB, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
return Collide( aA, aB.Vertices(), aClearance, aNeedMTV, aMTV );
|
||||
}
|
||||
|
||||
|
||||
static inline bool Collide( const SHAPE_CONVEX& aA, const SHAPE_CONVEX& aB, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
return Collide( aA.Vertices(), aB.Vertices(), aClearance, aNeedMTV, aMTV );
|
||||
}
|
||||
|
||||
|
||||
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
|
@ -204,6 +245,13 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, in
|
|||
}
|
||||
|
||||
|
||||
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_CONVEX& aB, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
return Collide( aA, aB.Vertices(), aClearance, aNeedMTV, aMTV );
|
||||
}
|
||||
|
||||
|
||||
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_SEGMENT& aSeg, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
|
@ -228,6 +276,13 @@ static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_SEGMENT& aB,
|
|||
}
|
||||
|
||||
|
||||
static inline bool Collide( const SHAPE_CONVEX& aA, const SHAPE_SEGMENT& aB, int aClearance,
|
||||
bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
return Collide( aA.Vertices(), aB, aClearance, aNeedMTV, aMTV );
|
||||
}
|
||||
|
||||
|
||||
template<class ShapeAType, class ShapeBType>
|
||||
inline bool CollCase( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV )
|
||||
{
|
||||
|
@ -264,6 +319,9 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
|
|||
case SH_SEGMENT:
|
||||
return CollCase<SHAPE_RECT, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_CONVEX:
|
||||
return CollCase<SHAPE_RECT, SHAPE_CONVEX>( aA, aB, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -283,6 +341,9 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
|
|||
case SH_SEGMENT:
|
||||
return CollCase<SHAPE_CIRCLE, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_CONVEX:
|
||||
return CollCase<SHAPE_CIRCLE, SHAPE_CONVEX>( aA, aB, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -302,6 +363,9 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
|
|||
case SH_SEGMENT:
|
||||
return CollCase<SHAPE_LINE_CHAIN, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_CONVEX:
|
||||
return CollCase<SHAPE_LINE_CHAIN, SHAPE_CONVEX>( aA, aB, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -321,6 +385,31 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
|
|||
case SH_SEGMENT:
|
||||
return CollCase<SHAPE_SEGMENT, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_CONVEX:
|
||||
return CollCase<SHAPE_CONVEX, SHAPE_SEGMENT>( aB, aA, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
case SH_CONVEX:
|
||||
switch( aB->Type() )
|
||||
{
|
||||
case SH_RECT:
|
||||
return CollCase<SHAPE_RECT, SHAPE_CONVEX>( aB, aA, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_CIRCLE:
|
||||
return CollCase<SHAPE_CIRCLE, SHAPE_CONVEX>( aB, aA, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_LINE_CHAIN:
|
||||
return CollCase<SHAPE_LINE_CHAIN, SHAPE_CONVEX>( aB, aA, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_SEGMENT:
|
||||
return CollCase<SHAPE_CONVEX, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
case SH_CONVEX:
|
||||
return CollCase<SHAPE_CONVEX, SHAPE_CONVEX>( aA, aB, aClearance, aNeedMTV, aMTV );
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -499,6 +499,26 @@ const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint( const VECTOR2I& aP ) const
|
|||
}
|
||||
|
||||
|
||||
const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint( const SEG& aSeg, int& dist ) const
|
||||
{
|
||||
int nearest = 0;
|
||||
|
||||
dist = INT_MAX;
|
||||
for( int i = 0; i < PointCount(); i++ )
|
||||
{
|
||||
int d = aSeg.LineDistance( CPoint( i ) );
|
||||
|
||||
if( d < dist )
|
||||
{
|
||||
dist = d;
|
||||
nearest = i;
|
||||
}
|
||||
}
|
||||
|
||||
return CPoint( nearest );
|
||||
}
|
||||
|
||||
|
||||
const std::string SHAPE_LINE_CHAIN::Format() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
|
|
@ -264,6 +264,9 @@ public:
|
|||
BOX2I bbox;
|
||||
bbox.Compute( m_points );
|
||||
|
||||
if( aClearance != 0 )
|
||||
bbox.Inflate( aClearance );
|
||||
|
||||
return bbox;
|
||||
}
|
||||
|
||||
|
@ -535,6 +538,17 @@ public:
|
|||
*/
|
||||
const VECTOR2I NearestPoint( const VECTOR2I& aP ) const;
|
||||
|
||||
/**
|
||||
* Function NearestPoint()
|
||||
*
|
||||
* Finds a point on the line chain that is closest to the line defined
|
||||
* by the points of segment aSeg, also returns the distance.
|
||||
* @param aSeg Segment defining the line.
|
||||
* @param dist reference receiving the distance to the nearest point.
|
||||
* @return the nearest point.
|
||||
*/
|
||||
const VECTOR2I NearestPoint( const SEG& aSeg, int& dist ) const;
|
||||
|
||||
/// @copydoc SHAPE::Format()
|
||||
const std::string Format() const;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <geometry/shape_line_chain.h>
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <geometry/shape_circle.h>
|
||||
#include <geometry/shape_convex.h>
|
||||
|
||||
PNS_LOGGER::PNS_LOGGER( )
|
||||
{
|
||||
|
@ -173,6 +174,17 @@ void PNS_LOGGER::dumpShape( const SHAPE* aSh )
|
|||
break;
|
||||
}
|
||||
|
||||
case SH_CONVEX:
|
||||
{
|
||||
const SHAPE_CONVEX* c = (const SHAPE_CONVEX*) aSh;
|
||||
m_theLog << "convex " << c->PointCount() << " ";
|
||||
|
||||
for( int i = 0; i < c->PointCount(); i++ )
|
||||
m_theLog << c->CPoint( i ).x << " " << c->CPoint( i ).y << " ";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <geometry/shape_line_chain.h>
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <geometry/shape_convex.h>
|
||||
|
||||
#include "pns_line.h"
|
||||
#include "pns_diff_pair.h"
|
||||
|
@ -659,6 +660,48 @@ PNS_OPTIMIZER::BREAKOUT_LIST PNS_OPTIMIZER::circleBreakouts( int aWidth,
|
|||
}
|
||||
|
||||
|
||||
PNS_OPTIMIZER::BREAKOUT_LIST PNS_OPTIMIZER::convexBreakouts( int aWidth,
|
||||
const SHAPE* aShape, bool aPermitDiagonal ) const
|
||||
{
|
||||
BREAKOUT_LIST breakouts;
|
||||
const SHAPE_CONVEX* convex = static_cast<const SHAPE_CONVEX*>( aShape );
|
||||
|
||||
BOX2I bbox = convex->BBox( 0 );
|
||||
VECTOR2I p0 = bbox.Centre();
|
||||
// must be large enough to guarantee intersecting the convex polygon
|
||||
int length = bbox.GetSize().EuclideanNorm() / 2 + 5;
|
||||
|
||||
for( int angle = 0; angle < 360; angle += ( aPermitDiagonal ? 45 : 90 ) )
|
||||
{
|
||||
SHAPE_LINE_CHAIN l;
|
||||
VECTOR2I v0( p0 + VECTOR2I( length, 0 ).Rotate( angle * M_PI / 180.0 ) );
|
||||
SHAPE_LINE_CHAIN::INTERSECTIONS intersections;
|
||||
int n = convex->Vertices().Intersect( SEG( p0, v0 ), intersections );
|
||||
// if n == 1 intersected a segment
|
||||
// if n == 2 intersected the common point of 2 segments
|
||||
// n == 0 can not happen I think, but...
|
||||
if( n > 0 )
|
||||
{
|
||||
l.Append( p0 );
|
||||
|
||||
// for a breakout distance relative to the distance between
|
||||
// center and polygon edge
|
||||
//l.Append( intersections[0].p + (v0 - p0).Resize( (intersections[0].p - p0).EuclideanNorm() * 0.4 ) );
|
||||
|
||||
// for an absolute breakout distance, e.g. 0.1 mm
|
||||
l.Append( intersections[0].p + (v0 - p0).Resize( 100000 ) );
|
||||
|
||||
// for the breakout right on the polygon edge
|
||||
//l.Append( intersections[0].p );
|
||||
|
||||
breakouts.push_back( l );
|
||||
}
|
||||
}
|
||||
|
||||
return breakouts;
|
||||
}
|
||||
|
||||
|
||||
PNS_OPTIMIZER::BREAKOUT_LIST PNS_OPTIMIZER::rectBreakouts( int aWidth,
|
||||
const SHAPE* aShape, bool aPermitDiagonal ) const
|
||||
{
|
||||
|
@ -743,6 +786,9 @@ PNS_OPTIMIZER::BREAKOUT_LIST PNS_OPTIMIZER::computeBreakouts( int aWidth,
|
|||
case SH_CIRCLE:
|
||||
return circleBreakouts( aWidth, shape, aPermitDiagonal );
|
||||
|
||||
case SH_CONVEX:
|
||||
return convexBreakouts( aWidth, shape, aPermitDiagonal );
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -158,6 +158,7 @@ private:
|
|||
BREAKOUT_LIST circleBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
|
||||
BREAKOUT_LIST rectBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
|
||||
BREAKOUT_LIST ovalBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
|
||||
BREAKOUT_LIST convexBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
|
||||
BREAKOUT_LIST computeBreakouts( int aWidth, const PNS_ITEM* aItem, bool aPermitDiagonal ) const;
|
||||
|
||||
int smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd, int aEndVertex );
|
||||
|
|
|
@ -207,53 +207,137 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
|
|||
double orient = aPad->GetOrientation() / 10.0;
|
||||
bool nonOrtho = false;
|
||||
|
||||
if( orient == 90.0 || orient == 270.0 )
|
||||
sz = VECTOR2I( sz.y, sz.x );
|
||||
else if( orient != 0.0 && orient != 180.0 )
|
||||
if( aPad->GetShape() == PAD_CIRCLE )
|
||||
{
|
||||
// rotated pads are replaced by for the moment by circles due to my laziness ;)
|
||||
solid->SetShape( new SHAPE_CIRCLE( c, std::min( sz.x, sz.y ) / 2 ) );
|
||||
nonOrtho = true;
|
||||
}
|
||||
solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
|
||||
} else {
|
||||
|
||||
if( !nonOrtho )
|
||||
{
|
||||
switch( aPad->GetShape() )
|
||||
if( orient == 0.0 || orient == 90.0 || orient == 180.0 || orient == 270.0 )
|
||||
{
|
||||
case PAD_CIRCLE:
|
||||
solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
|
||||
break;
|
||||
if( orient == 90.0 || orient == 270.0 )
|
||||
sz = VECTOR2I( sz.y, sz.x );
|
||||
|
||||
case PAD_OVAL:
|
||||
if( sz.x == sz.y )
|
||||
solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
|
||||
else
|
||||
switch( aPad->GetShape() )
|
||||
{
|
||||
VECTOR2I delta;
|
||||
|
||||
if( sz.x > sz.y )
|
||||
delta = VECTOR2I( ( sz.x - sz.y ) / 2, 0 );
|
||||
case PAD_OVAL:
|
||||
if( sz.x == sz.y )
|
||||
solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
|
||||
else
|
||||
delta = VECTOR2I( 0, ( sz.y - sz.x ) / 2 );
|
||||
{
|
||||
VECTOR2I delta;
|
||||
|
||||
if( sz.x > sz.y )
|
||||
delta = VECTOR2I( ( sz.x - sz.y ) / 2, 0 );
|
||||
else
|
||||
delta = VECTOR2I( 0, ( sz.y - sz.x ) / 2 );
|
||||
|
||||
SHAPE_SEGMENT* shape = new SHAPE_SEGMENT( c - delta, c + delta,
|
||||
std::min( sz.x, sz.y ) );
|
||||
solid->SetShape( shape );
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_RECT:
|
||||
solid->SetShape( new SHAPE_RECT( c - sz / 2, sz.x, sz.y ) );
|
||||
break;
|
||||
|
||||
case PAD_TRAPEZOID:
|
||||
{
|
||||
wxPoint coords[4];
|
||||
aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );
|
||||
|
||||
SHAPE_CONVEX* shape = new SHAPE_CONVEX();
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
{
|
||||
shape->Append( wx_c + coords[ii] );
|
||||
}
|
||||
|
||||
SHAPE_SEGMENT* shape = new SHAPE_SEGMENT( c - delta, c + delta,
|
||||
std::min( sz.x, sz.y ) );
|
||||
solid->SetShape( shape );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_RECT:
|
||||
solid->SetShape( new SHAPE_RECT( c - sz / 2, sz.x, sz.y ) );
|
||||
break;
|
||||
default:
|
||||
TRACEn( 0, "unsupported pad shape" );
|
||||
delete solid;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
switch( aPad->GetShape() )
|
||||
{
|
||||
// PAD_CIRCLE already handled above
|
||||
|
||||
default:
|
||||
TRACEn( 0, "unsupported pad shape" );
|
||||
delete solid;
|
||||
case PAD_OVAL:
|
||||
if( sz.x == sz.y )
|
||||
solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
|
||||
else
|
||||
{
|
||||
wxPoint start;
|
||||
wxPoint end;
|
||||
wxPoint corner;
|
||||
|
||||
return NULL;
|
||||
SHAPE_CONVEX* shape = new SHAPE_CONVEX();
|
||||
|
||||
int w = aPad->BuildSegmentFromOvalShape( start, end, 0.0, wxSize( 0, 0 ) );
|
||||
|
||||
if( start.y == 0 )
|
||||
corner = wxPoint( start.x, -(w / 2) );
|
||||
else
|
||||
corner = wxPoint( w / 2, start.y );
|
||||
RotatePoint( &start, aPad->GetOrientation() );
|
||||
RotatePoint( &corner, aPad->GetOrientation() );
|
||||
shape->Append( wx_c + corner );
|
||||
|
||||
for( int rot = 100; rot <= 1800; rot += 100 )
|
||||
{
|
||||
wxPoint p( corner );
|
||||
RotatePoint( &p, start, rot );
|
||||
shape->Append( wx_c + p );
|
||||
}
|
||||
|
||||
if( end.y == 0 )
|
||||
corner = wxPoint( end.x, w / 2 );
|
||||
else
|
||||
corner = wxPoint( -(w / 2), end.y );
|
||||
RotatePoint( &end, aPad->GetOrientation() );
|
||||
RotatePoint( &corner, aPad->GetOrientation() );
|
||||
shape->Append( wx_c + corner );
|
||||
|
||||
for( int rot = 100; rot <= 1800; rot += 100 )
|
||||
{
|
||||
wxPoint p( corner );
|
||||
RotatePoint( &p, end, rot );
|
||||
shape->Append( wx_c + p );
|
||||
}
|
||||
|
||||
solid->SetShape( shape );
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_RECT:
|
||||
case PAD_TRAPEZOID:
|
||||
{
|
||||
wxPoint coords[4];
|
||||
aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );
|
||||
|
||||
SHAPE_CONVEX* shape = new SHAPE_CONVEX();
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
{
|
||||
shape->Append( wx_c + coords[ii] );
|
||||
}
|
||||
|
||||
solid->SetShape( shape );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
TRACEn( 0, "unsupported pad shape" );
|
||||
delete solid;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return solid;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <geometry/shape_line_chain.h>
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <geometry/shape_circle.h>
|
||||
#include <geometry/shape_convex.h>
|
||||
|
||||
#include "pns_solid.h"
|
||||
#include "pns_utils.h"
|
||||
|
@ -54,6 +55,13 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness
|
|||
return SegmentHull( *seg, aClearance, aWalkaroundThickness );
|
||||
}
|
||||
|
||||
case SH_CONVEX:
|
||||
{
|
||||
SHAPE_CONVEX* convex = static_cast<SHAPE_CONVEX*>( m_shape );
|
||||
|
||||
return ConvexHull( *convex, cl );
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,74 @@ const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance,
|
|||
}
|
||||
|
||||
|
||||
static void MoveDiagonal( SEG& diagonal, const SHAPE_LINE_CHAIN& vertices, int clearance )
|
||||
{
|
||||
int dist;
|
||||
|
||||
vertices.NearestPoint( diagonal, dist );
|
||||
dist -= HULL_MARGIN;
|
||||
VECTOR2I moveBy = (diagonal.A - diagonal.B).Perpendicular().Resize( dist - clearance );
|
||||
diagonal.A += moveBy;
|
||||
diagonal.B += moveBy;
|
||||
}
|
||||
|
||||
|
||||
const SHAPE_LINE_CHAIN ConvexHull( const SHAPE_CONVEX& convex, int clearance )
|
||||
{
|
||||
// this defines the horizontal and vertical lines in the hull octagon
|
||||
BOX2I box = convex.BBox( clearance + HULL_MARGIN );
|
||||
box.Normalize();
|
||||
|
||||
SEG topline = SEG( VECTOR2I( box.GetX(), box.GetY() + box.GetHeight() ),
|
||||
VECTOR2I( box.GetX() + box.GetWidth(), box.GetY() + box.GetHeight() ) );
|
||||
SEG rightline = SEG( VECTOR2I( box.GetX() + box.GetWidth(), box.GetY() + box.GetHeight() ),
|
||||
VECTOR2I( box.GetX() + box.GetWidth(), box.GetY() ) );
|
||||
SEG bottomline = SEG( VECTOR2I( box.GetX() + box.GetWidth(), box.GetY() ),
|
||||
box.GetOrigin() );
|
||||
SEG leftline = SEG( box.GetOrigin(), VECTOR2I( box.GetX(), box.GetY() + box.GetHeight() ) );
|
||||
|
||||
const SHAPE_LINE_CHAIN& vertices = convex.Vertices();
|
||||
|
||||
// top right diagonal
|
||||
VECTOR2I corner = box.GetOrigin() + box.GetSize();
|
||||
SEG toprightline = SEG( corner,
|
||||
corner + VECTOR2I( box.GetHeight(), -box.GetHeight() ) );
|
||||
MoveDiagonal( toprightline, vertices, clearance );
|
||||
|
||||
// bottom right diagonal
|
||||
corner = box.GetOrigin() + VECTOR2I( box.GetWidth(), 0 );
|
||||
SEG bottomrightline = SEG( corner + VECTOR2I( box.GetHeight(), box.GetHeight() ),
|
||||
corner );
|
||||
MoveDiagonal( bottomrightline, vertices, clearance );
|
||||
|
||||
// bottom left diagonal
|
||||
corner = box.GetOrigin();
|
||||
SEG bottomleftline = SEG( corner,
|
||||
corner + VECTOR2I( -box.GetHeight(), box.GetHeight() ) );
|
||||
MoveDiagonal( bottomleftline, vertices, clearance );
|
||||
|
||||
// top left diagonal
|
||||
corner = box.GetOrigin() + VECTOR2I( 0, box.GetHeight() );
|
||||
SEG topleftline = SEG( corner + VECTOR2I( -box.GetHeight(), -box.GetHeight() ),
|
||||
corner );
|
||||
MoveDiagonal( topleftline, vertices, clearance );
|
||||
|
||||
SHAPE_LINE_CHAIN octagon;
|
||||
octagon.SetClosed( true );
|
||||
|
||||
octagon.Append( leftline.IntersectLines( bottomleftline ).get() );
|
||||
octagon.Append( bottomline.IntersectLines( bottomleftline ).get() );
|
||||
octagon.Append( bottomline.IntersectLines( bottomrightline ).get() );
|
||||
octagon.Append( rightline.IntersectLines( bottomrightline ).get() );
|
||||
octagon.Append( rightline.IntersectLines( toprightline ).get() );
|
||||
octagon.Append( topline.IntersectLines( toprightline ).get() );
|
||||
octagon.Append( topline.IntersectLines( topleftline ).get() );
|
||||
octagon.Append( leftline.IntersectLines( topleftline ).get() );
|
||||
|
||||
return octagon;
|
||||
}
|
||||
|
||||
|
||||
SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg )
|
||||
{
|
||||
SHAPE_RECT r;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <geometry/shape_line_chain.h>
|
||||
#include <geometry/shape_segment.h>
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <geometry/shape_convex.h>
|
||||
|
||||
#define HULL_MARGIN 10
|
||||
|
||||
|
@ -39,6 +40,16 @@ const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0, const VECTOR2I& aSize
|
|||
const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance,
|
||||
int aWalkaroundThickness );
|
||||
|
||||
/**
|
||||
* Function ConvexHull()
|
||||
*
|
||||
* Creates an octagonal hull around a convex polygon.
|
||||
* @param convex The convex polygon.
|
||||
* @param clearance The minimum distance between polygon and hull.
|
||||
* @return A closed line chain describing the octagon.
|
||||
*/
|
||||
const SHAPE_LINE_CHAIN ConvexHull( const SHAPE_CONVEX& convex, int clearance );
|
||||
|
||||
SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg );
|
||||
|
||||
void DrawDebugPoint( VECTOR2I aP, int aColor );
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <deque>
|
||||
#include <gal/color4d.h>
|
||||
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <geometry/shape_convex.h>
|
||||
|
||||
#include "class_track.h"
|
||||
#include <pcb_painter.h>
|
||||
|
@ -233,7 +235,29 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
|
|||
break;
|
||||
}
|
||||
|
||||
case SH_CONVEX:
|
||||
case SH_CONVEX:
|
||||
{
|
||||
const SHAPE_CONVEX* c = (const SHAPE_CONVEX*) m_shape;
|
||||
std::deque<VECTOR2D> polygon = std::deque<VECTOR2D>();
|
||||
for( int i = 0; i < c->PointCount(); i++ )
|
||||
{
|
||||
polygon.push_back( c->CDPoint( i ) );
|
||||
}
|
||||
aGal->DrawPolygon( polygon );
|
||||
|
||||
if( m_clearance > 0 )
|
||||
{
|
||||
aGal->SetLayerDepth( ClearanceOverlayDepth );
|
||||
aGal->SetStrokeColor( COLOR4D( DARKDARKGRAY ) );
|
||||
aGal->SetIsStroke( true );
|
||||
aGal->SetLineWidth( 2 * m_clearance );
|
||||
// need the implicit last segment to be explicit for DrawPolyline
|
||||
polygon.push_back( c->CDPoint( 0 ) );
|
||||
aGal->DrawPolyline( polygon );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SH_POLY_SET:
|
||||
case SH_COMPOUND:
|
||||
break; // Not yet in use
|
||||
|
|
Loading…
Reference in New Issue