38 int aClearance,
int aChamfer )
44 s.
Append( aP0.
x - aClearance, aP0.
y - aClearance + aChamfer );
47 s.
Append( aP0.
x - aClearance + aChamfer, aP0.
y - aClearance );
49 s.
Append( aP0.
x + aSize.
x + aClearance - aChamfer, aP0.
y - aClearance );
52 s.
Append( aP0.
x + aSize.
x + aClearance, aP0.
y - aClearance + aChamfer );
54 s.
Append( aP0.
x + aSize.
x + aClearance, aP0.
y + aSize.
y + aClearance - aChamfer );
57 s.
Append( aP0.
x + aSize.
x + aClearance - aChamfer, aP0.
y + aSize.
y + aClearance );
59 s.
Append( aP0.
x - aClearance + aChamfer, aP0.
y + aSize.
y + aClearance );
62 s.
Append( aP0.
x - aClearance, aP0.
y + aSize.
y + aClearance - aChamfer );
70 int cl = aClearance + ( aWalkaroundThickness + 1 ) / 2;
79 2.0 * ( 1.0 - M_SQRT1_2 ) * ( r + cl ) );
83 int x = (int) ( 2.0 / ( 1.0 + M_SQRT2 ) * d ) / 2;
89 std::vector<VECTOR2I> reverse_line;
91 auto seg = line.Segment( 0 );
99 s.
Append( seg.A + p0 - pd );
100 s.
Append( seg.A - dp + ds );
101 s.
Append( seg.A - dp - ds );
102 s.
Append( seg.A - p0 - pd );
104 for(
int i = 1; i < line.SegmentCount(); i++ )
108 ( line.CSegment( i - 1 ).B - line.CSegment( i - 1 ).A ).Perpendicular().Resize( d );
109 auto pp2 = ( line.CSegment( i ).B - line.CSegment( i ).A ).Perpendicular().Resize( d );
111 auto sa_out = line.CSegment( i - 1 ), sa_in = line.CSegment( i - 1 );
112 auto sb_out = line.CSegment( i ), sb_in = line.CSegment( i );
124 auto ip_out = sa_out.IntersectLines( sb_out );
125 auto ip_in = sa_in.IntersectLines( sb_in );
127 seg = line.CSegment( i );
128 auto lead = ( pp + pp2 ) / 2;
131 reverse_line.push_back( *ip_in );
134 seg = line.CSegment( -1 );
140 s.
Append( seg.B - p0 + pd );
141 s.
Append( seg.B + dp - ds );
142 s.
Append( seg.B + dp + ds );
143 s.
Append( seg.B + p0 + pd );
145 for(
int i = reverse_line.size() - 1; i >= 0; i-- )
146 s.
Append( reverse_line[i] );
175template <
typename T>
int sgn(T val) {
176 return (T(0) < val) - (val < T(0));
181 int aWalkaroundThickness )
183 const int kinkThreshold = aClearance / 10;
185 int cl = aClearance + aWalkaroundThickness / 2;
186 double d = (double)aSeg.
GetWidth() / 2.0 + cl;
187 double x = 2.0 / ( 1.0 + M_SQRT2 ) * d;
211 if ( len <= kinkThreshold && len > 0 )
220 if( len <= kinkThreshold )
233 else if ( delta45 <= 2 )
252 int xx2 =
KiROUND( 2.0 * ( 1.0 - M_SQRT1_2 ) * d );
294 VECTOR2I moveBy = ( aDiagonal.
A - aDiagonal.
B ).Perpendicular().
Resize( dist - aClearance );
295 aDiagonal.
A += moveBy;
296 aDiagonal.
B += moveBy;
318 SEG toprightline =
SEG( corner,
330 SEG bottomleftline =
SEG( corner,
364 return SHAPE_RECT( std::min( p0.
x, p1.
x ), std::min( p0.
y, p1.
y ),
373 const VIA* va =
static_cast<const VIA*
>( aItemA );
374 const VIA* vb =
static_cast<const VIA*
>( aItemB );
380 const LINE* la =
static_cast<const LINE*
> ( aItemA );
381 const LINE* lb =
static_cast<const LINE*
> ( aItemB );
405 for(
auto& p : ips_raw )
411 int d1_idx = 0, d2_idx = 0;
416 if( !p.is_corner_our && !p.is_corner_their )
419 ips.push_back( ipp );
426 if( p.is_corner_our )
428 d1[0] = hull.
CSegment( p.index_our );
429 d1[1] = hull.
CSegment( p.index_our - 1 );
434 d1[0] = hull.
CSegment( p.index_our );
438 if( p.is_corner_their )
440 if( p.index_their > 0 )
442 d2[d2_idx++] = line.
CSegment( p.index_their - 1 ).
A;
446 d2[d2_idx++] = line.
CSegment( p.index_their ).
B;
451 d2[d2_idx++] = line.
CSegment( p.index_their ).
A;
452 d2[d2_idx++] = line.
CSegment( p.index_their ).
B;
455 for(
int i = 0; i < d1_idx; i++ )
457 for(
int j = 0; j < d2_idx; j++ )
459 if( d1[i].Side( d2[j] ) > 0 )
466#ifdef TOM_EXTRA_DEBUG
467 printf(
"p %d %d hi %d their %d co %d ct %d ipv %d\n", p.p.x, p.p.y, p.index_our, p.index_their, p.is_corner_our?1:0, p.is_corner_their?1:0, ipp.
valid ?1:0);
468 printf(
"d1 %d d2 %d\n", d1_idx, d2_idx );
472 ips.push_back( ipp );
479 int aWalkaroundThickness )
481 int cl = aClearance + ( aWalkaroundThickness + 1 )/ 2;
483 switch( aShape->
Type() )
501 2.0 * ( 1.0 - M_SQRT1_2 ) * ( r + cl ) );
507 return SegmentHull( *seg, aClearance, aWalkaroundThickness );
513 return ArcHull( *arc, aClearance, aWalkaroundThickness );
524 wxFAIL_MSG( wxString::Format( wxT(
"Unsupported hull shape: %d (%s)." ),
540 PNS_DBG( dbg, BeginGroup, wxString::Format(
"node:%s this=%p depth=%d added=%d removed=%d",
541 label, node, node->
Depth(), (
int)added.size(), (
int) removed.size() ), 0 );
543 for(
auto& item : added )
544 PNS_DBG( dbg, AddItem, item,
BLUE, 10000, wxT(
"added-item") );
545 for(
auto& item : removed )
546 PNS_DBG( dbg, AddItem, item,
RED, 10000, wxString::Format(
"removed-item") );
constexpr int ARC_LOW_DEF
std::optional< BOX2I > OPT_BOX2I
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr coord_type GetX() const
constexpr size_type GetHeight() const
constexpr const Vec & GetOrigin() const
constexpr const SizeVec & GetSize() const
Base class for PNS router board items.
bool OfKind(int aKindMask) const
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
OPT_BOX2I ChangedArea(const LINE *aOther) const
Keep the router "world" - i.e.
std::vector< ITEM * > ITEM_VECTOR
void GetUpdatedItems(ITEM_VECTOR &aRemoved, ITEM_VECTOR &aAdded)
Return the list of items removed and added in this branch with respect to the root branch.
OPT_BOX2I ChangedArea(const VIA *aOther) const
int Length() const
Return the length (this).
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
int Side(const VECTOR2I &aP) const
Determine on which side of directed line passing via segment ends point aP lies.
EDA_ANGLE GetCentralAngle() const
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=DefaultAccuracyForPCB(), double *aEffectiveAccuracy=nullptr) const
Construct a SHAPE_LINE_CHAIN of segments from a given arc.
static double DefaultAccuracyForPCB()
const VECTOR2I & GetCenter() const
SHAPE_TYPE Type() const
Return the type of the shape.
const VECTOR2I GetCenter() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const SHAPE_LINE_CHAIN Reverse() const
Reverse point order in the line chain.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Find all intersection points between our line chain and the segment aSeg.
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
int SegmentCount() const
Return the number of segments in this line chain.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
std::vector< INTERSECTION > INTERSECTIONS
const VECTOR2I & GetPosition() const
const VECTOR2I GetSize() const
const SEG & GetSeg() const
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
const SHAPE_LINE_CHAIN & Vertices() const
Return the list of vertices defining this simple polygon.
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
An abstract shape on 2D plane.
constexpr VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Push and Shove diff pair dimensions (gap) settings dialog.
void HullIntersection(const SHAPE_LINE_CHAIN &hull, const SHAPE_LINE_CHAIN &line, SHAPE_LINE_CHAIN::INTERSECTIONS &ips)
const SHAPE_LINE_CHAIN BuildHullForPrimitiveShape(const SHAPE *aShape, int aClearance, int aWalkaroundThickness)
const SHAPE_LINE_CHAIN OctagonalHull(const VECTOR2I &aP0, const VECTOR2I &aSize, int aClearance, int aChamfer)
SHAPE_RECT ApproximateSegmentAsRect(const SHAPE_SEGMENT &aSeg)
const SHAPE_LINE_CHAIN ArcHull(const SHAPE_ARC &aArc, int aClearance, int aWalkaroundThickness)
Various utility functions.
const SHAPE_LINE_CHAIN ConvexHull(const SHAPE_SIMPLE &aConvex, int aClearance)
Function ConvexHull()
void NodeStats(DEBUG_DECORATOR *dbg, wxString label, PNS::NODE *node)
const SHAPE_LINE_CHAIN SegmentHull(const SHAPE_SEGMENT &aSeg, int aClearance, int aWalkaroundThickness)
static bool IsSegment45Degree(const SEG &aS)
static void MoveDiagonal(SEG &aDiagonal, const SHAPE_LINE_CHAIN &aVertices, int aClearance)
OPT_BOX2I ChangedArea(const ITEM *aItemA, const ITEM *aItemB)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
#define PNS_DBG(dbg, method,...)
#define PNS_DBGN(dbg, method)
@ SH_RECT
axis-aligned rectangle
@ SH_SIMPLE
simple polygon
static wxString SHAPE_TYPE_asString(SHAPE_TYPE a)
Represent an intersection between two line segments.
bool valid
Auxiliary flag to avoid copying intersection info to intersection refining code, used by the refining...
VECTOR2< int32_t > VECTOR2I