39 m_line( aOther.m_line ),
40 m_width( aOther.m_width ),
41 m_snapThreshhold( aOther.m_snapThreshhold )
103 s->Unmark( aMarker );
115 marker |= s->Marker();
166 const auto pFirst = line.
CPoint(0);
167 const auto pLast = line.
CPoint(-1);
174 if( inFirst || inLast )
179 enum VERTEX_TYPE { INSIDE = 0,
OUTSIDE, ON_EDGE };
192 std::vector<VERTEX*> neighbours;
198 bool visited =
false;
207 std::vector<VERTEX> vts;
211 for( VERTEX& v : vts )
221 for(
int i = 0; i < pnew.PointCount(); i++ )
238 if( pnew.Find( ip.p ) < 0 )
243 if( hnew.
Find( ip.p ) < 0 )
254 vts.reserve( 2 * ( hnew.
PointCount() + pnew.PointCount() ) );
257 for(
int i = 0; i < pnew.PointCount(); i++ )
268 v.type = inside && !onEdge ? INSIDE : onEdge ? ON_EDGE :
OUTSIDE;
273 for(
int i = 0; i < pnew.PointCount() - 1; i++ )
275 vts[i].neighbours.push_back( &vts[ i+1 ] );
281 auto hp = hnew.
CPoint( i );
309 vc->neighbours.push_back(vnext);
316 int iterLimit = 1000;
319 while ( v->indexp != (pnew.PointCount() - 1) )
339 VERTEX* v_next =
nullptr;
346 for(
auto vn : v->neighbours )
348 if( (vn->indexp > v->indexp) && vn->type != INSIDE )
360 else if (v->type == ON_EDGE)
363 for( VERTEX* vn: v->neighbours)
366 if( vn->type == ON_EDGE && (vn->indexp == (v->indexp + 1) ) && ( (vn->indexh == (v->indexh + 1) ) % hnew.
PointCount() ) )
376 for( VERTEX* vn: v->neighbours)
390 for( VERTEX* vn: v->neighbours)
392 if ( v->type == ON_EDGE )
394 if( vn->indexh == ( (v->indexh + 1) % hnew.
PointCount() ) )
439 double angle = 180.0 / M_PI *
440 atan2( (
double) s.
B.
y - (
double) s.
A.
y,
441 (
double) s.
B.
x - (
double) s.
A.
x );
446 double angle_a = fabs( fmod(
angle, 45.0 ) );
448 if( angle_a > 1.0 && angle_a < 44.0 )
458 const int IterationLimit = 5;
462 for( i = 0; i < IterationLimit; i++ )
469 int p = l.
Line().
Split( obs->m_ipFirst );
475 if( i == IterationLimit )
514 for(
int j = 0; j < 2; j++ )
516 paths[j] = d_start.BuildInitialTrace( p_start, aP, j );
518 if( paths[j].SegmentCount() < 1 )
521 assert( dirCount <
int(
sizeof( dirs ) /
sizeof( dirs[0] ) ) );
523 dirs[dirCount] =
DIRECTION_45( paths[j].CSegment( 0 ) );
527 for(
int j = 0; j < dirCount; j++ )
529 if( dirs[j] == d_start )
539 for(
int j = 0; j < dirCount; j++ )
541 if( dirs[j].IsObtuse( d_prev ) )
621 int s_start = std::max( aIndex - 2, 0 );
622 int s_end = std::min( aIndex + 2, aPath.
SegmentCount() - 1 );
625 int best_dist = INT_MAX;
631 for( i = s_start; i <= s_end; i++ )
635 for( j = s_start; j < i; j++ )
665 int snap_d[2] = { -1, -1 };
691 int minDist = INT_MAX;
693 for(
int i = 0; i < 2; i++ )
695 if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <=
m_snapThreshhold )
710 SEG guideA[2], guideB[2];
735 if( dir_prev == drag_dir )
737 dir_prev = dir_prev.
Left();
742 if( dir_next == drag_dir )
744 dir_next = dir_next.
Right();
748 s_prev = path.
CSegment( index - 1 );
749 s_next = path.
CSegment( index + 1 );
759 if( dir_prev.
Angle( drag_dir )
766 guideA[0] = guideA[1] =
SEG( dragged.
A, dragged.
A + dir_prev.
ToVector() );
776 if( dir_next.
Angle( drag_dir )
783 guideB[0] = guideB[1] =
SEG( dragged.
B, dragged.
B + dir_next.
ToVector() );
786 SEG s_current( target, target + drag_dir.
ToVector() );
788 int best_len = INT_MAX;
791 for(
int i = 0; i < 2; i++ )
793 for(
int j = 0; j < 2; j++ )
795 OPT_VECTOR2I ip1 = s_current.IntersectLines( guideA[i] );
796 OPT_VECTOR2I ip2 = s_current.IntersectLines( guideB[j] );
803 SEG s1( s_prev.
A, *ip1 );
804 SEG s2( *ip1, *ip2 );
805 SEG s3( *ip2, s_next.
B );
815 else if( ( ip = s3.
Intersect( s_prev ) ) )
835 if( np.
Length() < best_len )
845 else if( aIndex == 0 )
895 int min_rank = INT_MAX;
900 min_rank = std::min( min_rank, s->Rank() );
906 int rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
921 int lastLink = std::max( 0, static_cast<int>(
m_links.size() ) - 1 );
926 int numPoints = static_cast<int>( shapes.size() );
936 if( i > aStart && ( shapes[i - 1] >= 0 ) && ( shapes[i - 1] != shapes[i] ) )
942 while( i < numPoints && shapes[i] == arcIdx )
949 if( i >= aEnd - 1 || linkIdx >= lastLink )
958 wxASSERT( lastLink >= firstLink );
964 wxASSERT(
m_links.size() < INT_MAX );
965 wxASSERT( static_cast<int>(
m_links.size() ) >= ( lastLink - firstLink ) );
974 m_links.resize( lastLink - firstLink + 1 );
1011 bool areaDefined =
false;
1014 int i_end_self = -1, i_end_other = -1;
1024 int n = std::min( np_self, np_other );
1026 for(
int i = 0; i < n; i++ )
1028 const VECTOR2I p1 =
self.CPoint( i );
1035 SEG s =
self.CSegment( i );
1051 for(
int i = 0; i < n; i++ )
1053 const VECTOR2I p1 =
self.CPoint( np_self - 1 - i );
1058 i_end_self = np_self - 1 - i;
1059 i_end_other = np_other - 1 - i;
1067 if( i_end_self < 0 )
1068 i_end_self = np_self - 1;
1070 if( i_end_other < 0 )
1071 i_end_other = np_other - 1;
1073 for(
int i = i_start; i <= i_end_self; i++ )
1076 for(
int i = i_start; i <= i_end_other; i++ )
1091 for(
const auto seg :
m_links )
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
int Length() const
Return the length (this).
int Find(const VECTOR2I &aP) const
Function Find()
const SHAPE_LINE_CHAIN & CLine() const
OPT_OBSTACLE NearestObstacle(const LINE *aLine, int aKindMask=ITEM::ANY_T, const std::set< ITEM * > *aRestrictedSet=NULL)
Follow the line in search of an obstacle that is nearest to the starting to the line's starting point...
long long int Length() const
Function Length()
int Split(const VECTOR2I &aP)
Function Split()
bool isArc(size_t aSegment) const
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Function Intersect()
std::vector< INTERSECTION > INTERSECTIONS
Keep the router "world" - i.e.
OPT_BOX2I ChangedArea(const LINE *aOther) const
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).
LINE()
Makes an empty line.
void DragSegment(const VECTOR2I &aP, int aIndex, bool aFreeAngle=false)
LINE & operator=(const LINE &aOther)
void copyLinks(const LINK_HOLDER *aParent)
< Copy m_links from the line aParent.
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
void SetPoint(int aIndex, const VECTOR2I &aPos)
Accessor Function to move a point to a specific location.
VECTOR2I snapToNeighbourSegments(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
bool Is45Degree() const
Print out all linked segments.
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
int Rank() const override
const VECTOR2I ToVector() const
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Function Slice()
VECTOR2I p
point of intersection between our and their.
SEGMENT * Clone() const override
Return a deep copy of the item.
const DIRECTION_45 Left() const
Return the direction on the left side of this (i.e.
bool PointOnEdge(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of the line chain.
void AppendVia(const VIA &aVia)
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
static std::pair< bool, SHAPE_POLY_SET::VERTEX_INDEX > findVertex(SHAPE_POLY_SET &aPolySet, const EDIT_POINT &aPoint)
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...
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
const DIRECTION_45 Right() const
Return the direction on the right side of this (i.e.
const SHAPE_LINE_CHAIN Reverse() const
Function Reverse()
int PointCount() const
Function PointCount()
const VECTOR2I & Pos() const
const SHAPE_LINE_CHAIN Hull(int aClearance, int aWalkaroundThickness, int aLayer=-1) const override
const SHAPE_LINE_CHAIN SegmentHull(const SHAPE_SEGMENT &aSeg, int aClearance, int aWalkaroundThickness)
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
ITEM * m_blockingObstacle
For mark obstacle mode.
SHAPE_LINE_CHAIN dragCornerInternal(const SHAPE_LINE_CHAIN &aOrigin, const VECTOR2I &aP)
const VECTOR2I & CPoint(int aIdx) const
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
void Insert(size_t aVertex, const VECTOR2I &aP)
const std::vector< ssize_t > & CShapes() const
AngleType Angle(const DIRECTION_45 &aOther) const
Return the type of angle between directions (this) and aOther.
const VECTOR2I & CPoint(int aIndex) const
Function Point()
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
OPT< VECTOR2I > OPT_VECTOR2I
Represent route directions & corner angles in a 45-degree metric.
bool IsLinked() const
Check if the segment aLink is a part of the line.
void ClipVertexRange(int aStart, int aEnd)
Return the number of corners of angles specified by mask aAngles.
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const
Check if point aP lies inside a polygon (any type) defined by the line chain.
const LINE ClipToNearestObstacle(NODE *aNode) const
Clip the line to a given range of vertices.
const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false, bool aFillet=false) const
Build a 2-segment line chain between points aP0 and aP1 and following 45-degree routing regime.
Text appears outside the dimension line (default)
bool m_hasVia
Optional via at the end point.
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect.
void SetRank(int aRank) override
int SegmentCount() const
Function SegmentCount()
void dragCorner45(const VECTOR2I &aP, int aIndex)
SHAPE_LINE_CHAIN & Line()
void DragCorner(const VECTOR2I &aP, int aIndex, bool aFreeAngle=false)
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
virtual int Marker() const override
const SEG CSegment(int aIndex) const
Function CSegment()
int m_snapThreshhold
Width to smooth out jagged segments.
static void extendBox(BOX2I &aBox, bool &aDefined, const VECTOR2I &aP)
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
int Width() const
Return true if the line is geometrically identical as line aOther.
void Clear()
Function Clear() Removes all points from the line chain.
OPT< OBSTACLE > OPT_OBSTACLE
void dragSegment45(const VECTOR2I &aP, int aIndex)
void Replace(int aStartIndex, int aEndIndex, const VECTOR2I &aP)
Function Replace()
bool CompareGeometry(const LINE &aOther)
Reverse the point/vertex order.
Push and Shove diff pair dimensions (gap) settings dialog.
void dragCornerFree(const VECTOR2I &aP, int aIndex)
virtual LINE * Clone() const override
Return a deep copy of the item.
virtual void Unmark(int aMarker=-1) const override
bool CompareGeometry(const SHAPE_LINE_CHAIN &aOther) const
bool HasLockedSegments() const
int CountCorners(int aAngles) const
virtual void Mark(int aMarker) const override
bool Contains(const SEG &aSeg) const
VECTOR2I snapDraggedCorner(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const