78 m_via->SetOwner(
this );
102 if(
this == &aOther )
137 m_line = std::move( aOther.m_line );
139 m_net = aOther.m_net;
153 m_links = std::move( aOther.m_links );
181 s->Unmark( aMarker );
192 marker |= s->Marker();
216 for(
int i = 0; i <
m_line.SegmentCount() - 1; i++ )
219 const SEG seg2 =
m_line.CSegment( i + 1 );
235 if( x > 0 && x - 1 == y )
238 if( x < max - 1 && x + 1 == y )
244#ifdef TOM_EXTRA_DEBUG
259 while( head < origCount && head < pathCount
267 while( tail < origCount - head && tail < pathCount - head
268 && aOriginal.
CPoint( origCount - 1 - tail ) == aPath.
CPoint( pathCount - 1 - tail ) )
273 if( head == 0 && tail == 0 )
279 rebuilt = aOriginal.
Slice( 0, head - 1 );
281 if( head + tail < pathCount )
282 rebuilt.
Append( aPath.
Slice( std::max( head - 1, 0 ), pathCount - tail - 1 ) );
285 rebuilt.
Append( aOriginal.
Slice( origCount - tail, origCount - 1 ) );
287 aPath = std::move( rebuilt );
311 enum VERTEX_TYPE { INSIDE = 0,
OUTSIDE, ON_EDGE };
324 std::vector<VERTEX*> neighbours;
330 bool visited =
false;
333 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> ips;
339 std::vector<VERTEX> vts;
354 if(
const std::optional<SHAPE_LINE_CHAIN::INTERSECTION> isect = pnew.SelfIntersecting() )
356 if( isect->p != pnew.CLastPoint() )
357 pnew.Split( isect->p );
363 if( pnew.Find( ip.p, 1 ) < 0)
366 if( hnew.
Find( ip.p, 1 ) < 0 )
370 for(
int i = 0; i < pnew.PointCount(); i++ )
372 const VECTOR2I& p = pnew.CPoint( i );
378 int idx = hnew.
Find( p );
384 #ifdef TOM_EXTRA_DEBUG
385 for(
auto& ip : ips )
387 printf(
"Chk: %d %d\n", pnew.Find( ip.p ), hnew.
Find(ip.p) );
396 vts.reserve( 2 * ( hnew.
PointCount() + pnew.PointCount() ) );
399 for(
int i = 0; i < pnew.PointCount(); i++ )
405 #ifdef TOM_EXTRA_DEBUG
406 printf(
"pnew %d inside %d onedge %d\n", i, !!inside, !!onEdge );
414 v.type = inside && !onEdge ? INSIDE : onEdge ? ON_EDGE :
OUTSIDE;
418 #ifdef TOM_EXTRA_DEBUG
424 for(
int i = 0; i < pnew.PointCount() - 1; i++ )
426 vts[i].neighbours.push_back( &vts[ i+1 ] );
430 for(
int i = 1; i < pnew.PointCount() ; i++ )
432 vts[i].neighbours.push_back( &vts[ i-1 ] );
466 vc->neighbours.push_back( vnext );
474 int lastDst = INT_MAX;
476#ifdef TOM_EXTRA_DEBUG
481 if( v.indexh < 0 && v.type == ON_EDGE )
484 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 );
492 int iterLimit = 1000;
495 while( v->indexp != ( pnew.PointCount() - 1 ) )
510#ifdef TOM_EXTRA_DEBUG
511 printf(
"---\nvisit ip %d ih %d type %d outs %d neig %d\n", v->indexp, v->indexh, v->type, out.
PointCount(), v->neighbours.size() );
522 VERTEX* v_next_fallback =
nullptr;
524 for(
VERTEX* vn : v->neighbours )
526 if(
areNeighbours( vn->indexp , v->indexp, pnew.PointCount() )
527 && vn->type != INSIDE )
534 else if( vn != v_prev )
536 v_next_fallback = vn;
542 v_next = v_next_fallback;
547 #ifdef TOM_EXTRA_DEBUG
548 printf(
"FAIL VN fallback %p\n", v_next_fallback );
553 else if( v->type == ON_EDGE )
556 for(
VERTEX* vn : v->neighbours )
558#ifdef TOM_EXTRA_DEBUG
559 printf(
"- OUT scan ip %d ih %d type %d\n", vn->indexp, vn->indexh, vn->type );
562 if( vn->type ==
OUTSIDE && !vn->visited )
572 for(
VERTEX* vn : v->neighbours )
574 #ifdef TOM_EXTRA_DEBUG
575 printf(
"- scan ip %d ih %d type %d\n", vn->indexp, vn->indexh, vn->type );
577 if( vn->type == ON_EDGE && !vn->isHull &&
579 ( vn->indexh == ( ( v->indexh + 1 ) % hnew.
PointCount() ) ) )
591#ifdef TOM_EXTRA_DEBUG
592 printf(
"still no v_next\n");
594 for(
VERTEX* vn : v->neighbours )
596 if( vn->type == ON_EDGE )
598 if( vn->indexh == ( ( v->indexh + 1 ) % hnew.
PointCount() ) )
615#ifdef TOM_EXTRA_DEBUG
616 printf(
"v_next %p\n", v_next);
622 if( inLast && v_next )
624 int d = ( v_next->pos -
CLastPoint() ).SquaredEuclideanNorm();
657 aPath = std::move( out );
675 const int IterationLimit = 5;
679 for( i = 0; i < IterationLimit; i++ )
686 VECTOR2I collisionPoint = obs->m_ipFirst;
708 if( i == IterationLimit )
718 std::optional<SHAPE_LINE_CHAIN> picked;
749 for(
int j = 0; j < 2; j++ )
753 if( paths[j].SegmentCount() < 1 )
756 assert( dirCount <
int(
sizeof( dirs ) /
sizeof( dirs[0] ) ) );
758 dirs[dirCount] =
DIRECTION_45( paths[j].CSegment( 0 ) );
764 for(
int j = 0; j < dirCount; j++ )
767 if( endingDir == aPreferredEndingDirection )
777 for(
int j = 0; j < dirCount; j++ )
779 if( dirs[j] == d_start )
790 for(
int j = 0; j < dirCount; j++ )
792 if( dirs[j].IsObtuse( d_prev ) )
806 path.Append( *picked );
821 int width =
m_line.Width();
828 else if( aIndex ==
m_line.SegmentCount() )
835 if(
m_line.IsPtOnArc(
static_cast<size_t>( aIndex ) + 1 ) )
836 m_line.Insert( aIndex + 1,
m_line.CPoint( aIndex + 1 ) );
842 path.Append( path_rev );
846 path.SetWidth( width );
853 ssize_t idx =
static_cast<ssize_t
>( aIndex );
854 ssize_t numpts =
static_cast<ssize_t
>(
m_line.PointCount() );
857 if(
m_line.IsPtOnArc( idx ) )
859 if( idx == 0 || ( idx > 0 && !
m_line.IsPtOnArc( idx - 1 ) ) )
863 else if( ( idx == numpts - 1 ) || ( idx < numpts - 1 && !
m_line.IsArcSegment( idx ) ) )
870 wxASSERT_MSG(
false, wxT(
"Attempt to dragCornerFree in the middle of an arc!" ) );
874 m_line.SetPoint( idx, aP );
880 wxCHECK_RET( aIndex >= 0, wxT(
"Negative index passed to LINE::DragCorner" ) );
907 if( aIndex < 0 || aIndex >=
m_line.PointCount() )
910 ssize_t arcIdx =
m_line.ArcIndex( aIndex );
918 for(
int i = 0; i <
m_line.PointCount(); i++ )
920 if(
m_line.ArcIndex( i ) == arcIdx )
929 if( firstArcPt < 0 || lastArcPt < 0 )
935 auto tangentLineAtArcEndpoint = [&](
const VECTOR2I& aEndpoint ) ->
SEG
940 return SEG( aEndpoint - perp, aEndpoint + perp );
943 auto isCollinearTo = [&](
const SEG& aA,
const SEG& aB,
double aMaxDeviationDeg ) ->
bool
950 if( magA <= 0 || magB <= 0 )
953 double crossMag =
std::abs( dirA.
x * dirB.
y - dirA.
y * dirB.
x );
954 double sinAngle = crossMag / ( magA * magB );
955 double angleDeg = std::asin( std::clamp( sinAngle, 0.0, 1.0 ) ) * 180.0 /
M_PI;
957 return angleDeg <= aMaxDeviationDeg;
961 SEG arcLineStart = tangentLineAtArcEndpoint( oldArc.
GetP0() );
962 SEG arcLineEnd = tangentLineAtArcEndpoint( oldArc.
GetP1() );
964 bool useChainStart =
false;
965 bool useChainEnd =
false;
969 SEG candidate(
m_line.CPoint( firstArcPt - 1 ),
m_line.CPoint( firstArcPt ) );
971 if( isCollinearTo( candidate, arcLineStart, maxDeviation ) )
972 useChainStart =
true;
975 if( lastArcPt <
m_line.PointCount() - 1 )
977 SEG candidate(
m_line.CPoint( lastArcPt ),
m_line.CPoint( lastArcPt + 1 ) );
979 if( isCollinearTo( candidate, arcLineEnd, maxDeviation ) )
985 SEG tanStartSeg, tanEndSeg;
989 tanStartSeg =
SEG(
m_line.CPoint( firstArcPt - 1 ),
m_line.CPoint( firstArcPt ) );
993 if( !arcOwnTanIntersect )
996 tanStartSeg =
SEG( *arcOwnTanIntersect, oldArc.
GetP0() );
1001 tanEndSeg =
SEG(
m_line.CPoint( lastArcPt ),
m_line.CPoint( lastArcPt + 1 ) );
1005 if( !arcOwnTanIntersect )
1008 tanEndSeg =
SEG( *arcOwnTanIntersect, oldArc.
GetP1() );
1018 SEG tanStartFromIntersect =
SEG( *tanIntersect, oldArc.
GetP0() );
1019 SEG tanEndFromIntersect =
SEG( *tanIntersect, oldArc.
GetP1() );
1023 return ( aA - *tanIntersect ).EuclideanNorm() > ( aB - *tanIntersect ).EuclideanNorm() ? aA : aB;
1026 VECTOR2I tanStartFar = furthestFromIntersect( tanStartSeg.
A, tanStartSeg.
B );
1027 VECTOR2I tanEndFar = furthestFromIntersect( tanEndSeg.
A, tanEndSeg.
B );
1028 VECTOR2I tempTangentPoint = furthestFromIntersect( tanStartFar, tanEndFar ) == tanEndFar ? tanStartFar : tanEndFar;
1036 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
1037 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
1038 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
1041 int cSegTanStartSide = cSegTanStart.
Side( oldMid );
1042 int cSegTanEndSide = cSegTanEnd.
Side( oldMid );
1043 int cSegChordSide = cSegChord.
Side( oldMid );
1047 if( cSegTanStartSide != cSegTanStart.
Side(
cursor ) || cSegTanEndSide != cSegTanEnd.
Side(
cursor )
1048 || cSegChordSide != cSegChord.
Side(
cursor ) )
1054 if( ( candidate -
cursor ).SquaredEuclideanNorm() < ( best -
cursor ).SquaredEuclideanNorm() )
1080 int prefixCutoff = useChainStart ? ( firstArcPt - 1 ) : firstArcPt;
1081 int suffixCutoff = useChainEnd ? ( lastArcPt + 1 ) : lastArcPt;
1083 if( ( newEnd - newStart ).EuclideanNorm() <= maxStubIU )
1088 if( prefixCutoff >= 0 )
1091 if( suffixCutoff <=
m_line.PointCount() - 1 )
1098 if( firstArcPt > 0 )
1102 if( (
anchor - newStart ).EuclideanNorm() <= maxStubIU )
1105 prefixCutoff = useChainStart ? ( firstArcPt - 2 ) : ( firstArcPt - 1 );
1109 if( lastArcPt <
m_line.PointCount() - 1 )
1113 if( (
anchor - newEnd ).EuclideanNorm() <= maxStubIU )
1116 suffixCutoff = useChainEnd ? ( lastArcPt + 2 ) : ( lastArcPt + 1 );
1121 SHAPE_ARC newArc( newStart, newMid, newEnd, width );
1126 if( prefixCutoff >= 0 )
1129 rebuilt.
Append( newArc );
1131 if( suffixCutoff <=
m_line.PointCount() - 1 )
1140 int s_start = std::max( aIndex - 2, 0 );
1141 int s_end = std::min( aIndex + 2, aPath.
SegmentCount() - 1 );
1144 int best_dist = INT_MAX;
1150 for( i = s_start; i <= s_end; i++ )
1154 for( j = s_start; j < i; j++ )
1165 int dist = ( *ip - aP ).EuclideanNorm();
1184 int snap_d[2] = { -1, -1 };
1210 int minDist = INT_MAX;
1212 for(
int i = 0; i < 2; i++ )
1214 if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <=
m_snapThreshhold )
1216 minDist = snap_d[i];
1229 wxASSERT( aIndex <
m_line.PointCount() );
1231 SEG guideA[2], guideB[2];
1249 path.Insert(
path.PointCount() - 1,
path.CLastPoint() );
1265 if( dir_prev == drag_dir )
1267 dir_prev = dir_prev.
Left();
1273 dir_prev = drag_dir.
Left();
1276 if( dir_next == drag_dir )
1278 dir_next = dir_next.
Right();
1283 dir_next = drag_dir.
Right();
1297 if( dir_prev.
Angle( drag_dir )
1304 guideA[0] = guideA[1] =
SEG( dragged.
A, dragged.
A + dir_prev.
ToVector() );
1307 if( aIndex ==
m_line.SegmentCount() - 1 )
1314 if( dir_next.
Angle( drag_dir )
1321 guideB[0] = guideB[1] =
SEG( dragged.
B, dragged.
B + dir_next.
ToVector() );
1324 SEG s_current( target, target + drag_dir.
ToVector() );
1326 int best_len = INT_MAX;
1329 for(
int i = 0; i < 2; i++ )
1331 for(
int j = 0; j < 2; j++ )
1341 SEG s1( s_prev.
A, *ip1 );
1342 SEG s2( *ip1, *ip2 );
1343 SEG s3( *ip2, s_next.
B );
1353 else if( ( ip = s3.
Intersect( s_prev ) ) )
1373 if( np.
Length() < best_len )
1376 best = std::move( np );
1381 if(
m_line.PointCount() == 1 )
1383 else if( aIndex == 0 )
1384 m_line.Replace( 0, 1, best );
1385 else if( aIndex ==
m_line.SegmentCount() - 1 )
1386 m_line.Replace( -2, -1, best );
1388 m_line.Replace( aIndex, aIndex + 1, best );
1418 m_via->SetOwner(
this );
1443 s->SetRank( aRank );
1450 int min_rank = INT_MAX;
1455 min_rank = std::min( min_rank, item->Rank() );
1462 int rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
1477 int lastLink = std::max( 0,
static_cast<int>(
m_links.size() ) - 1 );
1480 for(
int i = 0; i >= 0 && i <
m_line.PointCount(); i =
m_line.NextShape( i ) )
1483 firstLink = linkIdx;
1485 if( i < 0 || i >= aEnd - 1 || linkIdx >= lastLink )
1494 wxASSERT( lastLink >= firstLink );
1500 wxASSERT(
m_links.size() < INT_MAX );
1501 wxASSERT(
static_cast<int>(
m_links.size() ) >= ( lastLink - firstLink ) );
1510 m_links.resize( lastLink - firstLink + 1 );
1547 bool areaDefined =
false;
1550 int i_end_self = -1, i_end_other = -1;
1560 int n = std::min( np_self, np_other );
1562 for(
int i = 0; i < n; i++ )
1587 for(
int i = 0; i < n; i++ )
1594 i_end_self = np_self - 1 - i;
1595 i_end_other = np_other - 1 - i;
1603 if( i_end_self < 0 )
1604 i_end_self = np_self - 1;
1606 if( i_end_other < 0 )
1607 i_end_other = np_other - 1;
1609 for(
int i = i_start; i <= i_end_self; i++ )
1612 for(
int i = i_start; i <= i_end_other; i++ )
1627 for(
const auto seg :
m_links )
1655 std::stringstream ss;
1657 ss <<
m_seg.Format(
false );
1664 for(
int i = 0; i <
m_line.SegmentCount(); i++)
1667 if( s == aSeg->
Seg() )
1677 for(
auto lnk :
Links() )
1681 if( seg->Seg() == aSeg || seg->Seg() == aSeg.
Reversed() )
1692 for(
auto lnk :
Links() )
1696 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)
Clip the line to a given range of vertices.
int FindSegment(const SEGMENT *aSeg) const
const VECTOR2I & CPoint(int aIdx) const
Return the aIdx-th point of the line.
OPT_BOX2I ChangedArea(const LINE *aOther) const
bool HasLockedSegments() const
void dropVia()
Free a via this line owns and forget whichever via it had.
int Rank() const override
void dragCorner45(const VECTOR2I &aP, int aIndex, DIRECTION_45 aPreferredEndingDirection)
const LINE ClipToNearestObstacle(NODE *aNode) const
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
void DragArc(const VECTOR2I &aP, int aIndex)
virtual void Mark(int aMarker) const override
bool CompareGeometry(const LINE &aOther)
Return true if the line is geometrically identical as line aOther.
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
Return the number of corners of angles specified by mask aAngles.
void SetRank(int aRank) override
LINE()
Makes an empty line.
bool Walkaround(SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN &aPrePath, SHAPE_LINE_CHAIN &aWalk, SHAPE_LINE_CHAIN &aPost, bool aCw) const
Calculate a line tightly wrapping a convex hull of an obstacle object (aObstacle).
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape.
void DragCorner(const VECTOR2I &aP, int aIndex, bool aFreeAngle=false, DIRECTION_45 aPreferredEndingDirection=DIRECTION_45())
bool m_ownsVia
A via made by AppendVia() or copied from a line that owned its via is ours to free.
virtual int Marker() const override
void AppendVia(const VIA &aVia)
SEGMENT * FindLinkedSegment(const SEG &aSeg) const
Finds a linked SEGMENT whose endpoints match aSeg (either direction)
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)
void Reverse()
Reverse the point/vertex order.
void dragCornerFree(const VECTOR2I &aP, int aIndex)
virtual LINE * Clone() const override
Return a deep copy of the item.
void copyVia(const LINE &aOther)
Take a copy of another line's via if it owns one, or share the via it borrows.
int Width() const
Return line width.
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)
void Link(LINKED_ITEM *aLink)
Add a reference to an item registered in a NODE that is a part of this line.
bool ContainsLink(const LINKED_ITEM *aItem) const
Check if the segment aLink is a part of the line.
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...
std::vector< LINKED_ITEM * > m_links
List of segments in the owning NODE (ITEM::m_owner) that constitute this line, or NULL if the line is...
LINK_HOLDER(PnsKind aKind)
virtual void ClearLinks()
Erase the linking information. Used to detach the line from the owning node.
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
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.
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.
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)
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)
void HullIntersection(const SHAPE_LINE_CHAIN &hull, const SHAPE_LINE_CHAIN &line, std::vector< SHAPE_LINE_CHAIN::INTERSECTION > &ips)
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