42 const std::vector<PCB_SHAPE*>& aList,
unsigned aLimit )
47 if( graphic == aShape || ( graphic->GetFlags() &
SKIP_STRUCT ) != 0 )
50 if( aPoint == graphic->GetStart() || aPoint == graphic->GetEnd() )
62 if( graphic == aShape || ( graphic->GetFlags() &
SKIP_STRUCT ) != 0 )
65 d_sq = ( pt - graphic->GetStart() ).SquaredEuclideanNorm();
67 if( d_sq < closest_dist_sq )
69 closest_dist_sq = d_sq;
70 closest_graphic = graphic;
73 d_sq = ( pt - graphic->GetEnd() ).SquaredEuclideanNorm();
75 if( d_sq < closest_dist_sq )
77 closest_dist_sq = d_sq;
78 closest_graphic = graphic;
82 return closest_graphic;
87 std::vector<std::unique_ptr<PCB_SHAPE>>& aNewShapes,
int aChainingEpsilon )
89 if( aShapeList.size() == 0 )
96 return ( aLeft - aRight ).SquaredEuclideanNorm() <=
SEG::Square( aLimit );
103 return ( aRef - aFirst ).SquaredEuclideanNorm() < ( aRef - aSecond ).SquaredEuclideanNorm();
109 return std::min( ( aRef - aFirst ).SquaredEuclideanNorm(),
110 ( aRef - aSecond ).SquaredEuclideanNorm() );
119 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>(
nullptr,
SHAPE_T::SEGMENT );
120 seg->SetStart( start );
122 seg->SetWidth( width );
123 seg->SetLayer( layer );
125 aNewShapes.emplace_back( std::move( seg ) );
130 bool success =
false;
133 SHAPE_T shape1 = aShape->GetShape();
138 SEG seg1( aShape->GetStart(), aShape->GetEnd() );
147 aPrevShape->
SetEnd( *inter );
150 aShape->SetStart( *inter );
152 aShape->SetEnd( *inter );
169 extAngle = -extAngle;
175 arcAngle += extAngle * 2;
182 std::vector<VECTOR2I> ips;
183 std::vector<VECTOR2I> onSeg;
188 if( min_distance_sq( ip, segShape->
GetStart(), segShape->
GetEnd() ) <= 0
189 && min_distance_sq( ip, arcShape->
GetStart(), arcShape->
GetEnd() ) <= 0 )
195 if( seg.
Distance( ip ) <= aChainingEpsilon )
228 segShape->
SetEnd( lineProj );
249 std::set<PCB_SHAPE*> startCandidates;
256 startCandidates.emplace( shape );
260 while( startCandidates.size() )
262 graphic = *startCandidates.begin();
272 findNext( curr_graphic, prevPt, aShapeList, aChainingEpsilon );
281 std::swap( nstart, nend );
283 if( !connectPair( curr_graphic, nextGraphic ) )
289 nend = nextGraphic->
GetEnd();
292 std::swap( nstart, nend );
295 curr_graphic = nextGraphic;
297 startCandidates.erase( curr_graphic );
305 PCB_SHAPE* grAtStart =
findNext( graphic, ptStart, aShapeList, aChainingEpsilon );
307 bool beginFromEndPt =
true;
310 if( grAtEnd && grAtStart )
315 min_distance_sq( ptStart, grAtStart->
GetStart(), grAtStart->
GetEnd() );
317 beginFromEndPt = dAtEnd <= dAtStart;
320 beginFromEndPt =
true;
322 beginFromEndPt =
false;
327 walkFrom( graphic, graphic->
GetEnd() );
328 walkFrom( graphic, graphic->
GetStart() );
332 walkFrom( graphic, graphic->
GetStart() );
333 walkFrom( graphic, graphic->
GetEnd() );
336 startCandidates.erase( graphic );
Represent basic circle geometry with utility geometry functions.
VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute the point on the circumference of the circle that is the closest to aP.
void SetFlags(EDA_ITEM_FLAGS aMask)
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SetEnd(const VECTOR2I &aEnd)
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
VECTOR2I GetArcMid() const
int GetWidth() const override
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
ecoord SquaredDistance(const SEG &aSeg) const
VECTOR2I::extended_type ecoord
bool Intersects(const SEG &aSeg) const
static SEG::ecoord Square(int a)
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
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.
EDA_ANGLE GetCentralAngle() const
const VECTOR2I & GetArcMid() const
const VECTOR2I & GetP1() const
int IntersectLine(const SEG &aSeg, std::vector< VECTOR2I > *aIpsBuffer) const
Find intersection points between this arc and aSeg, treating aSeg as an infinite line.
const VECTOR2I & GetP0() const
const VECTOR2I & GetCenter() const
static bool close_enough(VECTOR2I aLeft, VECTOR2I aRight, unsigned aLimit)
Local and tunable method of qualifying the proximity of two points.
static bool closer_to_first(VECTOR2I aRef, VECTOR2I aFirst, VECTOR2I aSecond)
Local method which qualifies whether the start or end point of a segment is closest to a point.
static constexpr EDA_ANGLE ANGLE_45
static constexpr EDA_ANGLE ANGLE_360
#define SKIP_STRUCT
flag indicating that the structure should be ignored
@ ARC
use RECTANGLE instead of RECT to avoid collision in a Windows header
static PCB_SHAPE * findNext(PCB_SHAPE *aShape, const VECTOR2I &aPoint, const std::vector< PCB_SHAPE * > &aList, unsigned aLimit)
Searches for a PCB_SHAPE matching a given end point or start point in a list.
void ConnectBoardShapes(std::vector< PCB_SHAPE * > &aShapeList, std::vector< std::unique_ptr< PCB_SHAPE > > &aNewShapes, int aChainingEpsilon)
Connects shapes to each other, making continious contours (adjacent shapes will have a common vertex)...
PCB_LAYER_ID
A quick note on layer IDs:
static bool addSegment(VRML_LAYER &model, IDF_SEGMENT *seg, int icont, int iseg)
std::optional< VECTOR2I > OPT_VECTOR2I
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.