56 if( aOther.m_via->BelongsTo( &aOther ) )
58 m_via = aOther.m_via->Clone();
59 m_via->SetOwner( this );
60 m_via->SetNet( m_net );
68 m_marker = aOther.m_marker;
69 m_rank = aOther.m_rank;
70 m_blockingObstacle = aOther.m_blockingObstacle;
101 m_via->SetOwner(
this );
130 m_line = std::move( aOther.m_line );
132 m_net = aOther.m_net;
140 if( aOther.m_via->BelongsTo( &aOther ) )
142 m_via = aOther.m_via->Clone();
143 m_via->SetOwner(
this );
148 m_via = aOther.m_via;
159 m_links = std::move( aOther.m_links );
187 s->Unmark( aMarker );
198 marker |= s->Marker();
222 for(
int i = 0; i <
m_line.SegmentCount() - 1; i++ )
225 const SEG seg2 =
m_line.CSegment( i + 1 );
241 if( x > 0 && x - 1 == y )
244 if( x < max - 1 && x + 1 == y )
250#ifdef TOM_EXTRA_DEBUG
265 while( head < origCount && head < pathCount
273 while( tail < origCount - head && tail < pathCount - head
274 && aOriginal.
CPoint( origCount - 1 - tail ) == aPath.
CPoint( pathCount - 1 - tail ) )
279 if( head == 0 && tail == 0 )
285 rebuilt = aOriginal.
Slice( 0, head - 1 );
287 if( head + tail < pathCount )
288 rebuilt.
Append( aPath.
Slice( std::max( head - 1, 0 ), pathCount - tail - 1 ) );
291 rebuilt.
Append( aOriginal.
Slice( origCount - tail, origCount - 1 ) );
293 aPath = std::move( rebuilt );
317 enum VERTEX_TYPE { INSIDE = 0,
OUTSIDE, ON_EDGE };
330 std::vector<VERTEX*> neighbours;
336 bool visited =
false;
345 std::vector<VERTEX> vts;
360 if(
const std::optional<SHAPE_LINE_CHAIN::INTERSECTION> isect = pnew.SelfIntersecting() )
362 if( isect->p != pnew.CLastPoint() )
363 pnew.Split( isect->p );
369 if( pnew.Find( ip.p, 1 ) < 0)
372 if( hnew.
Find( ip.p, 1 ) < 0 )
376 for(
int i = 0; i < pnew.PointCount(); i++ )
378 const VECTOR2I& p = pnew.CPoint( i );
384 int idx = hnew.
Find( p );
390 #ifdef TOM_EXTRA_DEBUG
391 for(
auto& ip : ips )
393 printf(
"Chk: %d %d\n", pnew.Find( ip.p ), hnew.
Find(ip.p) );
402 vts.reserve( 2 * ( hnew.
PointCount() + pnew.PointCount() ) );
405 for(
int i = 0; i < pnew.PointCount(); i++ )
411 #ifdef TOM_EXTRA_DEBUG
412 printf(
"pnew %d inside %d onedge %d\n", i, !!inside, !!onEdge );
420 v.type = inside && !onEdge ? INSIDE : onEdge ? ON_EDGE :
OUTSIDE;
424 #ifdef TOM_EXTRA_DEBUG
430 for(
int i = 0; i < pnew.PointCount() - 1; i++ )
432 vts[i].neighbours.push_back( &vts[ i+1 ] );
436 for(
int i = 1; i < pnew.PointCount() ; i++ )
438 vts[i].neighbours.push_back( &vts[ i-1 ] );
472 vc->neighbours.push_back( vnext );
480 int lastDst = INT_MAX;
482#ifdef TOM_EXTRA_DEBUG
487 if( v.indexh < 0 && v.type == ON_EDGE )
490 printf(
"V %d pos %d %d ip %d ih %d type %d\n", i++, v.pos.x, v.pos.y, v.indexp, v.indexh, v.type );
498 int iterLimit = 1000;
501 while( v->indexp != ( pnew.PointCount() - 1 ) )
516#ifdef TOM_EXTRA_DEBUG
517 printf(
"---\nvisit ip %d ih %d type %d outs %d neig %d\n", v->indexp, v->indexh, v->type, out.
PointCount(), v->neighbours.size() );
528 VERTEX* v_next_fallback =
nullptr;
530 for(
VERTEX* vn : v->neighbours )
532 if(
areNeighbours( vn->indexp , v->indexp, pnew.PointCount() )
533 && vn->type != INSIDE )
540 else if( vn != v_prev )
542 v_next_fallback = vn;
548 v_next = v_next_fallback;
553 #ifdef TOM_EXTRA_DEBUG
554 printf(
"FAIL VN fallback %p\n", v_next_fallback );
559 else if( v->type == ON_EDGE )
562 for(
VERTEX* vn : v->neighbours )
564#ifdef TOM_EXTRA_DEBUG
565 printf(
"- OUT scan ip %d ih %d type %d\n", vn->indexp, vn->indexh, vn->type );
568 if( vn->type ==
OUTSIDE && !vn->visited )
578 for(
VERTEX* vn : v->neighbours )
580 #ifdef TOM_EXTRA_DEBUG
581 printf(
"- scan ip %d ih %d type %d\n", vn->indexp, vn->indexh, vn->type );
583 if( vn->type == ON_EDGE && !vn->isHull &&
585 ( vn->indexh == ( ( v->indexh + 1 ) % hnew.
PointCount() ) ) )
597#ifdef TOM_EXTRA_DEBUG
598 printf(
"still no v_next\n");
600 for(
VERTEX* vn : v->neighbours )
602 if( vn->type == ON_EDGE )
604 if( vn->indexh == ( ( v->indexh + 1 ) % hnew.
PointCount() ) )
621#ifdef TOM_EXTRA_DEBUG
622 printf(
"v_next %p\n", v_next);
628 if( inLast && v_next )
630 int d = ( v_next->pos -
CLastPoint() ).SquaredEuclideanNorm();
663 aPath = std::move( out );
681 const int IterationLimit = 5;
685 for( i = 0; i < IterationLimit; i++ )
692 VECTOR2I collisionPoint = obs->m_ipFirst;
714 if( i == IterationLimit )
724 std::optional<SHAPE_LINE_CHAIN> picked;
755 for(
int j = 0; j < 2; j++ )
759 if( paths[j].SegmentCount() < 1 )
762 assert( dirCount <
int(
sizeof( dirs ) /
sizeof( dirs[0] ) ) );
764 dirs[dirCount] =
DIRECTION_45( paths[j].CSegment( 0 ) );
770 for(
int j = 0; j < dirCount; j++ )
773 if( endingDir == aPreferredEndingDirection )
783 for(
int j = 0; j < dirCount; j++ )
785 if( dirs[j] == d_start )
796 for(
int j = 0; j < dirCount; j++ )
798 if( dirs[j].IsObtuse( d_prev ) )
812 path.Append( *picked );
827 int width =
m_line.Width();
834 else if( aIndex ==
m_line.SegmentCount() )
841 if(
m_line.IsPtOnArc(
static_cast<size_t>( aIndex ) + 1 ) )
842 m_line.Insert( aIndex + 1,
m_line.CPoint( aIndex + 1 ) );
848 path.Append( path_rev );
852 path.SetWidth( width );
859 ssize_t idx =
static_cast<ssize_t
>( aIndex );
860 ssize_t numpts =
static_cast<ssize_t
>(
m_line.PointCount() );
863 if(
m_line.IsPtOnArc( idx ) )
865 if( idx == 0 || ( idx > 0 && !
m_line.IsPtOnArc( idx - 1 ) ) )
869 else if( ( idx == numpts - 1 ) || ( idx < numpts - 1 && !
m_line.IsArcSegment( idx ) ) )
876 wxASSERT_MSG(
false, wxT(
"Attempt to dragCornerFree in the middle of an arc!" ) );
880 m_line.SetPoint( idx, aP );
886 wxCHECK_RET( aIndex >= 0, wxT(
"Negative index passed to LINE::DragCorner" ) );
913 if( aIndex < 0 || aIndex >=
m_line.PointCount() )
916 ssize_t arcIdx =
m_line.ArcIndex( aIndex );
924 for(
int i = 0; i <
m_line.PointCount(); i++ )
926 if(
m_line.ArcIndex( i ) == arcIdx )
935 if( firstArcPt < 0 || lastArcPt < 0 )
941 auto tangentLineAtArcEndpoint = [&](
const VECTOR2I& aEndpoint ) ->
SEG
946 return SEG( aEndpoint - perp, aEndpoint + perp );
949 auto isCollinearTo = [&](
const SEG& aA,
const SEG& aB,
double aMaxDeviationDeg ) ->
bool
956 if( magA <= 0 || magB <= 0 )
959 double crossMag =
std::abs( dirA.
x * dirB.
y - dirA.
y * dirB.
x );
960 double sinAngle = crossMag / ( magA * magB );
961 double angleDeg = std::asin( std::clamp( sinAngle, 0.0, 1.0 ) ) * 180.0 /
M_PI;
963 return angleDeg <= aMaxDeviationDeg;
967 SEG arcLineStart = tangentLineAtArcEndpoint( oldArc.
GetP0() );
968 SEG arcLineEnd = tangentLineAtArcEndpoint( oldArc.
GetP1() );
970 bool useChainStart =
false;
971 bool useChainEnd =
false;
975 SEG candidate(
m_line.CPoint( firstArcPt - 1 ),
m_line.CPoint( firstArcPt ) );
977 if( isCollinearTo( candidate, arcLineStart, maxDeviation ) )
978 useChainStart =
true;
981 if( lastArcPt <
m_line.PointCount() - 1 )
983 SEG candidate(
m_line.CPoint( lastArcPt ),
m_line.CPoint( lastArcPt + 1 ) );
985 if( isCollinearTo( candidate, arcLineEnd, maxDeviation ) )
991 SEG tanStartSeg, tanEndSeg;
995 tanStartSeg =
SEG(
m_line.CPoint( firstArcPt - 1 ),
m_line.CPoint( firstArcPt ) );
999 if( !arcOwnTanIntersect )
1002 tanStartSeg =
SEG( *arcOwnTanIntersect, oldArc.
GetP0() );
1007 tanEndSeg =
SEG(
m_line.CPoint( lastArcPt ),
m_line.CPoint( lastArcPt + 1 ) );
1011 if( !arcOwnTanIntersect )
1014 tanEndSeg =
SEG( *arcOwnTanIntersect, oldArc.
GetP1() );
1024 SEG tanStartFromIntersect =
SEG( *tanIntersect, oldArc.
GetP0() );
1025 SEG tanEndFromIntersect =
SEG( *tanIntersect, oldArc.
GetP1() );
1029 return ( aA - *tanIntersect ).EuclideanNorm() > ( aB - *tanIntersect ).EuclideanNorm() ? aA : aB;
1032 VECTOR2I tanStartFar = furthestFromIntersect( tanStartSeg.
A, tanStartSeg.
B );
1033 VECTOR2I tanEndFar = furthestFromIntersect( tanEndSeg.
A, tanEndSeg.
B );
1034 VECTOR2I tempTangentPoint = furthestFromIntersect( tanStartFar, tanEndFar ) == tanEndFar ? tanStartFar : tanEndFar;
1042 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
1043 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
1044 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
1047 int cSegTanStartSide = cSegTanStart.
Side( oldMid );
1048 int cSegTanEndSide = cSegTanEnd.
Side( oldMid );
1049 int cSegChordSide = cSegChord.
Side( oldMid );
1053 if( cSegTanStartSide != cSegTanStart.
Side(
cursor ) || cSegTanEndSide != cSegTanEnd.
Side(
cursor )
1054 || cSegChordSide != cSegChord.
Side(
cursor ) )
1060 if( ( candidate -
cursor ).SquaredEuclideanNorm() < ( best -
cursor ).SquaredEuclideanNorm() )
1086 int prefixCutoff = useChainStart ? ( firstArcPt - 1 ) : firstArcPt;
1087 int suffixCutoff = useChainEnd ? ( lastArcPt + 1 ) : lastArcPt;
1089 if( ( newEnd - newStart ).EuclideanNorm() <= maxStubIU )
1094 if( prefixCutoff >= 0 )
1097 if( suffixCutoff <=
m_line.PointCount() - 1 )
1104 if( firstArcPt > 0 )
1108 if( (
anchor - newStart ).EuclideanNorm() <= maxStubIU )
1111 prefixCutoff = useChainStart ? ( firstArcPt - 2 ) : ( firstArcPt - 1 );
1115 if( lastArcPt <
m_line.PointCount() - 1 )
1119 if( (
anchor - newEnd ).EuclideanNorm() <= maxStubIU )
1122 suffixCutoff = useChainEnd ? ( lastArcPt + 2 ) : ( lastArcPt + 1 );
1127 SHAPE_ARC newArc( newStart, newMid, newEnd, width );
1132 if( prefixCutoff >= 0 )
1135 rebuilt.
Append( newArc );
1137 if( suffixCutoff <=
m_line.PointCount() - 1 )
1146 int s_start = std::max( aIndex - 2, 0 );
1147 int s_end = std::min( aIndex + 2, aPath.
SegmentCount() - 1 );
1150 int best_dist = INT_MAX;
1156 for( i = s_start; i <= s_end; i++ )
1160 for( j = s_start; j < i; j++ )
1171 int dist = ( *ip - aP ).EuclideanNorm();
1190 int snap_d[2] = { -1, -1 };
1216 int minDist = INT_MAX;
1218 for(
int i = 0; i < 2; i++ )
1220 if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <=
m_snapThreshhold )
1222 minDist = snap_d[i];
1235 wxASSERT( aIndex <
m_line.PointCount() );
1237 SEG guideA[2], guideB[2];
1255 path.Insert(
path.PointCount() - 1,
path.CLastPoint() );
1271 if( dir_prev == drag_dir )
1273 dir_prev = dir_prev.
Left();
1279 dir_prev = drag_dir.
Left();
1282 if( dir_next == drag_dir )
1284 dir_next = dir_next.
Right();
1289 dir_next = drag_dir.
Right();
1303 if( dir_prev.
Angle( drag_dir )
1310 guideA[0] = guideA[1] =
SEG( dragged.
A, dragged.
A + dir_prev.
ToVector() );
1313 if( aIndex ==
m_line.SegmentCount() - 1 )
1320 if( dir_next.
Angle( drag_dir )
1327 guideB[0] = guideB[1] =
SEG( dragged.
B, dragged.
B + dir_next.
ToVector() );
1330 SEG s_current( target, target + drag_dir.
ToVector() );
1332 int best_len = INT_MAX;
1335 for(
int i = 0; i < 2; i++ )
1337 for(
int j = 0; j < 2; j++ )
1347 SEG s1( s_prev.
A, *ip1 );
1348 SEG s2( *ip1, *ip2 );
1349 SEG s3( *ip2, s_next.
B );
1359 else if( ( ip = s3.
Intersect( s_prev ) ) )
1379 if( np.
Length() < best_len )
1382 best = std::move( np );
1387 if(
m_line.PointCount() == 1 )
1389 else if( aIndex == 0 )
1390 m_line.Replace( 0, 1, best );
1391 else if( aIndex ==
m_line.SegmentCount() - 1 )
1392 m_line.Replace( -2, -1, best );
1394 m_line.Replace( aIndex, aIndex + 1, best );
1422 m_via->SetOwner(
this );
1444 s->SetRank( aRank );
1451 int min_rank = INT_MAX;
1456 min_rank = std::min( min_rank, item->Rank() );
1463 int rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
1478 int lastLink = std::max( 0,
static_cast<int>(
m_links.size() ) - 1 );
1481 for(
int i = 0; i >= 0 && i <
m_line.PointCount(); i =
m_line.NextShape( i ) )
1484 firstLink = linkIdx;
1486 if( i < 0 || i >= aEnd - 1 || linkIdx >= lastLink )
1495 wxASSERT( lastLink >= firstLink );
1501 wxASSERT(
m_links.size() < INT_MAX );
1502 wxASSERT(
static_cast<int>(
m_links.size() ) >= ( lastLink - firstLink ) );
1511 m_links.resize( lastLink - firstLink + 1 );
1548 bool areaDefined =
false;
1551 int i_end_self = -1, i_end_other = -1;
1561 int n = std::min( np_self, np_other );
1563 for(
int i = 0; i < n; i++ )
1588 for(
int i = 0; i < n; i++ )
1595 i_end_self = np_self - 1 - i;
1596 i_end_other = np_other - 1 - i;
1604 if( i_end_self < 0 )
1605 i_end_self = np_self - 1;
1607 if( i_end_other < 0 )
1608 i_end_other = np_other - 1;
1610 for(
int i = i_start; i <= i_end_self; i++ )
1613 for(
int i = i_start; i <= i_end_other; i++ )
1628 for(
const auto seg :
m_links )
1651 if(
m_via->BelongsTo(
this ) )
1661 std::stringstream ss;
1663 ss <<
m_seg.Format(
false );
1670 for(
int i = 0; i <
m_line.SegmentCount(); i++)
1673 if( s == aSeg->
Seg() )
1683 for(
auto lnk :
Links() )
1687 if( seg->Seg() == aSeg || seg->Seg() == aSeg.
Reversed() )
1698 for(
auto lnk :
Links() )
1702 if( seg->Seg().Contains( aP ) )
constexpr EDA_IU_SCALE pcbIUScale
std::optional< BOX2I > OPT_BOX2I
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Represent basic circle geometry with utility geometry functions.
VECTOR2I Center
Public to make access simpler.
int Radius
Public to make access simpler.
CIRCLE & ConstructFromTanTanPt(const SEG &aLineA, const SEG &aLineB, const VECTOR2I &aP)
Construct this circle such that it is tangent to the given segments and passes through the given poin...
VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute the point on the circumference of the circle that is the closest to aP.
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.
const DIRECTION_45 Left() const
Return the direction on the left side of this (i.e.
const VECTOR2I ToVector() const
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.
const DIRECTION_45 Right() const
Return the direction on the right side of this (i.e.
BOARD_ITEM * m_sourceItem
virtual const std::string Format() const
VECTOR2I snapToNeighbourSegments(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
void ClipVertexRange(int aStart, int aEnd)
Return the number of corners of angles specified by mask aAngles.
int FindSegment(const SEGMENT *aSeg) const
const VECTOR2I & CPoint(int aIdx) const
OPT_BOX2I ChangedArea(const LINE *aOther) const
bool HasLockedSegments() const
int Rank() const override
void dragCorner45(const VECTOR2I &aP, int aIndex, DIRECTION_45 aPreferredEndingDirection)
const LINE ClipToNearestObstacle(NODE *aNode) const
Clip the line to a given range of vertices.
void DragArc(const VECTOR2I &aP, int aIndex)
virtual void Mark(int aMarker) const override
bool CompareGeometry(const LINE &aOther)
Reverse the point/vertex order.
ITEM * m_blockingObstacle
For mark obstacle mode.
const SHAPE_LINE_CHAIN & CLine() const
VECTOR2I snapDraggedCorner(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
LINE & operator=(const LINE &aOther)
void dragSegment45(const VECTOR2I &aP, int aIndex)
const VECTOR2I & CLastPoint() const
int CountCorners(int aAngles) const
void SetRank(int aRank) override
LINE()
Makes an empty line.
SHAPE_LINE_CHAIN & Line()
void DragCorner(const VECTOR2I &aP, int aIndex, bool aFreeAngle=false, DIRECTION_45 aPreferredEndingDirection=DIRECTION_45())
virtual int Marker() const override
void AppendVia(const VIA &aVia)
SEGMENT * FindLinkedSegment(const SEG &aSeg) const
Assign a shape to the line (a polyline/line chain).
virtual void Unmark(int aMarker=-1) const override
SEGMENT * FindLinkContainingVertex(const VECTOR2I &aP) const
int m_snapThreshhold
Width to smooth out jagged segments.
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
void DragSegment(const VECTOR2I &aP, int aIndex, bool aFreeAngle=false)
bool Walkaround(SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN &aPre, SHAPE_LINE_CHAIN &aWalk, SHAPE_LINE_CHAIN &aPost, bool aCw) const
Calculate a line tightly wrapping a convex hull of an obstacle object (aObstacle).
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
void dragCornerFree(const VECTOR2I &aP, int aIndex)
virtual LINE * Clone() const override
Return a deep copy of the item.
int Width() const
Return true if the line is geometrically identical as line aOther.
void restoreUntouchedArcs(SHAPE_LINE_CHAIN &aPath, const SHAPE_LINE_CHAIN &aOriginal) const
Used to rebuild arcs in the walkaround since the graph only stores vertices.
void copyLinks(const LINK_HOLDER *aParent)
< Copy m_links from the line aParent.
void Unlink(const LINKED_ITEM *aLink)
Return the list of links from the owning node that constitute this line (or NULL if the line is not l...
void Link(LINKED_ITEM *aLink)
bool IsLinked() const
Check if the segment aLink is a part of the line.
bool ContainsLink(const LINKED_ITEM *aItem) const
std::vector< LINKED_ITEM * > & Links()
std::vector< LINKED_ITEM * > m_links
LINK_HOLDER(PnsKind aKind)
Add a reference to an item registered in a NODE that is a part of this line.
virtual void ClearLinks()
Return the number of segments that were assembled together to form this line.
Keep the router "world" - i.e.
std::optional< OBSTACLE > OPT_OBSTACLE
OPT_OBSTACLE NearestObstacle(const LINE *aLine, const COLLISION_SEARCH_OPTIONS &aOpts=COLLISION_SEARCH_OPTIONS())
Follow the line in search of an obstacle that is nearest to the starting to the line's starting point...
const ITEM_OWNER * m_owner
bool BelongsTo(const ITEM_OWNER *aNode) const
virtual const std::string Format() const override
SEGMENT * Clone() const override
Return a deep copy of the item.
const SHAPE_LINE_CHAIN Hull(int aClearance, int aWalkaroundThickness, int aLayer=-1) const override
const VECTOR2I & Pos() const
VIA * Clone() const override
Return a deep copy of the item.
int LineDistance(const VECTOR2I &aP, bool aDetermineSide=false) const
Return the closest Euclidean distance between point aP and the line defined by the ends of segment (t...
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
bool Contains(const SEG &aSeg) const
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
int Side(const VECTOR2I &aP) const
Determine on which side of directed line passing via segment ends point aP lies.
SEG Reversed() const
Returns the center point of the line.
const VECTOR2I & GetArcMid() const
int GetWidth() const override
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
const VECTOR2I & GetCenter() const
bool PointOnEdge(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of the line chain.
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.
int Split(const VECTOR2I &aP, bool aExact=false)
Insert the point aP belonging to one of the our segments, splitting the adjacent segment in two.
int PointCount() const
Return the number of points (vertices) in this line chain.
void Clear()
Remove all points from the line chain.
void Simplify(int aTolerance=0)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
void SetWidth(int aWidth) override
Set the width of all segments in the chain.
int NearestSegment(const VECTOR2I &aP) const
Find the segment nearest the given point.
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
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const override
Check if point aP lies inside a closed shape.
std::vector< INTERSECTION > INTERSECTIONS
long long int Length() const
Return length of the line chain in Euclidean metric.
int Find(const VECTOR2I &aP, int aThreshold=0) const
Search for point aP.
const std::vector< VECTOR2I > & CPoints() const
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
double m_MaxTangentAngleDeviation
Maximum angle between the tangent line of an arc track and a connected straight track in order to com...
Push and Shove diff pair dimensions (gap) settings dialog.
static void extendBox(BOX2I &aBox, bool &aDefined, const VECTOR2I &aP)
void HullIntersection(const SHAPE_LINE_CHAIN &hull, const SHAPE_LINE_CHAIN &line, SHAPE_LINE_CHAIN::INTERSECTIONS &ips)
static int areNeighbours(int x, int y, int max=0)
SHAPE_LINE_CHAIN dragCornerInternal(const SHAPE_LINE_CHAIN &aOrigin, const VECTOR2I &aP, DIRECTION_45 aPreferredEndingDirection=DIRECTION_45())
const SHAPE_LINE_CHAIN SegmentHull(const SHAPE_SEGMENT &aSeg, int aClearance, int aWalkaroundThickness)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ OUTSIDE
Text appears outside the dimension line (default)
static std::pair< bool, SHAPE_POLY_SET::VERTEX_INDEX > findVertex(SHAPE_POLY_SET &aPolySet, const EDIT_POINT &aPoint)
std::optional< VECTOR2I > OPT_VECTOR2I
Represent an intersection between two line segments.
CADSTAR_ARCHIVE_PARSER::VERTEX_TYPE vt
const VECTOR2I CalcArcMid(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aMinArcAngle=true)
Return the middle point of an arc, half-way between aStart and aEnd.
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D