48 switch( dir_a.Angle( dir_b ) )
101 double aCornerTolerance )
const
176 auto links = aLine->
Links();
181 for(
int i = aStartVertex; i < aEndVertex - 1; i++ )
206 for(
const std::pair<ITEM* const, CACHED_ITEM>& entry :
m_cacheTags )
208 if( entry.second.m_isStatic )
213 [](
const std::pair<ITEM* const, CACHED_ITEM>& entry )
215 return entry.second.m_isStatic;
233 if( aVertex1 < aCurrentPath.
PointCount() - 1 && !p1_in && p2_in
256 for(
int i = aVertex1; i < aVertex2; i++ )
294 LINE newPath( *aOriginLine, aCurrentPath );
295 newPath.
Line().
Replace( aVertex1, aVertex2, aReplacement );
313 [](
const SEG& aS1,
const SEG& aS2 ) ->
bool
325 for(
int i = 0; i < replSegs - 1; i++ )
327 if( !isAngleOk( aReplacement.
CSegment( i ), aReplacement.
CSegment( i + 1 ) ) )
334 SEG lastReplSeg = aReplacement.
CSegment( replSegs - 1 );
338 if( !isAngleOk( aCurrentPath.
CSegment( aVertex1 - 1 ), firstReplSeg ) )
342 if( aVertex2 < pathSegs )
344 if( !isAngleOk( lastReplSeg, aCurrentPath.
CSegment( aVertex2 ) ) )
373 for(
size_t i = 1; i <= cnt; ++i )
377 if( ipNext.
y == aP.
y )
379 if( ( ipNext.
x == aP.
x )
380 || ( ip.
y == aP.
y && ( ( ipNext.
x > aP.
x ) == ( ip.
x < aP.
x ) ) ) )
384 if( ( ip.
y < aP.
y ) != ( ipNext.
y < aP.
y ) )
394 double d =
static_cast<double>( ip.
x - aP.
x ) *
395 static_cast<double>( ipNext.
y - aP.
y ) -
396 static_cast<double>( ipNext.
x - aP.
x ) *
397 static_cast<double>( ip.
y - aP.
y );
402 if( ( d > 0 ) == ( ipNext.
y > ip.
y ) )
410 double d = ( (double) ip.
x - aP.
x ) * ( (
double) ipNext.
y - aP.
y )
411 - ( (double) ipNext.
x - aP.
x ) * ( (
double) ip.
y - aP.
y );
416 if( ( d > 0 ) == ( ipNext.
y > ip.
y ) )
440 std::vector<JOINT*> joints;
447 for(
JOINT* j : joints )
449 if( j->Net() == aOriginLine->
Net() )
454 bool falsePositive =
false;
456 for(
int k = 0; k < encPoly.
PointCount(); k++ )
458 if( encPoly.
CPoint(k) == j->Pos() )
460 falsePositive =
true;
495 if( !c->Check( aVertex1, aVertex2, aOriginLine, aCurrentPath, aReplacement ) )
505 LINE tmp( *aLine, aOptPath );
526 int max_step = n_segs - 2;
528 if( step > max_step )
533 line = std::move( current_path );
537 bool found_anything =
false;
539 for(
int n = 0; n < n_segs - step; n++ )
549 s1opt =
SEG( s1.
A, ip );
550 s2opt =
SEG( ip, s2.
B );
559 LINE opt_track( *aLine, opt_path );
567 found_anything =
true;
574 if( !found_anything )
578 line = std::move( current_path );
605 int max_step = n_segs - 2;
607 if( step > max_step )
613 bool found_anything =
mergeStep( aLine, current_path, step );
615 if( !found_anything )
634 for(
int segIdx = 0; segIdx < line.
SegmentCount() - 1; ++segIdx )
645 line.
Remove( segIdx + 1 );
667 int rootObtuseCorners = aRoot->
CountCorners( angleMask );
743 if( aVIdx <= 0 || aVIdx >=
path.PointCount() - 1 )
746 if(
path.IsArcSegment( aVIdx - 1 ) ||
path.IsArcSegment( aVIdx ) )
749 const SEG s1 =
path.CSegment( aVIdx - 1 );
750 const SEG s2 =
path.CSegment( aVIdx );
764 double bestArea = std::numeric_limits<double>::max();
766 for(
int posture = 0; posture < 2; posture++ )
781 for(
int j = bypass.
PointCount() - 1; j >= 0; j-- )
786 if(
double area =
std::abs( loop.
Area() ); area < bestArea )
815 if(
path.IsArcSegment( anchorIdx - 1 ) ||
path.IsArcSegment( anchorIdx ) )
818 bool changed =
false;
820 if( anchorIdx >=
path.PointCount() - 1 )
838 if( anchorIdx > 0 && anchorIdx <
path.PointCount() - 1 )
866 for(
int n = 0; n < n_segs - step; n++ )
870 || aCurrentPath.
IsArcSegment(
static_cast<std::size_t
>( n ) + step ) )
882 for(
int i = 0; i < 2; i++ )
896 path[i] = aCurrentPath;
903 if( cost[0] < cost_orig && cost[0] < cost[1] )
905 else if( cost[1] < cost_orig )
911 aCurrentPath = *picked;
921 bool aPermitDiagonal )
const
936 breakouts.push_back( l );
944 bool aPermitDiagonal )
const
961 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersections;
979 l.
Append( intersections[0].p );
981 breakouts.push_back( l );
990 bool aPermitDiagonal )
const
997 breakouts.reserve( 12 );
1001 d_offset.
x = ( s.
x > s.
y ) ? ( s.
x - s.
y ) / 2 : 0;
1002 d_offset.
y = ( s.
x < s.
y ) ? ( s.
y - s.
x ) / 2 : 0;
1012 if( aPermitDiagonal )
1014 int l = aWidth + std::min( s.
x, s.
y ) / 2;
1018 breakouts.emplace_back(
1020 breakouts.emplace_back(
1022 breakouts.emplace_back(
1024 breakouts.emplace_back(
1030 breakouts.emplace_back(
1032 breakouts.emplace_back(
1034 breakouts.emplace_back(
1036 breakouts.emplace_back(
1046 bool aPermitDiagonal )
const
1048 switch( aItem->
Kind() )
1052 const VIA*
via =
static_cast<const VIA*
>( aItem );
1061 switch( shape->
Type() )
1096 const JOINT* jt =
m_world->FindJoint( aP, aLayer, aNet );
1118 typedef std::tuple<int, long long int, SHAPE_LINE_CHAIN> RtVariant;
1119 std::vector<RtVariant> variants;
1134 int p_end = std::min( aEndVertex, std::min( 3, line.
PointCount() - 1 ) );
1137 for(
int p = 1; p <= p_end; p++ )
1148 for(
int diag = 0; diag < 2; diag++ )
1152 breakout.CLastPoint(), line.
CPoint( p ), diag == 0 );
1161 if( ang1 & ForbiddenAngles )
1164 if( breakout.Length() > line.
Length() )
1170 for(
int i = p + 1; i < line.
PointCount(); i++ )
1173 LINE tmp( *aLine, v );
1179 std::get<0>( vp ) = p;
1180 std::get<1>( vp ) = breakout.Length();
1181 std::get<2>( vp ) = aEnd ? v.
Reverse() : v;
1183 variants.push_back( std::move( vp ) );
1195 long long int max_length = 0;
1200 for( RtVariant& vp : variants )
1202 LINE tmp( *aLine, std::get<2>( vp ) );
1204 long long int len = std::get<1>( vp );
1208 if( cost < min_cost || ( cost == min_cost && len > max_length ) )
1210 l_best = std::get<2>( vp );
1211 p_best = std::get<0>( vp );
1214 if( cost <= min_cost )
1215 max_length = std::max<int>( len, max_length );
1217 min_cost = std::min( cost, min_cost );
1263 opt.SetEffortLevel( aEffortLevel );
1264 opt.SetCollisionMask( -1 );
1267 opt.SetPreserveVertex( aV );
1270 return opt.Optimize( &tmp, aLine );
1286 int thr = aLine->
Width() * 10;
1293 bool endMatch =
false;
1304 if( startMatch && endMatch && len < thr )
1306 for(
int i = 0; i < 2; i++ )
1310 repl =
LINE( *aLine, l2 );
1312 if( !
m_world->CheckColliding( &repl ) )
1324 DIFF_PAIR* aPair, std::vector<int>* aIndices )
1336 int64_t{ ( ( projOverCoupled - aVertex ).EuclideanNorm() ) } - aPair->
Dimensions().
Width();
1340 aIndices->push_back( i );
1353 LINE refLine ( aRefIsP ? aPair->
PLine() : aPair->
NLine(), aNewRef );
1354 LINE coupledLine ( aRefIsP ? aPair->
NLine() : aPair->
PLine(), aNewCoupled );
1356 if( refLine.
Collide( &coupledLine, aNode, refLine.
Layer() ) )
1373 std::vector<int> vStartIdx;
1374 vStartIdx.reserve( 1024 );
1377 aPair, &vStartIdx );
1380 int64_t bestLength = -1;
1385 for(
int i=0; i< nStarts; i++ )
1387 for(
int j = 1; j < aCoupled.
PointCount() - 1; j++ )
1397 int64_t coupledLength;
1399 std::tie( coupledLength, tmp ) = aPair->
CoupledLength( aRef, bypass );
1407 newCoupled.
Replace( si, ei, bypass );
1411 if( coupledLength > bestLength &&
verifyDpBypass( aNode, aPair, aRefIsP, aRef, newCoupled) )
1413 bestBypass = std::move( newCoupled );
1414 bestLength = coupledLength;
1422 aNewCoupled = std::move( bestBypass );
1447 std::tie(clenPre, tmp) = aPair->
CoupledLength( currentPath, coupledPath );
1448 int64_t budget = clenPre / 10;
1450 while( n < n_segs - step )
1464 int64_t deltaCoupled = -1, deltaUni = -1;
1466 newRef = currentPath;
1469 std::tie(deltaUni, tmp2) = aPair->
CoupledLength ( newRef, coupledPath );
1470 deltaUni += (- clenPre + budget);
1474 std::tie(deltaCoupled, tmp) = aPair->
CoupledLength( newRef, newCoup );
1475 deltaCoupled += (- clenPre + budget);
1477 if( deltaCoupled >= 0 )
1482 aPair->
SetShape( newRef, newCoup, !aTryP );
1491 aPair->
SetShape( newRef, coupledPath, !aTryP );
1513 int max_step_p = n_segs_p - 2;
1514 int max_step_n = n_segs_n - 2;
1516 if( step_p > max_step_p )
1517 step_p = max_step_p;
1519 if( step_n > max_step_n )
1520 step_n = max_step_n;
1522 if( step_p < 1 && step_n < 1 )
1525 bool found_anything_p =
false;
1526 bool found_anything_n =
false;
1529 found_anything_p =
mergeDpStep( aPair,
true, step_p );
1532 found_anything_n =
mergeDpStep( aPair,
false, step_n );
1534 if( !found_anything_n && !found_anything_p )
1555 const int total = oc + nc;
1557 for(
int i = 0; i < total; i++)
1559 int i_next = (i + 1 == total ? 0 : i + 1);
1562 : aNew.
CPoint( nc - 1 - (i - oc) );
1564 : aNew.
CPoint( nc - 1 - (i_next - oc) );
1565 area += -(int64_t) v0.
y *
v1.x + (int64_t) v0.
x *
v1.y;
1625 initial = guide.
Length();
1647 else if ( current + step >= initial )
1656 if ( current == initial )
1662 out = std::move( snew );
1676 for(
int step = 0; step < 3; step++ )
1684 l_in = current.
Slice( i, i + 3 );
1686 for(
int dir = 0; dir <= 1; dir++ )
1688 if(
tightenSegment( dir ?
true :
false, aNode, aNewLine, l_in, l_out ) )
1691 opt.
Replace( i, i + 3, l_out );
1695 if( optArea < prevArea )
1696 current = std::move( opt );
1704 aOptimized =
LINE( aNewLine, current );
constexpr size_type GetWidth() const
constexpr size_type GetHeight() const
Represent route directions & corner angles in a 45-degree metric.
const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false, CORNER_MODE aMode=CORNER_MODE::MITERED_45) const
Build a 2-segment line chain between points aP0 and aP1 and following 45-degree routing regime.
AngleType Angle(const DIRECTION_45 &aOther) const
Return the type of angle between directions (this) and aOther.
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
bool IsDiagonal() const
Returns true if the direction is diagonal (e.g.
@ ROUNDED_90
H/V with filleted corners.
@ MITERED_90
H/V only (90-degree corners)
bool IsObtuse(const DIRECTION_45 &aOther) const
bool IsHorizontal() const
bool Matches(const T v) const
bool Check(int aVertex1, int aVertex2, const LINE *aOriginLine, const SHAPE_LINE_CHAIN &aCurrentPath, const SHAPE_LINE_CHAIN &aReplacement) override
virtual bool Check(int aVertex1, int aVertex2, const LINE *aOriginLine, const SHAPE_LINE_CHAIN &aCurrentPath, const SHAPE_LINE_CHAIN &aReplacement) override
void Replace(const LINE &aOldLine, const LINE &aNewLine)
void Remove(const LINE &aLine)
void Add(const LINE &aLine)
static int CornerCost(const SEG &aA, const SEG &aB)
bool IsBetter(const COST_ESTIMATOR &aOther, double aLengthTolerance, double aCornerTollerace) const
Basic class for a differential pair.
const SHAPE_LINE_CHAIN & CN() const
double CoupledLength() const
const DP_DIMENSIONS & Dimensions() const
void SetShape(const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN &aN, bool aSwapLanes=false)
const SHAPE_LINE_CHAIN & CP() const
const DP_GAP_CONSTRAINT GapConstraint() const
Base class for PNS router board items.
virtual const SHAPE * Shape(int aLayer) const
Return the geometrical shape of the item.
const PNS_LAYER_RANGE & Layers() const
virtual NET_HANDLE Net() const
PnsKind Kind() const
Return the type (kind) of the item.
virtual int Layer() const
bool Collide(const ITEM *aHead, const NODE *aNode, int aLayer, COLLISION_SEARCH_CONTEXT *aCtx=nullptr) const
Check for a collision (clearance violation) with between us and item aOther.
bool OfKind(int aKindMask) const
A 2D point on a given set of layers and belonging to a certain net, that links together a number of b...
const std::vector< ITEM * > & LinkList() const
bool Check(int aVertex1, int aVertex2, const LINE *aOriginLine, const SHAPE_LINE_CHAIN &aCurrentPath, const SHAPE_LINE_CHAIN &aReplacement) override
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
const VECTOR2I & CPoint(int aIdx) const
Return the aIdx-th point of the line.
void SetShape(const SHAPE_LINE_CHAIN &aLine)
Assign a shape to the line (a polyline/line chain).
const SHAPE_LINE_CHAIN & CLine() const
const VECTOR2I & CLastPoint() const
int CountCorners(int aAngles) const
Return the number of corners of angles specified by mask aAngles.
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape.
const SEG CSegment(int aIdx) const
int Width() const
Return line width.
std::vector< LINKED_ITEM * > & Links()
Return the list of links from the owning node that constitute this line (or NULL if the line is not l...
virtual void ClearLinks()
Erase the linking information. Used to detach the line from the owning node.
Keep the router "world" - i.e.
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Check if the item collides with anything else in the world, and if found, returns the obstacle.
bool Check(int aVertex1, int aVertex2, const LINE *aOriginLine, const SHAPE_LINE_CHAIN &aCurrentPath, const SHAPE_LINE_CHAIN &aReplacement) override
std::pair< int, int > m_restrictedVertexRange
std::vector< OPT_CONSTRAINT * > m_constraints
bool mergeColinear(LINE *aLine)
void cacheAdd(ITEM *aItem, bool aIsStatic)
void removeCachedSegments(LINE *aLine, int aStartVertex=0, int aEndVertex=-1)
bool m_restrictAreaIsStrict
bool dragFixCorners(LINE *aLine)
BREAKOUT_LIST computeBreakouts(int aWidth, const ITEM *aItem, bool aPermitDiagonal) const
bool fanoutCleanup(LINE *aLine)
std::vector< SHAPE_LINE_CHAIN > BREAKOUT_LIST
bool mergeFull(LINE *aLine)
bool mergeStep(LINE *aLine, SHAPE_LINE_CHAIN &aCurrentLine, int step)
bool mergeDpStep(DIFF_PAIR *aPair, bool aTryP, int step)
void CacheRemove(ITEM *aItem)
bool mergeObtuse(LINE *aLine)
bool checkConstraints(int aVertex1, int aVertex2, LINE *aOriginLine, const SHAPE_LINE_CHAIN &aCurrentPath, const SHAPE_LINE_CHAIN &aReplacement)
bool checkColliding(ITEM *aItem, bool aUpdateCache=true)
std::unordered_map< ITEM *, CACHED_ITEM > m_cacheTags
bool runSmartPads(LINE *aLine)
bool mergeDpSegments(DIFF_PAIR *aPair)
int smartPadsSingle(LINE *aLine, ITEM *aPad, bool aEnd, int aEndVertex)
bool dragFixCorner(LINE *aLine, int aVIdx)
ITEM * findPadOrVia(int aLayer, NET_HANDLE aNet, const VECTOR2I &aP) const
BREAKOUT_LIST rectBreakouts(int aWidth, const SHAPE *aShape, bool aPermitDiagonal) const
BREAKOUT_LIST customBreakouts(int aWidth, const ITEM *aItem, bool aPermitDiagonal) const
BREAKOUT_LIST circleBreakouts(int aWidth, const SHAPE *aShape, bool aPermitDiagonal) const
VECTOR2I m_preservedVertex
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I &aV=VECTOR2I(0, 0))
A quick shortcut to optimize a line without creating and setting up an optimizer.
void addConstraint(OPT_CONSTRAINT *aConstraint)
void ClearCache(bool aStaticOnly=false)
@ LIMIT_CORNER_COUNT
Do not attempt to optimize if the resulting line's corner count is outside the predefined range.
@ SMART_PADS
Reroute pad exits.
@ FANOUT_CLEANUP
Simplify pad-pad and pad-via connections if possible.
@ MERGE_SEGMENTS
Reduce corner cost iteratively.
@ MERGE_COLINEAR
Merge co-linear segments.
@ MERGE_OBTUSE
Reduce corner cost by merging obtuse segments.
@ REQUIRE_OBTUSE_ANGLES
Try to prevent 90-degree or acute corners in a drag.
SHAPE_INDEX_LIST< ITEM * > m_cache
bool Check(int aVertex1, int aVertex2, const LINE *aOriginLine, const SHAPE_LINE_CHAIN &aCurrentPath, const SHAPE_LINE_CHAIN &aReplacement) override
virtual bool Check(int aVertex1, int aVertex2, const LINE *aOriginLine, const SHAPE_LINE_CHAIN &aCurrentPath, const SHAPE_LINE_CHAIN &aReplacement) override
ROUTING_SETTINGS & Settings()
static ROUTER * GetInstance()
DIRECTION_45::CORNER_MODE GetCornerMode() const
const SHAPE * Shape(int aLayer) const override
Return the geometrical shape of the item.
ecoord SquaredDistance(const SEG &aSeg) const
VECTOR2I::extended_type ecoord
int Index() const
Return the index of this segment in its parent shape (applicable only to non-local segments).
int Length() const
Return the length (this).
bool ApproxParallel(const SEG &aSeg, int aDistanceThreshold=1) const
bool Collinear(const SEG &aSeg) const
Check if segment aSeg lies on the same line as (this).
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
ecoord SquaredLength() const
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
EDA_ANGLE Angle(const SEG &aOther) const
Determine the smallest angle between two segments.
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...
int Intersect(const SEG &aSeg, std::vector< INTERSECTION > &aIp) const
Find all intersection points between our line chain and the segment aSeg.
const SHAPE_LINE_CHAIN Reverse() const
Reverse point order in the line chain.
bool IsPtOnArc(size_t aPtIndex) const
bool IsClosed() const override
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
void Replace(int aStartIndex, int aEndIndex, const VECTOR2I &aP)
Replace points with indices in range [start_index, end_index] with a single point aP.
void Clear()
Remove all points from the line chain.
double Area(bool aAbsolute=true) const
Return the area of this chain.
SHAPE_LINE_CHAIN & Simplify2(bool aRemoveColinear=true)
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex) const
Return a subset of this line chain containing the [start_index, end_index] range of points.
int SegmentCount() const
Return the number of segments in this line chain.
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
bool IsArcSegment(size_t aSegment) const
long long int Length() const
Return length of the line chain in Euclidean metric.
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
const VECTOR2I & GetPosition() const
const VECTOR2I GetSize() 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.
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_45
static constexpr EDA_ANGLE ANGLE_360
Push and Shove diff pair dimensions (gap) settings dialog.
int findCoupledVertices(const VECTOR2I &aVertex, const SEG &aOrigSeg, const SHAPE_LINE_CHAIN &aCoupled, DIFF_PAIR *aPair, std::vector< int > *aIndices)
bool tightenSegment(bool dir, NODE *aNode, const LINE &cur, const SHAPE_LINE_CHAIN &in, SHAPE_LINE_CHAIN &out)
SHAPE_RECT ApproximateSegmentAsRect(const SHAPE_SEGMENT &aSeg)
bool coupledBypass(NODE *aNode, DIFF_PAIR *aPair, bool aRefIsP, const SHAPE_LINE_CHAIN &aRef, const SHAPE_LINE_CHAIN &aRefBypass, const SHAPE_LINE_CHAIN &aCoupled, SHAPE_LINE_CHAIN &aNewCoupled)
void Tighten(NODE *aNode, const SHAPE_LINE_CHAIN &aOldLine, const LINE &aNewLine, LINE &aOptimized)
bool verifyDpBypass(NODE *aNode, DIFF_PAIR *aPair, bool aRefIsP, const SHAPE_LINE_CHAIN &aNewRef, const SHAPE_LINE_CHAIN &aNewCoupled)
bool checkDpColliding(NODE *aNode, DIFF_PAIR *aPair, bool aIsP, const SHAPE_LINE_CHAIN &aPath)
static bool pointInside2(const SHAPE_LINE_CHAIN &aL, const VECTOR2I &aP)
Determine if a point is located within a given polygon.
static int64_t shovedArea(const SHAPE_LINE_CHAIN &aOld, const SHAPE_LINE_CHAIN &aNew)
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ SH_RECT
axis-aligned rectangle
@ SH_SIMPLE
simple polygon
bool operator()(ITEM *aOtherItem)
CACHE_VISITOR(const ITEM *aOurItem, NODE *aNode, int aMask)
wxString result
Test unit parsing edge cases and error handling.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
VECTOR2< int32_t > VECTOR2I