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
274 enum VERTEX_TYPE { INSIDE = 0,
OUTSIDE, ON_EDGE };
287 std::vector<VERTEX*> neighbours;
293 bool visited =
false;
302 std::vector<VERTEX> vts;
317 if(
const std::optional<SHAPE_LINE_CHAIN::INTERSECTION> isect = pnew.SelfIntersecting() )
319 if( isect->p != pnew.CLastPoint() )
320 pnew.Split( isect->p );
326 if( pnew.Find( ip.p, 1 ) < 0)
329 if( hnew.
Find( ip.p, 1 ) < 0 )
333 for(
int i = 0; i < pnew.PointCount(); i++ )
335 const VECTOR2I& p = pnew.CPoint( i );
341 int idx = hnew.
Find( p );
347 #ifdef TOM_EXTRA_DEBUG
348 for(
auto& ip : ips )
350 printf(
"Chk: %d %d\n", pnew.Find( ip.p ), hnew.
Find(ip.p) );
359 vts.reserve( 2 * ( hnew.
PointCount() + pnew.PointCount() ) );
362 for(
int i = 0; i < pnew.PointCount(); i++ )
368 #ifdef TOM_EXTRA_DEBUG
369 printf(
"pnew %d inside %d onedge %d\n", i, !!inside, !!onEdge );
377 v.type = inside && !onEdge ? INSIDE : onEdge ? ON_EDGE :
OUTSIDE;
381 #ifdef TOM_EXTRA_DEBUG
387 for(
int i = 0; i < pnew.PointCount() - 1; i++ )
389 vts[i].neighbours.push_back( &vts[ i+1 ] );
393 for(
int i = 1; i < pnew.PointCount() ; i++ )
395 vts[i].neighbours.push_back( &vts[ i-1 ] );
429 vc->neighbours.push_back( vnext );
437 int lastDst = INT_MAX;
439#ifdef TOM_EXTRA_DEBUG
444 if( v.indexh < 0 && v.type == ON_EDGE )
447 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 );
455 int iterLimit = 1000;
458 while( v->indexp != ( pnew.PointCount() - 1 ) )
473#ifdef TOM_EXTRA_DEBUG
474 printf(
"---\nvisit ip %d ih %d type %d outs %d neig %d\n", v->indexp, v->indexh, v->type, out.
PointCount(), v->neighbours.size() );
485 VERTEX* v_next_fallback =
nullptr;
487 for(
VERTEX* vn : v->neighbours )
489 if(
areNeighbours( vn->indexp , v->indexp, pnew.PointCount() )
490 && vn->type != INSIDE )
497 else if( vn != v_prev )
499 v_next_fallback = vn;
505 v_next = v_next_fallback;
510 #ifdef TOM_EXTRA_DEBUG
511 printf(
"FAIL VN fallback %p\n", v_next_fallback );
516 else if( v->type == ON_EDGE )
519 for(
VERTEX* vn : v->neighbours )
521#ifdef TOM_EXTRA_DEBUG
522 printf(
"- OUT scan ip %d ih %d type %d\n", vn->indexp, vn->indexh, vn->type );
525 if( vn->type ==
OUTSIDE && !vn->visited )
535 for(
VERTEX* vn : v->neighbours )
537 #ifdef TOM_EXTRA_DEBUG
538 printf(
"- scan ip %d ih %d type %d\n", vn->indexp, vn->indexh, vn->type );
540 if( vn->type == ON_EDGE && !vn->isHull &&
542 ( vn->indexh == ( ( v->indexh + 1 ) % hnew.
PointCount() ) ) )
554#ifdef TOM_EXTRA_DEBUG
555 printf(
"still no v_next\n");
557 for(
VERTEX* vn : v->neighbours )
559 if( vn->type == ON_EDGE )
561 if( vn->indexh == ( ( v->indexh + 1 ) % hnew.
PointCount() ) )
578#ifdef TOM_EXTRA_DEBUG
579 printf(
"v_next %p\n", v_next);
585 if( inLast && v_next )
587 int d = ( v_next->pos -
CLastPoint() ).SquaredEuclideanNorm();
615 aPath = std::move( out );
633 const int IterationLimit = 5;
637 for( i = 0; i < IterationLimit; i++ )
644 VECTOR2I collisionPoint = obs->m_ipFirst;
666 if( i == IterationLimit )
676 std::optional<SHAPE_LINE_CHAIN> picked;
707 for(
int j = 0; j < 2; j++ )
711 if( paths[j].SegmentCount() < 1 )
714 assert( dirCount <
int(
sizeof( dirs ) /
sizeof( dirs[0] ) ) );
716 dirs[dirCount] =
DIRECTION_45( paths[j].CSegment( 0 ) );
722 for(
int j = 0; j < dirCount; j++ )
725 if( endingDir == aPreferredEndingDirection )
735 for(
int j = 0; j < dirCount; j++ )
737 if( dirs[j] == d_start )
748 for(
int j = 0; j < dirCount; j++ )
750 if( dirs[j].IsObtuse( d_prev ) )
764 path.Append( *picked );
779 int width =
m_line.Width();
786 else if( aIndex ==
m_line.SegmentCount() )
793 if(
m_line.IsPtOnArc(
static_cast<size_t>( aIndex ) + 1 ) )
794 m_line.Insert( aIndex + 1,
m_line.CPoint( aIndex + 1 ) );
800 path.Append( path_rev );
804 path.SetWidth( width );
811 ssize_t idx =
static_cast<ssize_t
>( aIndex );
812 ssize_t numpts =
static_cast<ssize_t
>(
m_line.PointCount() );
815 if(
m_line.IsPtOnArc( idx ) )
817 if( idx == 0 || ( idx > 0 && !
m_line.IsPtOnArc( idx - 1 ) ) )
821 else if( ( idx == numpts - 1 ) || ( idx < numpts - 1 && !
m_line.IsArcSegment( idx ) ) )
828 wxASSERT_MSG(
false, wxT(
"Attempt to dragCornerFree in the middle of an arc!" ) );
832 m_line.SetPoint( idx, aP );
838 wxCHECK_RET( aIndex >= 0, wxT(
"Negative index passed to LINE::DragCorner" ) );
865 if( aIndex < 0 || aIndex >=
m_line.PointCount() )
868 ssize_t arcIdx =
m_line.ArcIndex( aIndex );
876 for(
int i = 0; i <
m_line.PointCount(); i++ )
878 if(
m_line.ArcIndex( i ) == arcIdx )
887 if( firstArcPt < 0 || lastArcPt < 0 )
893 auto tangentLineAtArcEndpoint = [&](
const VECTOR2I& aEndpoint ) ->
SEG
898 return SEG( aEndpoint - perp, aEndpoint + perp );
901 auto isCollinearTo = [&](
const SEG& aA,
const SEG& aB,
double aMaxDeviationDeg ) ->
bool
908 if( magA <= 0 || magB <= 0 )
911 double crossMag =
std::abs( dirA.
x * dirB.
y - dirA.
y * dirB.
x );
912 double sinAngle = crossMag / ( magA * magB );
913 double angleDeg = std::asin( std::clamp( sinAngle, 0.0, 1.0 ) ) * 180.0 /
M_PI;
915 return angleDeg <= aMaxDeviationDeg;
919 SEG arcLineStart = tangentLineAtArcEndpoint( oldArc.
GetP0() );
920 SEG arcLineEnd = tangentLineAtArcEndpoint( oldArc.
GetP1() );
922 bool useChainStart =
false;
923 bool useChainEnd =
false;
927 SEG candidate(
m_line.CPoint( firstArcPt - 1 ),
m_line.CPoint( firstArcPt ) );
929 if( isCollinearTo( candidate, arcLineStart, maxDeviation ) )
930 useChainStart =
true;
933 if( lastArcPt <
m_line.PointCount() - 1 )
935 SEG candidate(
m_line.CPoint( lastArcPt ),
m_line.CPoint( lastArcPt + 1 ) );
937 if( isCollinearTo( candidate, arcLineEnd, maxDeviation ) )
943 SEG tanStartSeg, tanEndSeg;
947 tanStartSeg =
SEG(
m_line.CPoint( firstArcPt - 1 ),
m_line.CPoint( firstArcPt ) );
951 if( !arcOwnTanIntersect )
954 tanStartSeg =
SEG( *arcOwnTanIntersect, oldArc.
GetP0() );
959 tanEndSeg =
SEG(
m_line.CPoint( lastArcPt ),
m_line.CPoint( lastArcPt + 1 ) );
963 if( !arcOwnTanIntersect )
966 tanEndSeg =
SEG( *arcOwnTanIntersect, oldArc.
GetP1() );
976 SEG tanStartFromIntersect =
SEG( *tanIntersect, oldArc.
GetP0() );
977 SEG tanEndFromIntersect =
SEG( *tanIntersect, oldArc.
GetP1() );
981 return ( aA - *tanIntersect ).EuclideanNorm() > ( aB - *tanIntersect ).EuclideanNorm() ? aA : aB;
984 VECTOR2I tanStartFar = furthestFromIntersect( tanStartSeg.
A, tanStartSeg.
B );
985 VECTOR2I tanEndFar = furthestFromIntersect( tanEndSeg.
A, tanEndSeg.
B );
986 VECTOR2I tempTangentPoint = furthestFromIntersect( tanStartFar, tanEndFar ) == tanEndFar ? tanStartFar : tanEndFar;
994 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
995 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
996 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
999 int cSegTanStartSide = cSegTanStart.
Side( oldMid );
1000 int cSegTanEndSide = cSegTanEnd.
Side( oldMid );
1001 int cSegChordSide = cSegChord.
Side( oldMid );
1005 if( cSegTanStartSide != cSegTanStart.
Side(
cursor ) || cSegTanEndSide != cSegTanEnd.
Side(
cursor )
1006 || cSegChordSide != cSegChord.
Side(
cursor ) )
1012 if( ( candidate -
cursor ).SquaredEuclideanNorm() < ( best -
cursor ).SquaredEuclideanNorm() )
1038 int prefixCutoff = useChainStart ? ( firstArcPt - 1 ) : firstArcPt;
1039 int suffixCutoff = useChainEnd ? ( lastArcPt + 1 ) : lastArcPt;
1041 if( ( newEnd - newStart ).EuclideanNorm() <= maxStubIU )
1046 if( prefixCutoff >= 0 )
1049 if( suffixCutoff <=
m_line.PointCount() - 1 )
1056 if( firstArcPt > 0 )
1060 if( (
anchor - newStart ).EuclideanNorm() <= maxStubIU )
1063 prefixCutoff = useChainStart ? ( firstArcPt - 2 ) : ( firstArcPt - 1 );
1067 if( lastArcPt <
m_line.PointCount() - 1 )
1071 if( (
anchor - newEnd ).EuclideanNorm() <= maxStubIU )
1074 suffixCutoff = useChainEnd ? ( lastArcPt + 2 ) : ( lastArcPt + 1 );
1079 SHAPE_ARC newArc( newStart, newMid, newEnd, width );
1084 if( prefixCutoff >= 0 )
1087 rebuilt.
Append( newArc );
1089 if( suffixCutoff <=
m_line.PointCount() - 1 )
1098 int s_start = std::max( aIndex - 2, 0 );
1099 int s_end = std::min( aIndex + 2, aPath.
SegmentCount() - 1 );
1102 int best_dist = INT_MAX;
1108 for( i = s_start; i <= s_end; i++ )
1112 for( j = s_start; j < i; j++ )
1123 int dist = ( *ip - aP ).EuclideanNorm();
1142 int snap_d[2] = { -1, -1 };
1168 int minDist = INT_MAX;
1170 for(
int i = 0; i < 2; i++ )
1172 if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <=
m_snapThreshhold )
1174 minDist = snap_d[i];
1187 wxASSERT( aIndex <
m_line.PointCount() );
1189 SEG guideA[2], guideB[2];
1207 path.Insert(
path.PointCount() - 1,
path.CLastPoint() );
1223 if( dir_prev == drag_dir )
1225 dir_prev = dir_prev.
Left();
1231 dir_prev = drag_dir.
Left();
1234 if( dir_next == drag_dir )
1236 dir_next = dir_next.
Right();
1241 dir_next = drag_dir.
Right();
1255 if( dir_prev.
Angle( drag_dir )
1262 guideA[0] = guideA[1] =
SEG( dragged.
A, dragged.
A + dir_prev.
ToVector() );
1265 if( aIndex ==
m_line.SegmentCount() - 1 )
1272 if( dir_next.
Angle( drag_dir )
1279 guideB[0] = guideB[1] =
SEG( dragged.
B, dragged.
B + dir_next.
ToVector() );
1282 SEG s_current( target, target + drag_dir.
ToVector() );
1284 int best_len = INT_MAX;
1287 for(
int i = 0; i < 2; i++ )
1289 for(
int j = 0; j < 2; j++ )
1299 SEG s1( s_prev.
A, *ip1 );
1300 SEG s2( *ip1, *ip2 );
1301 SEG s3( *ip2, s_next.
B );
1311 else if( ( ip = s3.
Intersect( s_prev ) ) )
1331 if( np.
Length() < best_len )
1334 best = std::move( np );
1339 if(
m_line.PointCount() == 1 )
1341 else if( aIndex == 0 )
1342 m_line.Replace( 0, 1, best );
1343 else if( aIndex ==
m_line.SegmentCount() - 1 )
1344 m_line.Replace( -2, -1, best );
1346 m_line.Replace( aIndex, aIndex + 1, best );
1374 m_via->SetOwner(
this );
1396 s->SetRank( aRank );
1403 int min_rank = INT_MAX;
1408 min_rank = std::min( min_rank, item->Rank() );
1415 int rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
1430 int lastLink = std::max( 0,
static_cast<int>(
m_links.size() ) - 1 );
1433 for(
int i = 0; i >= 0 && i <
m_line.PointCount(); i =
m_line.NextShape( i ) )
1436 firstLink = linkIdx;
1438 if( i < 0 || i >= aEnd - 1 || linkIdx >= lastLink )
1447 wxASSERT( lastLink >= firstLink );
1453 wxASSERT(
m_links.size() < INT_MAX );
1454 wxASSERT(
static_cast<int>(
m_links.size() ) >= ( lastLink - firstLink ) );
1463 m_links.resize( lastLink - firstLink + 1 );
1500 bool areaDefined =
false;
1503 int i_end_self = -1, i_end_other = -1;
1513 int n = std::min( np_self, np_other );
1515 for(
int i = 0; i < n; i++ )
1540 for(
int i = 0; i < n; i++ )
1547 i_end_self = np_self - 1 - i;
1548 i_end_other = np_other - 1 - i;
1556 if( i_end_self < 0 )
1557 i_end_self = np_self - 1;
1559 if( i_end_other < 0 )
1560 i_end_other = np_other - 1;
1562 for(
int i = i_start; i <= i_end_self; i++ )
1565 for(
int i = i_start; i <= i_end_other; i++ )
1580 for(
const auto seg :
m_links )
1603 if(
m_via->BelongsTo(
this ) )
1613 std::stringstream ss;
1615 ss <<
m_seg.Format(
false );
1622 for(
int i = 0; i <
m_line.SegmentCount(); i++)
1625 if( s == aSeg->
Seg() )
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)
virtual void Unmark(int aMarker=-1) const override
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 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 * > 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.
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.
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.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D