KiCad PCB EDA Suite
SHAPE_LINE_CHAIN Class Reference

SHAPE_LINE_CHAIN. More...

#include <shape_line_chain.h>

Inheritance diagram for SHAPE_LINE_CHAIN:
SHAPE_LINE_CHAIN_BASE SHAPE SHAPE_BASE

Classes

struct  compareOriginDistance
 
struct  INTERSECTION
 Struct INTERSECTION. More...
 
class  POINT_INSIDE_TRACKER
 Class POINT_INSIDE_TRACKER. More...
 

Public Types

typedef std::vector< INTERSECTIONINTERSECTIONS
 

Public Member Functions

 SHAPE_LINE_CHAIN ()
 Constructor Initializes an empty line chain. More...
 
 SHAPE_LINE_CHAIN (const SHAPE_LINE_CHAIN &aShape)
 Copy Constructor. More...
 
 SHAPE_LINE_CHAIN (const std::vector< int > &aV)
 
 SHAPE_LINE_CHAIN (const std::vector< wxPoint > &aV, bool aClosed=false)
 
 SHAPE_LINE_CHAIN (const std::vector< VECTOR2I > &aV, bool aClosed=false)
 
 SHAPE_LINE_CHAIN (const SHAPE_ARC &aArc, bool aClosed=false)
 
 SHAPE_LINE_CHAIN (const ClipperLib::Path &aPath)
 
virtual ~SHAPE_LINE_CHAIN ()
 
SHAPE_LINE_CHAINoperator= (const SHAPE_LINE_CHAIN &)=default
 
SHAPEClone () const override
 Return a dynamically allocated copy of the shape. More...
 
void Clear ()
 Function Clear() Removes all points from the line chain. More...
 
void SetClosed (bool aClosed)
 Function SetClosed() More...
 
bool IsClosed () const override
 Function IsClosed() More...
 
void SetWidth (int aWidth)
 Sets the width of all segments in the chain. More...
 
int Width () const
 Gets the current width of the segments in the chain. More...
 
int SegmentCount () const
 Function SegmentCount() More...
 
int ShapeCount () const
 Returns the number of shapes (line segments or arcs) in this line chain. More...
 
int PointCount () const
 Function PointCount() More...
 
SEG Segment (int aIndex)
 Function Segment() More...
 
const SEG CSegment (int aIndex) const
 Function CSegment() More...
 
int NextShape (int aPointIndex, bool aForwards=true) const
 Returns the vertex index of the next shape in the chain, or -1 if aPoint is in the last shape If aPoint is the start of a segment, this will be ( aPoint + 1 ). More...
 
int PrevShape (int aPointIndex) const
 
void SetPoint (int aIndex, const VECTOR2I &aPos)
 Accessor Function to move a point to a specific location. More...
 
const VECTOR2ICPoint (int aIndex) const
 Function Point() More...
 
const std::vector< VECTOR2I > & CPoints () const
 
const VECTOR2ICLastPoint () const
 Returns the last point in the line chain. More...
 
const std::vector< SHAPE_ARC > & CArcs () const
 
const std::vector< ssize_t > & CShapes () const
 
const BOX2I BBox (int aClearance=0) const override
 Compute a bounding box of the shape, with a margin of aClearance a collision. More...
 
void GenerateBBoxCache () const
 
const BOX2I BBoxFromCache () const
 
int Distance (const VECTOR2I &aP, bool aOutlineOnly=false) const
 Function Distance() More...
 
const SHAPE_LINE_CHAIN Reverse () const
 Function Reverse() More...
 
long long int Length () const
 Function Length() More...
 
void Append (int aX, int aY, bool aAllowDuplication=false)
 Function Append() More...
 
void Append (const VECTOR2I &aP, bool aAllowDuplication=false)
 Function Append() More...
 
void Append (const SHAPE_LINE_CHAIN &aOtherLine)
 Function Append() More...
 
void Append (const SHAPE_ARC &aArc)
 
void Insert (size_t aVertex, const VECTOR2I &aP)
 
void Insert (size_t aVertex, const SHAPE_ARC &aArc)
 
void Replace (int aStartIndex, int aEndIndex, const VECTOR2I &aP)
 Function Replace() More...
 
void Replace (int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN &aLine)
 Function Replace() More...
 
void Remove (int aStartIndex, int aEndIndex)
 Function Remove() More...
 
void Remove (int aIndex)
 Function Remove() removes the aIndex-th point from the line chain. More...
 
void RemoveShape (int aPointIndex)
 Removes the shape at the given index from the line chain. More...
 
int Split (const VECTOR2I &aP)
 Function Split() More...
 
int Find (const VECTOR2I &aP) const
 Function Find() More...
 
int FindSegment (const VECTOR2I &aP) const
 Function FindSegment() More...
 
const SHAPE_LINE_CHAIN Slice (int aStartIndex, int aEndIndex=-1) const
 Function Slice() More...
 
bool Intersects (const SHAPE_LINE_CHAIN &aChain) const
 
int Intersect (const SEG &aSeg, INTERSECTIONS &aIp) const
 Function Intersect() More...
 
int Intersect (const SHAPE_LINE_CHAIN &aChain, INTERSECTIONS &aIp) const
 Function Intersect() More...
 
int PathLength (const VECTOR2I &aP) const
 Function PathLength() More...
 
bool CheckClearance (const VECTOR2I &aP, const int aDist) const
 Function CheckClearance() More...
 
const OPT< INTERSECTIONSelfIntersecting () const
 Function SelfIntersecting() More...
 
SHAPE_LINE_CHAINSimplify (bool aRemoveColinear=true)
 Function Simplify() More...
 
void convertArc (ssize_t aArcIndex)
 Converts an arc to only a point chain by removing the arc and references. More...
 
ClipperLib::Path convertToClipper (bool aRequiredOrientation) const
 Creates a new Clipper path from the SHAPE_LINE_CHAIN in a given orientation. More...
 
int NearestSegment (const VECTOR2I &aP) const
 Find the segment nearest the given point. More...
 
const VECTOR2I NearestPoint (const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
 Finds a point on the line chain that is closest to point aP. More...
 
const VECTOR2I NearestPoint (const SEG &aSeg, int &dist) const
 Finds a point on the line chain that is closest to the line defined by the points of segment aSeg, also returns the distance. More...
 
const std::string Format () const override
 
bool Parse (std::stringstream &aStream) override
 
bool operator!= (const SHAPE_LINE_CHAIN &aRhs) const
 
bool CompareGeometry (const SHAPE_LINE_CHAIN &aOther) const
 
void Move (const VECTOR2I &aVector) override
 
void Mirror (bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
 Mirrors the line points about y or x (or both) More...
 
void Mirror (const SEG &axis)
 Mirrors the line points using an given axis. More...
 
void Rotate (double aAngle, const VECTOR2I &aCenter=VECTOR2I(0, 0)) override
 Function Rotate rotates all vertices by a given angle. More...
 
bool IsSolid () const override
 
const VECTOR2I PointAlong (int aPathLength) const
 
double Area () const
 
size_t ArcCount () const
 
ssize_t ArcIndex (size_t aSegment) const
 
const SHAPE_ARCArc (size_t aArc) const
 
bool isArc (size_t aSegment) const
 
virtual const VECTOR2I GetPoint (int aIndex) const override
 
virtual const SEG GetSegment (int aIndex) const override
 
virtual size_t GetPointCount () const override
 
virtual size_t GetSegmentCount () const override
 
virtual bool Collide (const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
 Check if point aP lies closer to us than aClearance. More...
 
virtual bool Collide (const SEG &aSeg, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
 Check if segment aSeg lies closer to us than aClearance. More...
 
virtual bool Collide (const SHAPE *aShape, int aClearance, VECTOR2I *aMTV) const
 Check if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating a collision. More...
 
virtual bool Collide (const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
 
SEG::ecoord SquaredDistance (const VECTOR2I &aP, bool aOutlineOnly=false) const
 
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. More...
 
bool PointOnEdge (const VECTOR2I &aP, int aAccuracy=0) const
 Check if point aP lies on an edge or vertex of the line chain. More...
 
int EdgeContainingPoint (const VECTOR2I &aP, int aAccuracy=0) const
 Check if point aP lies on an edge or vertex of the line chain. More...
 
bool IsNull () const
 Return true if the shape is a null shape. More...
 
virtual VECTOR2I Centre () const
 Compute a center-of-mass of the shape. More...
 
FACETNewFacet ()
 
SGNODECalcShape (SGNODE *aParent, SGNODE *aColor, WRL1_ORDER aVertexOrder, float aCreaseLimit=0.74317, bool isVRML2=false)
 
SHAPE_TYPE Type () const
 Return the type of the shape. More...
 
virtual bool HasIndexableSubshapes () const
 
virtual size_t GetIndexableSubshapeCount () const
 
virtual void GetIndexableSubshapes (std::vector< SHAPE * > &aSubshapes)
 

Static Public Attributes

static const int MIN_PRECISION_IU = 4
 This is the minimum precision for all the points in a shape. More...
 

Protected Types

typedef VECTOR2I::extended_type ecoord
 

Protected Attributes

SHAPE_TYPE m_type
 < type of our shape More...
 

Private Types

typedef std::vector< VECTOR2I >::iterator point_iter
 
typedef std::vector< VECTOR2I >::const_iterator point_citer
 

Private Attributes

std::vector< VECTOR2Im_points
 array of vertices More...
 
std::vector< ssize_t > m_shapes
 Array of indices that refer to the index of the shape if the point is part of a larger shape, e.g. More...
 
std::vector< SHAPE_ARCm_arcs
 
bool m_closed
 is the line chain closed? More...
 
int m_width
 Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to account for where we need a width and where not Alternatively, we could split the class into a LINE_CHAIN (no width) and SHAPE_LINE_CHAIN that derives from SHAPE as well that does have a width. More...
 
BOX2I m_bbox
 cached bounding box More...
 

Static Private Attributes

static constexpr ssize_t SHAPE_IS_PT = -1
 

Detailed Description

SHAPE_LINE_CHAIN.

Represents a polyline (an zero-thickness chain of connected line segments). I purposedly didn't name it "polyline" to avoid confusion with the existing CPolyLine in pcbnew.

SHAPE_LINE_CHAIN class shall not be used for polygons!

Definition at line 46 of file shape_line_chain.h.

Member Typedef Documentation

◆ ecoord

typedef VECTOR2I::extended_type SHAPE::ecoord
protectedinherited

Definition at line 236 of file shape.h.

◆ INTERSECTIONS

Definition at line 95 of file shape_line_chain.h.

◆ point_citer

typedef std::vector<VECTOR2I>::const_iterator SHAPE_LINE_CHAIN::point_citer
private

Definition at line 50 of file shape_line_chain.h.

◆ point_iter

typedef std::vector<VECTOR2I>::iterator SHAPE_LINE_CHAIN::point_iter
private

Definition at line 49 of file shape_line_chain.h.

Constructor & Destructor Documentation

◆ SHAPE_LINE_CHAIN() [1/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( )
inline

Constructor Initializes an empty line chain.

Definition at line 102 of file shape_line_chain.h.

103  {}
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
bool m_closed
is the line chain closed?
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45

Referenced by Clone().

◆ SHAPE_LINE_CHAIN() [2/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const SHAPE_LINE_CHAIN aShape)
inline

Copy Constructor.

Definition at line 109 of file shape_line_chain.h.

111  m_points( aShape.m_points ),
112  m_shapes( aShape.m_shapes ),
113  m_arcs( aShape.m_arcs ),
114  m_closed( aShape.m_closed ),
115  m_width( aShape.m_width ),
116  m_bbox( aShape.m_bbox )
117  {}
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
BOX2I m_bbox
cached bounding box
std::vector< SHAPE_ARC > m_arcs
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45

◆ SHAPE_LINE_CHAIN() [3/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const std::vector< int > &  aV)

Definition at line 39 of file shape_line_chain.cpp.

41 {
42  for(size_t i = 0; i < aV.size(); i+= 2 )
43  {
44  Append( aV[i], aV[i+1] );
45  }
46 }
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
bool m_closed
is the line chain closed?
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45

References Append().

◆ SHAPE_LINE_CHAIN() [4/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const std::vector< wxPoint > &  aV,
bool  aClosed = false 
)
inline

Definition at line 121 of file shape_line_chain.h.

122  : SHAPE_LINE_CHAIN_BASE( SH_LINE_CHAIN ), m_closed( aClosed ), m_width( 0 )
123  {
124  m_points.reserve( aV.size() );
125 
126  for( auto pt : aV )
127  m_points.emplace_back( pt.x, pt.y );
128 
129  m_shapes = std::vector<ssize_t>( aV.size(), ssize_t( SHAPE_IS_PT ) );
130  }
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45

References m_points, m_shapes, and SHAPE_IS_PT.

◆ SHAPE_LINE_CHAIN() [5/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const std::vector< VECTOR2I > &  aV,
bool  aClosed = false 
)
inline

Definition at line 132 of file shape_line_chain.h.

133  : SHAPE_LINE_CHAIN_BASE( SH_LINE_CHAIN ), m_closed( aClosed ), m_width( 0 )
134  {
135  m_points = aV;
136  m_shapes = std::vector<ssize_t>( aV.size(), ssize_t( SHAPE_IS_PT ) );
137  }
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45

References m_points, m_shapes, and SHAPE_IS_PT.

◆ SHAPE_LINE_CHAIN() [6/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const SHAPE_ARC aArc,
bool  aClosed = false 
)
inline

Definition at line 139 of file shape_line_chain.h.

141  m_closed( aClosed ),
142  m_width( 0 )
143  {
145  m_arcs.emplace_back( aArc );
146  m_shapes = std::vector<ssize_t>( m_points.size(), 0 );
147  }
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
std::vector< SHAPE_ARC > m_arcs
bool m_closed
is the line chain closed?
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=0.005 *PCB_IU_PER_MM) const
Constructs a SHAPE_LINE_CHAIN of segments from a given arc.
Definition: shape_arc.cpp:408
const std::vector< VECTOR2I > & CPoints() const
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45

References SHAPE_ARC::ConvertToPolyline(), CPoints(), m_arcs, m_points, and m_shapes.

◆ SHAPE_LINE_CHAIN() [7/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const ClipperLib::Path &  aPath)
inline

Definition at line 149 of file shape_line_chain.h.

149  :
151  m_closed( true ),
152  m_width( 0 )
153  {
154  m_points.reserve( aPath.size() );
155  m_shapes = std::vector<ssize_t>( aPath.size(), ssize_t( SHAPE_IS_PT ) );
156 
157  for( const auto& point : aPath )
158  m_points.emplace_back( point.X, point.Y );
159  }
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45

References m_points, m_shapes, and SHAPE_IS_PT.

◆ ~SHAPE_LINE_CHAIN()

virtual SHAPE_LINE_CHAIN::~SHAPE_LINE_CHAIN ( )
inlinevirtual

Definition at line 161 of file shape_line_chain.h.

162  {}

Member Function Documentation

◆ Append() [1/4]

void SHAPE_LINE_CHAIN::Append ( int  aX,
int  aY,
bool  aAllowDuplication = false 
)
inline

Function Append()

Appends a new point at the end of the line chain.

Parameters
aXis X coordinate of the new point
aYis Y coordinate of the new point
aAllowDuplication= true to append the new point even it is the same as the last entered point false (default) to skip it if it is the same as the last entered point

Definition at line 431 of file shape_line_chain.h.

432  {
433  VECTOR2I v( aX, aY );
434  Append( v, aAllowDuplication );
435  }
Define a general 2D-vector/point.
Definition: vector2d.h:61
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()

Referenced by PNS_PCBNEW_DEBUG_DECORATOR::AddBox(), ZONE_FILLER::addHatchFillTypeOnZone(), POLYGON_GEOM_MANAGER::AddPoint(), PNS_TEST_DEBUG_DECORATOR::AddPoint(), PNS_PCBNEW_DEBUG_DECORATOR::AddPoint(), ZONE::AddPolygon(), PNS_PCBNEW_DEBUG_DECORATOR::AddSegment(), PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), SHAPE_SIMPLE::Append(), PNS::DIFF_PAIR::Append(), PNS::ArcHull(), PNS::NODE::AssembleLine(), buildBoardBoundingBoxPoly(), PAD::BuildEffectiveShapes(), BuildFootprintPolygonOutlines(), PNS::DIFF_PAIR::BuildInitial(), DIRECTION_45::BuildInitialTrace(), ZONE_FILLER::buildThermalSpokes(), SHAPE_POLY_SET::chamferFilletPolygon(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS::OPTIMIZER::circleBreakouts(), PNS::clipToLoopStart(), KI_TEST::CommonTestData::CommonTestData(), PCB_GRID_HELPER::computeAnchors(), SCH_SHEET_PIN::ConstrainOnEdge(), SHAPE_ARC::ConvertToPolyline(), PNS::ConvexHull(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), PNS::OPTIMIZER::customBreakouts(), PNS::MEANDER_PLACER::doMove(), PNS::LINE::dragSegment45(), PNS::MEANDER_SHAPE::forward(), SHAPE_POLY_SET::fractureSingle(), PNS::MEANDER_SHAPE::genMeanderShape(), CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromDrawsegments(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), HelperShapeLineChainFromAltiumVertices(), LIB_POLYLINE::HitTest(), PNS::ROUTER::isStartingPointRoutable(), IteratorFixture::IteratorFixture(), PNS::TOPOLOGY::LeadingRatLine(), CADSTAR_SCH_ARCHIVE_LOADER::loadBusses(), FABMASTER::loadFootprints(), CADSTAR_SCH_ARCHIVE_LOADER::loadNets(), FABMASTER::loadShapePolySet(), FABMASTER::loadZone(), PNS::MEANDER_SHAPE::MakeCorner(), PNS::MEANDER_SHAPE::makeMiterShape(), CONVERT_TOOL::makePolysFromRects(), CONVERT_TOOL::makePolysFromSegs(), GEOM_TEST::MakeSquarePolyLine(), PNS::LINE_PLACER::mergeHead(), PNS::OPTIMIZER::mergeObtuse(), PNS::MEANDER_SHAPE::miter(), PNS::DP_MEANDER_PLACER::Move(), PNS::OctagonalHull(), ZONE_CREATE_HELPER::OnComplete(), PNS::LINE_PLACER::optimizeTailHeadTransition(), SHAPE_RECT::Outline(), SHAPE_POLY_SET::Parse(), ALTIUM_PCB::ParseRegions6Data(), partitionPolyIntoRegularCellGrid(), BRDITEMS_PLOTTER::PlotFootprintGraphicItem(), BRDITEMS_PLOTTER::PlotPcbShape(), CONVERT_TOOL::PolyToLines(), PNS::LINE_PLACER::rhShoveOnly(), PNS::WALKAROUND::Route(), PNS::SegmentHull(), SHAPE_LINE_CHAIN(), MARKER_BASE::ShapeToPolygon(), PNS::WALKAROUND::singleStep(), Slice(), PNS::OPTIMIZER::smartPadsSingle(), PNS::MEANDER_SHAPE::start(), TestConcaveSquareFillet(), PNS::tightenSegment(), PNS::LINE_PLACER::Trace(), TransformCircleToPolygon(), unfracture(), SHAPE_POLY_SET::unfractureSingle(), POLYGON_GEOM_MANAGER::updateLeaderPoints(), PNS::LINE::Walkaround(), and walkaround2().

◆ Append() [2/4]

void SHAPE_LINE_CHAIN::Append ( const VECTOR2I aP,
bool  aAllowDuplication = false 
)
inline

Function Append()

Appends a new point at the end of the line chain.

Parameters
aPthe new point
aAllowDuplication= true to append the new point even it is the same as the last entered point false (default) to skip it if it is the same as the last entered point

Definition at line 446 of file shape_line_chain.h.

447  {
448  if( m_points.size() == 0 )
449  m_bbox = BOX2I( aP, VECTOR2I( 0, 0 ) );
450 
451  if( m_points.size() == 0 || aAllowDuplication || CPoint( -1 ) != aP )
452  {
453  m_points.push_back( aP );
454  m_shapes.push_back( ssize_t( SHAPE_IS_PT ) );
455  m_bbox.Merge( aP );
456  }
457  }
BOX2I m_bbox
cached bounding box
BOX2< VECTOR2I > BOX2I
Definition: box2.h:522
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
const VECTOR2I & CPoint(int aIndex) const
Function Point()
std::vector< VECTOR2I > m_points
array of vertices
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect.
Definition: box2.h:386
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References CPoint(), m_bbox, m_points, m_shapes, BOX2< Vec >::Merge(), and SHAPE_IS_PT.

◆ Append() [3/4]

void SHAPE_LINE_CHAIN::Append ( const SHAPE_LINE_CHAIN aOtherLine)

Function Append()

Appends another line chain at the end.

Parameters
aOtherLinethe line chain to be appended.

Definition at line 623 of file shape_line_chain.cpp.

624 {
625  assert( m_shapes.size() == m_points.size() );
626 
627  if( aOtherLine.PointCount() == 0 )
628  return;
629 
630  else if( PointCount() == 0 || aOtherLine.CPoint( 0 ) != CPoint( -1 ) )
631  {
632  const VECTOR2I p = aOtherLine.CPoint( 0 );
633  m_points.push_back( p );
634  m_shapes.push_back( aOtherLine.CShapes()[0] );
635  m_bbox.Merge( p );
636  }
637 
638  size_t num_arcs = m_arcs.size();
639  m_arcs.insert( m_arcs.end(), aOtherLine.m_arcs.begin(), aOtherLine.m_arcs.end() );
640 
641  for( int i = 1; i < aOtherLine.PointCount(); i++ )
642  {
643  const VECTOR2I p = aOtherLine.CPoint( i );
644  m_points.push_back( p );
645 
646  ssize_t arcIndex = aOtherLine.ArcIndex( i );
647 
648  if( arcIndex != ssize_t( SHAPE_IS_PT ) )
649  m_shapes.push_back( num_arcs + arcIndex );
650  else
651  m_shapes.push_back( ssize_t( SHAPE_IS_PT ) );
652 
653  m_bbox.Merge( p );
654  }
655 
656  assert( m_shapes.size() == m_points.size() );
657 }
BOX2I m_bbox
cached bounding box
Define a general 2D-vector/point.
Definition: vector2d.h:61
int PointCount() const
Function PointCount()
std::vector< SHAPE_ARC > m_arcs
const std::vector< ssize_t > & CShapes() const
ssize_t ArcIndex(size_t aSegment) const
const VECTOR2I & CPoint(int aIndex) const
Function Point()
std::vector< VECTOR2I > m_points
array of vertices
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect.
Definition: box2.h:386
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References ArcIndex(), CPoint(), CShapes(), m_arcs, m_bbox, m_points, m_shapes, BOX2< Vec >::Merge(), PointCount(), and SHAPE_IS_PT.

◆ Append() [4/4]

void SHAPE_LINE_CHAIN::Append ( const SHAPE_ARC aArc)

Definition at line 660 of file shape_line_chain.cpp.

661 {
662  auto& chain = aArc.ConvertToPolyline();
663 
664  for( auto& pt : chain.CPoints() )
665  {
666  m_points.push_back( pt );
667  m_shapes.push_back( m_arcs.size() );
668  }
669 
670  m_arcs.push_back( aArc );
671 
672  assert( m_shapes.size() == m_points.size() );
673 }
std::vector< SHAPE_ARC > m_arcs
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=0.005 *PCB_IU_PER_MM) const
Constructs a SHAPE_LINE_CHAIN of segments from a given arc.
Definition: shape_arc.cpp:408
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References SHAPE_ARC::ConvertToPolyline(), m_arcs, m_points, and m_shapes.

◆ Arc()

const SHAPE_ARC& SHAPE_LINE_CHAIN::Arc ( size_t  aArc) const
inline

Definition at line 747 of file shape_line_chain.h.

748  {
749  return m_arcs[aArc];
750  }
std::vector< SHAPE_ARC > m_arcs

References m_arcs.

Referenced by PNS::NODE::Add(), and PNS::LINE_PLACER::FixRoute().

◆ ArcCount()

size_t SHAPE_LINE_CHAIN::ArcCount ( ) const
inline

Definition at line 734 of file shape_line_chain.h.

735  {
736  return m_arcs.size();
737  }
std::vector< SHAPE_ARC > m_arcs

References m_arcs.

Referenced by PNS::LINE::ArcCount(), ROUTER_PREVIEW_ITEM::drawLineChain(), and PNS::LINE_PLACER::FixRoute().

◆ ArcIndex()

ssize_t SHAPE_LINE_CHAIN::ArcIndex ( size_t  aSegment) const
inline

Definition at line 739 of file shape_line_chain.h.

740  {
741  if( aSegment >= m_shapes.size() )
742  return SHAPE_IS_PT;
743 
744  return m_shapes[aSegment];
745  }
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References m_shapes, and SHAPE_IS_PT.

Referenced by Append(), and PNS::LINE_PLACER::FixRoute().

◆ Area()

double SHAPE_LINE_CHAIN::Area ( ) const

Definition at line 1315 of file shape_line_chain.cpp.

1316 {
1317  // see https://www.mathopenref.com/coordpolygonarea2.html
1318 
1319  if( !m_closed )
1320  return 0.0;
1321 
1322  double area = 0.0;
1323  int size = m_points.size();
1324 
1325  for( int i = 0, j = size - 1; i < size; ++i )
1326  {
1327  area += ( (double) m_points[j].x + m_points[i].x ) * ( (double) m_points[j].y - m_points[i].y );
1328  j = i;
1329  }
1330 
1331  return -area * 0.5;
1332 }
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices

References m_closed, and m_points.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), SHAPE_POLY_SET::Area(), ZONE::CalculateFilledArea(), ZONE_FILLER::Fill(), FOOTPRINT::GetCoverageArea(), DIALOG_BOARD_STATISTICS::getDataFromPCB(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), polygonArea(), unfracture(), and SHAPE_POLY_SET::unfractureSingle().

◆ BBox()

const BOX2I SHAPE_LINE_CHAIN::BBox ( int  aClearance = 0) const
inlineoverridevirtual

Compute a bounding box of the shape, with a margin of aClearance a collision.

Parameters
aClearancehow much the bounding box is expanded wrs to the minimum enclosing rectangle for the shape.
Returns
the bounding box.

Implements SHAPE.

Definition at line 372 of file shape_line_chain.h.

373  {
374  BOX2I bbox;
375  bbox.Compute( m_points );
376 
377  if( aClearance != 0 || m_width != 0 )
378  bbox.Inflate( aClearance + m_width );
379 
380  return bbox;
381  }
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Definition: box2.h:91
BOX2 handles a 2-D bounding box, built on top of an origin point and size vector, both of templated c...
Definition: box2.h:43
std::vector< VECTOR2I > m_points
array of vertices
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:302
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...

References BOX2< Vec >::Compute(), BOX2< Vec >::Inflate(), m_points, and m_width.

Referenced by SHAPE_SIMPLE::BBox(), POLY_GRID_PARTITION::build(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), AR_AUTOPLACER::fillMatrix(), DIALOG_BOARD_STATISTICS::getDataFromPCB(), Intersect(), FABMASTER::loadZones(), and PolygonTriangulation::TesselatePolygon().

◆ BBoxFromCache()

const BOX2I SHAPE_LINE_CHAIN::BBoxFromCache ( ) const
inline

Definition at line 391 of file shape_line_chain.h.

392  {
393  return m_bbox;
394  }
BOX2I m_bbox
cached bounding box

References m_bbox.

◆ CalcShape()

SGNODE * SHAPE::CalcShape ( SGNODE aParent,
SGNODE aColor,
WRL1_ORDER  aVertexOrder,
float  aCreaseLimit = 0.74317,
bool  isVRML2 = false 
)
inherited

Definition at line 713 of file wrlfacet.cpp.

715 {
716  if( facets.empty() || !facets.front()->HasMinPoints() )
717  return NULL;
718 
719  std::vector< std::list< FACET* > > flist;
720 
721  // determine the max. index and size flist as appropriate
722  std::list< FACET* >::iterator sF = facets.begin();
723  std::list< FACET* >::iterator eF = facets.end();
724 
725  int maxIdx = 0;
726  int tmi;
727  float maxV = 0.0;
728  float tV = 0.0;
729 
730  while( sF != eF )
731  {
732  tV = ( *sF )->CalcFaceNormal();
733  tmi = ( *sF )->GetMaxIndex();
734 
735  if( tmi > maxIdx )
736  maxIdx = tmi;
737 
738  if( tV > maxV )
739  maxV = tV;
740 
741  ++sF;
742  }
743 
744  ++maxIdx;
745 
746  if( maxIdx < 3 )
747  return NULL;
748 
749  flist.resize( maxIdx );
750 
751  // create the lists of facets common to indices
752  sF = facets.begin();
753 
754  while( sF != eF )
755  {
756  ( *sF )->Renormalize( tV );
757  ( *sF )->CollectVertices( flist );
758  ++sF;
759  }
760 
761  // calculate the normals
762  size_t vs = flist.size();
763 
764  for( size_t i = 0; i < vs; ++i )
765  {
766  sF = flist[i].begin();
767  eF = flist[i].end();
768 
769  while( sF != eF )
770  {
771  ( *sF )->CalcVertexNormal( static_cast<int>( i ), flist[i], aCreaseLimit );
772  ++sF;
773  }
774  }
775 
776  std::vector< WRLVEC3F > vertices;
777  std::vector< WRLVEC3F > normals;
778  std::vector< SGCOLOR > colors;
779 
780  // push the facet data to the final output list
781  sF = facets.begin();
782  eF = facets.end();
783 
784  while( sF != eF )
785  {
786  ( *sF )->GetData( vertices, normals, colors, aVertexOrder );
787  ++sF;
788  }
789 
790  flist.clear();
791 
792  if( vertices.size() < 3 )
793  return NULL;
794 
795  IFSG_SHAPE shapeNode( false );
796 
797  if( !isVRML2 )
798  {
799  shapeNode.NewNode( aParent );
800 
801  if( aColor )
802  {
803  if( NULL == S3D::GetSGNodeParent( aColor ) )
804  shapeNode.AddChildNode( aColor );
805  else
806  shapeNode.AddRefNode( aColor );
807  }
808  }
809 
810  std::vector< SGPOINT > lCPts; // vertex points in SGPOINT (double) format
811  std::vector< SGVECTOR > lCNorm; // per-vertex normals
812  vs = vertices.size();
813 
814  for( size_t i = 0; i < vs; ++i )
815  {
816  SGPOINT pt;
817  pt.x = vertices[i].x;
818  pt.y = vertices[i].y;
819  pt.z = vertices[i].z;
820  lCPts.push_back( pt );
821  lCNorm.emplace_back( normals[i].x, normals[i].y, normals[i].z );
822  }
823 
824  vertices.clear();
825  normals.clear();
826 
827  IFSG_FACESET fsNode( false );
828 
829  if( !isVRML2 )
830  fsNode.NewNode( shapeNode );
831  else
832  fsNode.NewNode( aParent );
833 
834  IFSG_COORDS cpNode( fsNode );
835  cpNode.SetCoordsList( lCPts.size(), &lCPts[0] );
836  IFSG_COORDINDEX ciNode( fsNode );
837 
838  for( int i = 0; i < (int)lCPts.size(); ++i )
839  ciNode.AddIndex( i );
840 
841  IFSG_NORMALS nmNode( fsNode );
842  nmNode.SetNormalList( lCNorm.size(), &lCNorm[0] );
843 
844  if( !colors.empty() )
845  {
846  IFSG_COLORS nmColor( fsNode );
847  nmColor.SetColorList( colors.size(), &colors[0] );
848  colors.clear();
849  }
850 
851  if( !isVRML2 )
852  return shapeNode.GetRawPtr();
853 
854  return fsNode.GetRawPtr();
855 }
double x
Definition: sg_base.h:70
IFSG_COORDS is the wrapper for SGCOORDS.
Definition: ifsg_coords.h:40
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
IFSG_COLORS is the wrapper for SGCOLORS.
Definition: ifsg_colors.h:41
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:492
double y
Definition: sg_base.h:71
IFSG_NORMALS is the wrapper for the SGNORMALS class.
Definition: ifsg_normals.h:40
#define NULL
std::list< FACET * > facets
Definition: wrlfacet.h:143
IFSG_FACESET is the wrapper for the SGFACESET class.
Definition: ifsg_faceset.h:40
double z
Definition: sg_base.h:72
IFSG_SHAPE is the wrapper for the SGSHAPE class.
Definition: ifsg_shape.h:40

References IFSG_NODE::AddChildNode(), IFSG_INDEX::AddIndex(), IFSG_NODE::AddRefNode(), SHAPE::facets, IFSG_NODE::GetRawPtr(), S3D::GetSGNodeParent(), IFSG_FACESET::NewNode(), IFSG_SHAPE::NewNode(), NULL, IFSG_COLORS::SetColorList(), IFSG_COORDS::SetCoordsList(), IFSG_NORMALS::SetNormalList(), SGPOINT::x, SGPOINT::y, and SGPOINT::z.

Referenced by WRL1FACESET::TranslateToSG(), X3DIFACESET::TranslateToSG(), and WRL2FACESET::TranslateToSG().

◆ CArcs()

const std::vector<SHAPE_ARC>& SHAPE_LINE_CHAIN::CArcs ( ) const
inline
Returns
the vector of stored arcs

Definition at line 358 of file shape_line_chain.h.

359  {
360  return m_arcs;
361  }
std::vector< SHAPE_ARC > m_arcs

References m_arcs.

Referenced by ROUTER_PREVIEW_ITEM::drawLineChain(), PNS::LINE_PLACER::handlePullback(), and PNS::LINE_PLACER::mergeHead().

◆ Centre()

virtual VECTOR2I SHAPE::Centre ( ) const
inlinevirtualinherited

Compute a center-of-mass of the shape.

Returns
the center-of-mass point

Definition at line 216 of file shape.h.

217  {
218  return BBox( 0 ).Centre(); // if nothing better is available....
219  }
virtual const BOX2I BBox(int aClearance=0) const =0
Compute a bounding box of the shape, with a margin of aClearance a collision.
Vec Centre() const
Definition: box2.h:79

References SHAPE::BBox(), and BOX2< Vec >::Centre().

Referenced by Collide().

◆ CheckClearance()

bool SHAPE_LINE_CHAIN::CheckClearance ( const VECTOR2I aP,
const int  aDist 
) const

Function CheckClearance()

Checks if point aP is closer to (or on) an edge or vertex of the line chain.

Parameters
aPpoint to check
aDistdistance in internal units
Returns
true if the point is equal to or closer than aDist to the line chain.

Definition at line 927 of file shape_line_chain.cpp.

928 {
929  if( !PointCount() )
930  return false;
931 
932  else if( PointCount() == 1 )
933  return m_points[0] == aP;
934 
935  for( int i = 0; i < SegmentCount(); i++ )
936  {
937  const SEG s = CSegment( i );
938 
939  if( s.A == aP || s.B == aP )
940  return true;
941 
942  if( s.Distance( aP ) <= aDist )
943  return true;
944  }
945 
946  return false;
947 }
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.h:239
int PointCount() const
Function PointCount()
std::vector< VECTOR2I > m_points
array of vertices
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
const SEG CSegment(int aIndex) const
Function CSegment()
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50

References SEG::A, SEG::B, CSegment(), SEG::Distance(), m_points, PointCount(), and SegmentCount().

◆ CLastPoint()

const VECTOR2I& SHAPE_LINE_CHAIN::CLastPoint ( ) const
inline

Returns the last point in the line chain.

Definition at line 350 of file shape_line_chain.h.

351  {
352  return m_points[PointCount() - 1];
353  }
int PointCount() const
Function PointCount()
std::vector< VECTOR2I > m_points
array of vertices

References m_points, and PointCount().

Referenced by POLYGON_GEOM_MANAGER::DeleteLastCorner(), and POLYGON_GEOM_MANAGER::updateLeaderPoints().

◆ Clear()

void SHAPE_LINE_CHAIN::Clear ( )
inline

Function Clear() Removes all points from the line chain.

Definition at line 172 of file shape_line_chain.h.

173  {
174  m_points.clear();
175  m_arcs.clear();
176  m_shapes.clear();
177  m_closed = false;
178  }
std::vector< SHAPE_ARC > m_arcs
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References m_arcs, m_closed, m_points, and m_shapes.

Referenced by PNS_PCBNEW_DEBUG_DECORATOR::AddPoint(), PNS::LINE_PLACER::buildInitialLine(), PNS::MOUSE_TRAIL_TRACER::Clear(), SHAPE_SIMPLE::Clear(), PNS::LINE::Clear(), PNS::DIFF_PAIR::Clear(), PNS::LINE::ClipToNearestObstacle(), KI_TEST::CommonTestData::CommonTestData(), PNS::MEANDER_PLACER::doMove(), PNS::LINE_PLACER::FixRoute(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), PNS::LINE_PLACER::handlePullback(), PNS::LINE_PLACER::handleSelfIntersections(), PNS::LINE_PLACER::initPlacement(), IteratorFixture::IteratorFixture(), PNS::TOPOLOGY::LeadingRatLine(), PNS::MEANDER_SHAPE::MakeCorner(), PNS::DP_MEANDER_PLACER::Move(), PNS::SHOVE::onReverseCollidingVia(), PNS::LINE_PLACER::optimizeTailHeadTransition(), PNS::LINE_PLACER::reduceTail(), POLYGON_GEOM_MANAGER::Reset(), PNS::LINE_PLACER::SetLayer(), PNS::MEANDER_SHAPE::start(), PNS::tightenSegment(), and PNS::LINE_PLACER::UnfixRoute().

◆ Clone()

SHAPE * SHAPE_LINE_CHAIN::Clone ( ) const
overridevirtual

Return a dynamically allocated copy of the shape.

Return values
copyof the shape

Reimplemented from SHAPE.

Definition at line 1238 of file shape_line_chain.cpp.

1239 {
1240  return new SHAPE_LINE_CHAIN( *this );
1241 }
SHAPE_LINE_CHAIN()
Constructor Initializes an empty line chain.

References SHAPE_LINE_CHAIN().

Referenced by ROUTER_PREVIEW_ITEM::Line().

◆ Collide() [1/4]

bool SHAPE::Collide ( const SHAPE aShape,
int  aClearance,
VECTOR2I aMTV 
) const
virtualinherited

Check if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating a collision.

Parameters
aShapeshape to check collision against
aClearanceminimum clearance
aMTVminimum translation vector
aActual[out] an optional pointer to an int to store the actual distance in the event of a collision.
aLocation[out] an option pointer to a point to store a nearby location in the event of a collision.
Returns
true, if there is a collision.

Reimplemented in SHAPE_RECT, SHAPE_SEGMENT, and SHAPE_COMPOUND.

Definition at line 881 of file shape_collisions.cpp.

882 {
883  return collideShapes( this, aShape, aClearance, nullptr, nullptr, aMTV );
884 }
static bool collideShapes(const SHAPE *aA, const SHAPE *aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)

References collideShapes().

◆ Collide() [2/4]

bool SHAPE::Collide ( const SHAPE aShape,
int  aClearance = 0,
int *  aActual = nullptr,
VECTOR2I aLocation = nullptr 
) const
virtualinherited

Reimplemented in SHAPE_POLY_SET, SHAPE_RECT, SHAPE_SEGMENT, and SHAPE_COMPOUND.

Definition at line 887 of file shape_collisions.cpp.

888 {
889  return collideShapes( this, aShape, aClearance, aActual, aLocation, nullptr );
890 }
static bool collideShapes(const SHAPE *aA, const SHAPE *aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)

References collideShapes().

◆ Collide() [3/4]

bool SHAPE_LINE_CHAIN_BASE::Collide ( const VECTOR2I aP,
int  aClearance = 0,
int *  aActual = nullptr,
VECTOR2I aLocation = nullptr 
) const
overridevirtualinherited

Check if point aP lies closer to us than aClearance.

Parameters
aPthe point to check for collisions with
aClearanceminimum distance that does not qualify as a collision.
aActualan optional pointer to an int to store the actual distance in the event of a collision.
Returns
true, when a collision has been found

Reimplemented from SHAPE.

Definition at line 88 of file shape_line_chain.cpp.

90 {
91  if( IsClosed() && PointInside( aP, aClearance ) )
92  {
93  if( aLocation )
94  *aLocation = aP;
95 
96  if( aActual )
97  *aActual = 0;
98 
99  return true;
100  }
101 
102  SEG::ecoord closest_dist_sq = VECTOR2I::ECOORD_MAX;
103  SEG::ecoord clearance_sq = SEG::Square( aClearance );
104  VECTOR2I nearest;
105 
106  for( size_t i = 0; i < GetSegmentCount(); i++ )
107  {
108  const SEG& s = GetSegment( i );
109  VECTOR2I pn = s.NearestPoint( aP );
110  SEG::ecoord dist_sq = ( pn - aP ).SquaredEuclideanNorm();
111 
112  if( dist_sq < closest_dist_sq )
113  {
114  nearest = pn;
115  closest_dist_sq = dist_sq;
116 
117  if( closest_dist_sq == 0 )
118  break;
119 
120  // If we're not looking for aActual then any collision will do
121  if( closest_dist_sq < clearance_sq && !aActual )
122  break;
123  }
124  }
125 
126  if( closest_dist_sq == 0 || closest_dist_sq < clearance_sq )
127  {
128  if( aLocation )
129  *aLocation = nearest;
130 
131  if( aActual )
132  *aActual = sqrt( closest_dist_sq );
133 
134  return true;
135  }
136 
137  return false;
138 }
virtual bool IsClosed() const =0
VECTOR2I::extended_type ecoord
Definition: seg.h:44
Define a general 2D-vector/point.
Definition: vector2d.h:61
virtual size_t GetSegmentCount() const =0
static SEG::ecoord Square(int a)
Definition: seg.h:123
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
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 VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.h:437
Definition: seg.h:41
virtual const SEG GetSegment(int aIndex) const =0

References VECTOR2< T >::ECOORD_MAX, SHAPE_LINE_CHAIN_BASE::GetSegment(), SHAPE_LINE_CHAIN_BASE::GetSegmentCount(), SHAPE_LINE_CHAIN_BASE::IsClosed(), SEG::NearestPoint(), SHAPE_LINE_CHAIN_BASE::PointInside(), and SEG::Square().

Referenced by PNS::MEANDERED_LINE::CheckSelfIntersections(), SHAPE_SIMPLE::Collide(), Collide(), and PCB_SELECTION_TOOL::hitTestDistance().

◆ Collide() [4/4]

bool SHAPE_LINE_CHAIN_BASE::Collide ( const SEG aSeg,
int  aClearance = 0,
int *  aActual = nullptr,
VECTOR2I aLocation = nullptr 
) const
overridevirtualinherited

Check if segment aSeg lies closer to us than aClearance.

Parameters
aSegthe segment to check for collisions with
aClearanceminimum distance that does not qualify as a collision.
aActualan optional pointer to an int to store the actual distance in the event of a collision.
Returns
true, when a collision has been found

Implements SHAPE.

Reimplemented in SHAPE_SIMPLE.

Definition at line 155 of file shape_line_chain.cpp.

157 {
158  if( IsClosed() && PointInside( aSeg.A ) )
159  {
160  if( aLocation )
161  *aLocation = aSeg.A;
162 
163  if( aActual )
164  *aActual = 0;
165 
166  return true;
167  }
168 
169  SEG::ecoord closest_dist_sq = VECTOR2I::ECOORD_MAX;
170  SEG::ecoord clearance_sq = SEG::Square( aClearance );
171  VECTOR2I nearest;
172 
173  for( size_t i = 0; i < GetSegmentCount(); i++ )
174  {
175  const SEG& s = GetSegment( i );
176  SEG::ecoord dist_sq =s.SquaredDistance( aSeg );
177 
178  if( dist_sq < closest_dist_sq )
179  {
180  if( aLocation )
181  nearest = s.NearestPoint( aSeg );
182 
183  closest_dist_sq = dist_sq;
184 
185  if( closest_dist_sq == 0)
186  break;
187 
188  // If we're not looking for aActual then any collision will do
189  if( closest_dist_sq < clearance_sq && !aActual )
190  break;
191  }
192  }
193 
194  if( closest_dist_sq == 0 || closest_dist_sq < clearance_sq )
195  {
196  if( aLocation )
197  *aLocation = nearest;
198 
199  if( aActual )
200  *aActual = sqrt( closest_dist_sq );
201 
202  return true;
203  }
204 
205  return false;
206 }
virtual bool IsClosed() const =0
VECTOR2I::extended_type ecoord
Definition: seg.h:44
Define a general 2D-vector/point.
Definition: vector2d.h:61
ecoord SquaredDistance(const SEG &aSeg) const
Definition: seg.cpp:39
virtual size_t GetSegmentCount() const =0
static SEG::ecoord Square(int a)
Definition: seg.h:123
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
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 VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.h:437
Definition: seg.h:41
virtual const SEG GetSegment(int aIndex) const =0
VECTOR2I A
Definition: seg.h:49

References SEG::A, VECTOR2< T >::ECOORD_MAX, SHAPE_LINE_CHAIN_BASE::GetSegment(), SHAPE_LINE_CHAIN_BASE::GetSegmentCount(), SHAPE_LINE_CHAIN_BASE::IsClosed(), SEG::NearestPoint(), SHAPE_LINE_CHAIN_BASE::PointInside(), SEG::Square(), and SEG::SquaredDistance().

◆ CompareGeometry()

bool SHAPE_LINE_CHAIN::CompareGeometry ( const SHAPE_LINE_CHAIN aOther) const

Definition at line 1215 of file shape_line_chain.cpp.

1216 {
1217  SHAPE_LINE_CHAIN a(*this), b( aOther );
1218  a.Simplify();
1219  b.Simplify();
1220 
1221  if( a.m_points.size() != b.m_points.size() )
1222  return false;
1223 
1224  for( int i = 0; i < a.PointCount(); i++)
1225  if( a.CPoint( i ) != b.CPoint( i ) )
1226  return false;
1227  return true;
1228 }
SHAPE_LINE_CHAIN.

References CPoint(), m_points, and Simplify().

Referenced by PNS::LINE::CompareGeometry().

◆ convertArc()

void SHAPE_LINE_CHAIN::convertArc ( ssize_t  aArcIndex)

Converts an arc to only a point chain by removing the arc and references.

Parameters
aArcIndexindex of the arc to convert to points

Definition at line 66 of file shape_line_chain.cpp.

67 {
68  if( aArcIndex < 0 )
69  aArcIndex += m_arcs.size();
70 
71  if( aArcIndex >= static_cast<ssize_t>( m_arcs.size() ) )
72  return;
73 
74  // Clear the shapes references
75  for( auto& sh : m_shapes )
76  {
77  if( sh == aArcIndex )
78  sh = SHAPE_IS_PT;
79 
80  if( sh > aArcIndex )
81  --sh;
82  }
83 
84  m_arcs.erase( m_arcs.begin() + aArcIndex );
85 }
std::vector< SHAPE_ARC > m_arcs
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References m_arcs, m_shapes, and SHAPE_IS_PT.

Referenced by Insert(), Remove(), Replace(), and SetPoint().

◆ convertToClipper()

ClipperLib::Path SHAPE_LINE_CHAIN::convertToClipper ( bool  aRequiredOrientation) const

Creates a new Clipper path from the SHAPE_LINE_CHAIN in a given orientation.

Definition at line 48 of file shape_line_chain.cpp.

49 {
50  ClipperLib::Path c_path;
51 
52  for( int i = 0; i < PointCount(); i++ )
53  {
54  const VECTOR2I& vertex = CPoint( i );
55  c_path.push_back( ClipperLib::IntPoint( vertex.x, vertex.y ) );
56  }
57 
58  if( Orientation( c_path ) != aRequiredOrientation )
59  ReversePath( c_path );
60 
61  return c_path;
62 }
Define a general 2D-vector/point.
Definition: vector2d.h:61
int PointCount() const
Function PointCount()
const VECTOR2I & CPoint(int aIndex) const
Function Point()

References CPoint(), PointCount(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ CPoint()

const VECTOR2I& SHAPE_LINE_CHAIN::CPoint ( int  aIndex) const
inline

Function Point()

Returns a const reference to a given point in the line chain.

Parameters
aIndexindex of the point
Returns
const reference to the point

Definition at line 332 of file shape_line_chain.h.

333  {
334  if( aIndex < 0 )
335  aIndex += PointCount();
336  else if( aIndex >= PointCount() )
337  aIndex -= PointCount();
338 
339  return m_points[aIndex];
340  }
int PointCount() const
Function PointCount()
std::vector< VECTOR2I > m_points
array of vertices

References m_points, and PointCount().

Referenced by POLYGON_GEOM_MANAGER::AddPoint(), SHAPE_LINE_CHAIN::POINT_INSIDE_TRACKER::AddPolyline(), BOARD_ADAPTER::addSolidAreasShapes(), TRIANGLE_DISPLAY_LIST::AddToMiddleContourns(), PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), Append(), PNS::LINE::AppendVia(), ArePolylineEndPointsNearCircle(), ArePolylineMidPointsNearCircle(), PNS::NODE::AssembleLine(), PNS::TOPOLOGY::AssembleTuningPath(), BOOST_AUTO_TEST_CASE(), BuildConvexHull(), PAD::BuildEffectivePolygon(), PAD::BuildEffectiveShapes(), PNS::LINE_PLACER::buildInitialLine(), SHAPE_POLY_SET::chamferFilletPolygon(), PNS::LINE::ChangedArea(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), CN_VISITOR::checkZoneZoneConnection(), CompareGeometry(), convertToClipper(), PNS::coupledBypass(), SHAPE_SIMPLE::CPoint(), PNS::LINE::CPoint(), PolygonTriangulation::createList(), CreatePadsShapesSection(), PNS::LINE::dragCorner45(), PNS::dragCornerInternal(), APERTURE_MACRO::DrawApertureMacroShape(), KIGFX::CAIRO_GAL_BASE::drawPoly(), KIGFX::OPENGL_GAL::DrawPolygon(), KIGFX::OPENGL_GAL::DrawPolyline(), EXPORTER_PCB_VRML::ExportVrmlBoard(), EXPORTER_PCB_VRML::ExportVrmlPolygonSet(), DSN::SPECCTRA_DB::fillBOUNDARY(), AR_AUTOPLACER::fillMatrix(), Find(), PNS::LINE_PLACER::FixRoute(), GERBER_PLOTTER::FlashPadChamferRoundRect(), PSLIKE_PLOTTER::FlashPadCustom(), DXF_PLOTTER::FlashPadCustom(), HPGL_PLOTTER::FlashPadCustom(), GERBER_PLOTTER::FlashPadCustom(), PSLIKE_PLOTTER::FlashPadRoundRect(), DXF_PLOTTER::FlashPadRoundRect(), HPGL_PLOTTER::FlashPadRoundRect(), GERBER_PLOTTER::FlashPadRoundRect(), PNS::TOPOLOGY::followTrivialPath(), PCB_IO::format(), CN_ZONE_LAYER::GetAnchor(), SHAPE_SIMPLE::GetPoint(), GetPoint(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), PNS::MOUSE_TRAIL_TRACER::GetTrailLeadVector(), PNS::LINE_PLACER::handlePullback(), PNS::LINE_PLACER::handleSelfIntersections(), DS_DRAW_ITEM_POLYPOLYGONS::HitTest(), POLYGON_GEOM_MANAGER::IsSelfIntersecting(), DSN::SPECCTRA_DB::makePADSTACK(), PNS::LINE_PLACER::mergeHead(), PNS::MEANDER_SHAPE::miter(), PNS::LINE_PLACER::Move(), NearestPoint(), POLYGON_GEOM_MANAGER::NewPointClosesOutline(), operator!=(), BOOST_TEST_PRINT_NAMESPACE_OPEN::print_log_value< SHAPE_LINE_CHAIN >::operator()(), PNS::LINE_PLACER::optimizeTailHeadTransition(), BITMAPCONV_INFO::outputOnePolygon(), PlotDrawingSheet(), BRDITEMS_PLOTTER::PlotFilledAreas(), PLOTTER::PlotPoly(), PointAlong(), PNS::pointInside2(), polygon_Convert(), GERBER_DRAW_ITEM::PrintGerberPoly(), DS_DRAW_ITEM_POLYPOLYGONS::PrintWsItem(), PNS::LINE_PLACER::removeLoops(), PNS::DIFF_PAIR_PLACER::routeHead(), PNS::OPTIMIZER::runSmartPads(), KIGFX::PREVIEW::POLYGON_ITEM::SetPoints(), PNS::shovedArea(), PNS::SHOVE::shoveLineFromLoneVia(), PNS::SHOVE::shoveLineToHullSet(), Simplify(), unfracture(), SHAPE_POLY_SET::unfractureSingle(), PNS::MEANDER_SHAPE::updateBaseSegment(), POLYGON_GEOM_MANAGER::updateLeaderPoints(), PNS::LINE::Walkaround(), walkaround2(), HYPERLYNX_EXPORTER::writeNetObjects(), GBR_TO_PCB_EXPORTER::writePcbPolygon(), and GBR_TO_PCB_EXPORTER::writePcbZoneItem().

◆ CPoints()

◆ CSegment()

const SEG SHAPE_LINE_CHAIN::CSegment ( int  aIndex) const
inline

Function CSegment()

Returns a constant copy of the aIndex-th segment in the line chain.

Parameters
aIndexindex of the segment in the line chain. Negative values are counted from the end (i.e. -1 means the last segment in the line chain)
Returns
const SEG - aIndex-th segment in the line chain

Definition at line 280 of file shape_line_chain.h.

281  {
282  if( aIndex < 0 )
283  aIndex += SegmentCount();
284 
285  if( aIndex == (int)( m_points.size() - 1 ) && m_closed )
286  return SEG( m_points[aIndex], m_points[0], aIndex );
287  else
288  return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
289  }
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41

References m_closed, m_points, and SegmentCount().

Referenced by PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), PNS::ArcHull(), PNS::LINE_PLACER::buildInitialLine(), PNS::PRESERVE_VERTEX_CONSTRAINT::Check(), CheckClearance(), PNS::NODE::CheckColliding(), PNS::DIFF_PAIR::CheckConnectionAngle(), PNS::checkGap(), PNS::MEANDERED_LINE::CheckSelfIntersections(), PNS::closestProjectedPoint(), PCB_GRID_HELPER::computeAnchors(), PNS::COST_ESTIMATOR::CornerCost(), PNS::LINE::CountCorners(), PNS::coupledBypass(), PNS::DIFF_PAIR::CoupledLength(), PNS::LINE::CSegment(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::dragCornerInternal(), PNS::findCoupledVertices(), FindSegment(), PNS::DIFF_PAIR_PLACER::FixRoute(), PNS::LINE_PLACER::FixRoute(), PCB_SHAPE::GetLength(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), SHAPE_SIMPLE::GetSegment(), GetSegment(), PNS::LINE_PLACER::handlePullback(), PNS::LINE_PLACER::handleSelfIntersections(), Intersect(), PNS::LINE::Is45Degree(), Length(), PNS::OPTIMIZER::mergeColinear(), PNS::OPTIMIZER::mergeDpStep(), PNS::LINE_PLACER::mergeHead(), PNS::OPTIMIZER::mergeObtuse(), PNS::OPTIMIZER::mergeStep(), PNS::NODE::NearestObstacle(), NearestPoint(), NearestSegment(), PathLength(), PointAlong(), KIGFX::VIEW_OVERLAY::Polyline(), PNS::LINE_PLACER::reduceTail(), DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run(), POLY_GRID_PARTITION::scanCell(), segmentCrossesHullBoundary(), PNS::SegmentHull(), SelfIntersecting(), PNS::OPTIMIZER::smartPadsSingle(), PNS::LINE::snapDraggedCorner(), PNS::LINE::snapToNeighbourSegments(), Split(), PNS::tightenSegment(), SHAPE_POLY_SET::unfractureSingle(), and HYPERLYNX_EXPORTER::writeBoardInfo().

◆ CShapes()

const std::vector<ssize_t>& SHAPE_LINE_CHAIN::CShapes ( ) const
inline
Returns
the vector of values indicating shape type and location

Definition at line 366 of file shape_line_chain.h.

367  {
368  return m_shapes;
369  }
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References m_shapes.

Referenced by Append(), PNS::NODE::AssembleLine(), BOOST_AUTO_TEST_CASE(), PNS::LINE::ClipVertexRange(), PNS::LINE::dragCorner45(), PNS::LINE::dragCornerFree(), PNS::LINE_PLACER::FixRoute(), PNS::LINE_PLACER::handlePullback(), PNS::OPTIMIZER::mergeColinear(), PNS::LINE_PLACER::mergeHead(), and PNS::DRAGGER::startDragSegment().

◆ Distance()

int SHAPE_LINE_CHAIN::Distance ( const VECTOR2I aP,
bool  aOutlineOnly = false 
) const

Function Distance()

Computes the minimum distance between the line chain and a point aP.

Parameters
aPthe point
Returns
minimum distance.

Definition at line 392 of file shape_line_chain.cpp.

393 {
394  return sqrt( SquaredDistance( aP, aOutlineOnly ) );
395 }
SEG::ecoord SquaredDistance(const VECTOR2I &aP, bool aOutlineOnly=false) const

References SHAPE_LINE_CHAIN_BASE::SquaredDistance().

Referenced by PAD::GetBestAnchorPosition().

◆ EdgeContainingPoint()

int SHAPE_LINE_CHAIN_BASE::EdgeContainingPoint ( const VECTOR2I aP,
int  aAccuracy = 0 
) const
inherited

Check if point aP lies on an edge or vertex of the line chain.

Parameters
aPpoint to check
Returns
index of the first edge containing the point, otherwise negative

Definition at line 901 of file shape_line_chain.cpp.

902 {
903  if( !GetPointCount() )
904  return -1;
905 
906  else if( GetPointCount() == 1 )
907  {
908  VECTOR2I dist = GetPoint(0) - aPt;
909  return ( hypot( dist.x, dist.y ) <= aAccuracy + 1 ) ? 0 : -1;
910  }
911 
912  for( size_t i = 0; i < GetSegmentCount(); i++ )
913  {
914  const SEG s = GetSegment( i );
915 
916  if( s.A == aPt || s.B == aPt )
917  return i;
918 
919  if( s.Distance( aPt ) <= aAccuracy + 1 )
920  return i;
921  }
922 
923  return -1;
924 }
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.h:239
Define a general 2D-vector/point.
Definition: vector2d.h:61
virtual size_t GetPointCount() const =0
virtual size_t GetSegmentCount() const =0
Definition: seg.h:41
virtual const SEG GetSegment(int aIndex) const =0
VECTOR2I A
Definition: seg.h:49
virtual const VECTOR2I GetPoint(int aIndex) const =0
VECTOR2I B
Definition: seg.h:50

References SEG::A, SEG::B, SEG::Distance(), SHAPE_LINE_CHAIN_BASE::GetPoint(), SHAPE_LINE_CHAIN_BASE::GetPointCount(), SHAPE_LINE_CHAIN_BASE::GetSegment(), SHAPE_LINE_CHAIN_BASE::GetSegmentCount(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by SHAPE_LINE_CHAIN_BASE::PointOnEdge().

◆ Find()

int SHAPE_LINE_CHAIN::Find ( const VECTOR2I aP) const

Function Find()

Searches for point aP.

Parameters
aPthe point to be looked for
Returns
index of the correspoinding point in the line chain or negative when not found.

Definition at line 456 of file shape_line_chain.cpp.

457 {
458  for( int s = 0; s < PointCount(); s++ )
459  if( CPoint( s ) == aP )
460  return s;
461 
462  return -1;
463 }
int PointCount() const
Function PointCount()
const VECTOR2I & CPoint(int aIndex) const
Function Point()

References CPoint(), and PointCount().

Referenced by PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::DRAGGER::dragViaMarkObstacles(), PNS::DRAGGER::dragViaWalkaround(), PNS::NODE::FindLinesBetweenJoints(), PNS::DRAGGER::optimizeAndUpdateDraggedLine(), Split(), PNS::LINE::Walkaround(), and walkaround2().

◆ FindSegment()

int SHAPE_LINE_CHAIN::FindSegment ( const VECTOR2I aP) const

Function FindSegment()

Searches for segment containing point aP.

Parameters
aPthe point to be looked for
Returns
index of the correspoinding segment in the line chain or negative when not found.

Definition at line 466 of file shape_line_chain.cpp.

467 {
468  for( int s = 0; s < SegmentCount(); s++ )
469  if( CSegment( s ).Distance( aP ) <= 1 )
470  return s;
471 
472  return -1;
473 }
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.h:239
int SegmentCount() const
Function SegmentCount()
const SEG CSegment(int aIndex) const
Function CSegment()

References CSegment(), SEG::Distance(), and SegmentCount().

Referenced by PNS::MEANDER_PLACER_BASE::cutTunedLine(), and CADSTAR_SCH_ARCHIVE_LOADER::loadNets().

◆ Format()

const std::string SHAPE_LINE_CHAIN::Format ( ) const
overridevirtual

Reimplemented from SHAPE.

Definition at line 1184 of file shape_line_chain.cpp.

1185 {
1186  std::stringstream ss;
1187 
1188 
1189  ss << "SHAPE_LINE_CHAIN( { ";
1190  for( int i = 0; i < PointCount(); i++ )
1191  {
1192  ss << "VECTOR2I( " << m_points[i].x << ", " << m_points[i].y << ")";
1193  if( i != PointCount() -1 )
1194  ss << ", ";
1195  }
1196 
1197  ss << "}, " << ( m_closed ? "true" : "false" );
1198  ss << " );";
1199 
1200 
1201 
1202  return ss.str();
1203 
1204 
1205  /* fixme: arcs
1206  for( size_t i = 0; i < m_arcs.size(); i++ )
1207  ss << m_arcs[i].GetCenter().x << " " << m_arcs[i].GetCenter().y << " "
1208  << m_arcs[i].GetP0().x << " " << m_arcs[i].GetP0().y << " "
1209  << m_arcs[i].GetCentralAngle();
1210 
1211  return ss.str();*/
1212 }
int PointCount() const
Function PointCount()
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices

References m_closed, m_points, and PointCount().

Referenced by PNS::SHOVE::shoveLineToHullSet().

◆ GenerateBBoxCache()

void SHAPE_LINE_CHAIN::GenerateBBoxCache ( ) const
inline

Definition at line 383 of file shape_line_chain.h.

384  {
386 
387  if( m_width != 0 )
389  }
BOX2I m_bbox
cached bounding box
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Definition: box2.h:91
std::vector< VECTOR2I > m_points
array of vertices
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:302
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...

References BOX2< Vec >::Compute(), BOX2< Vec >::Inflate(), m_bbox, m_points, and m_width.

Referenced by SHAPE_POLY_SET::BuildBBoxCaches(), and ZONE_FILLER::buildThermalSpokes().

◆ GetIndexableSubshapeCount()

virtual size_t SHAPE_BASE::GetIndexableSubshapeCount ( ) const
inlinevirtualinherited

Reimplemented in SHAPE_POLY_SET, and SHAPE_COMPOUND.

Definition at line 104 of file shape.h.

104 { return 0; }

◆ GetIndexableSubshapes()

virtual void SHAPE_BASE::GetIndexableSubshapes ( std::vector< SHAPE * > &  aSubshapes)
inlinevirtualinherited

Reimplemented in SHAPE_POLY_SET, and SHAPE_COMPOUND.

Definition at line 106 of file shape.h.

106 { }

Referenced by SHAPE_COMPOUND::AddShape(), and ROUTER_PREVIEW_ITEM::ViewDraw().

◆ GetPoint()

virtual const VECTOR2I SHAPE_LINE_CHAIN::GetPoint ( int  aIndex) const
inlineoverridevirtual

Implements SHAPE_LINE_CHAIN_BASE.

Definition at line 764 of file shape_line_chain.h.

764 { return CPoint(aIndex); }
const VECTOR2I & CPoint(int aIndex) const
Function Point()

References CPoint().

Referenced by PNS::TOPOLOGY::AssembleTuningPath(), BuildFootprintPolygonOutlines(), PNS::LINE::dragCornerFree(), and CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromDrawsegments().

◆ GetPointCount()

virtual size_t SHAPE_LINE_CHAIN::GetPointCount ( ) const
inlineoverridevirtual

Implements SHAPE_LINE_CHAIN_BASE.

Definition at line 766 of file shape_line_chain.h.

766 { return PointCount(); }
int PointCount() const
Function PointCount()

References PointCount().

◆ GetSegment()

virtual const SEG SHAPE_LINE_CHAIN::GetSegment ( int  aIndex) const
inlineoverridevirtual

Implements SHAPE_LINE_CHAIN_BASE.

Definition at line 765 of file shape_line_chain.h.

765 { return CSegment(aIndex); }
const SEG CSegment(int aIndex) const
Function CSegment()

References CSegment().

Referenced by TransformArcToPolygon().

◆ GetSegmentCount()

virtual size_t SHAPE_LINE_CHAIN::GetSegmentCount ( ) const
inlineoverridevirtual

Implements SHAPE_LINE_CHAIN_BASE.

Definition at line 767 of file shape_line_chain.h.

767 { return SegmentCount(); }
int SegmentCount() const
Function SegmentCount()

References SegmentCount().

Referenced by DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run(), and TransformArcToPolygon().

◆ HasIndexableSubshapes()

virtual bool SHAPE_BASE::HasIndexableSubshapes ( ) const
inlinevirtualinherited

Reimplemented in SHAPE_POLY_SET, and SHAPE_COMPOUND.

Definition at line 99 of file shape.h.

100  {
101  return false;
102  }

Referenced by SHAPE_COMPOUND::AddShape(), and ROUTER_PREVIEW_ITEM::ViewDraw().

◆ Insert() [1/2]

void SHAPE_LINE_CHAIN::Insert ( size_t  aVertex,
const VECTOR2I aP 
)

Definition at line 676 of file shape_line_chain.cpp.

677 {
678  if( aVertex < m_points.size() && m_shapes[aVertex] != SHAPE_IS_PT )
679  convertArc( aVertex );
680 
681  m_points.insert( m_points.begin() + aVertex, aP );
682  m_shapes.insert( m_shapes.begin() + aVertex, ssize_t( SHAPE_IS_PT ) );
683 
684  assert( m_shapes.size() == m_points.size() );
685 }
void convertArc(ssize_t aArcIndex)
Converts an arc to only a point chain by removing the arc and references.
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References convertArc(), m_points, m_shapes, and SHAPE_IS_PT.

Referenced by PNS::TOPOLOGY::AssembleTuningPath(), PNS::LINE::dragCorner45(), and PNS::LINE::dragCornerFree().

◆ Insert() [2/2]

void SHAPE_LINE_CHAIN::Insert ( size_t  aVertex,
const SHAPE_ARC aArc 
)

Step 1: Find the position for the new arc in the existing arc vector

Step 2: Add the arc polyline points to the chain

Step 3: Add the vector of indices to the shape vector

Definition at line 688 of file shape_line_chain.cpp.

689 {
690  if( m_shapes[aVertex] != SHAPE_IS_PT )
691  convertArc( aVertex );
692 
694  size_t arc_pos = m_arcs.size();
695 
696  for( auto arc_it = m_shapes.rbegin() ;
697  arc_it != m_shapes.rend() + aVertex;
698  arc_it++ )
699  {
700  if( *arc_it != SHAPE_IS_PT )
701  arc_pos = ( *arc_it )++;
702  }
703 
704  m_arcs.insert( m_arcs.begin() + arc_pos, aArc );
705 
707  auto& chain = aArc.ConvertToPolyline();
708  m_points.insert( m_points.begin() + aVertex,
709  chain.CPoints().begin(), chain.CPoints().end() );
710 
712  std::vector<size_t> new_points( chain.PointCount(), arc_pos );
713  m_shapes.insert( m_shapes.begin() + aVertex, new_points.begin(), new_points.end() );
714  assert( m_shapes.size() == m_points.size() );
715 }
void convertArc(ssize_t aArcIndex)
Converts an arc to only a point chain by removing the arc and references.
std::vector< SHAPE_ARC > m_arcs
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=0.005 *PCB_IU_PER_MM) const
Constructs a SHAPE_LINE_CHAIN of segments from a given arc.
Definition: shape_arc.cpp:408
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References convertArc(), SHAPE_ARC::ConvertToPolyline(), m_arcs, m_points, m_shapes, and SHAPE_IS_PT.

◆ Intersect() [1/2]

int SHAPE_LINE_CHAIN::Intersect ( const SEG aSeg,
INTERSECTIONS aIp 
) const

Function Intersect()

Finds all intersection points between our line chain and the segment aSeg.

Parameters
aSegthe segment chain to find intersections with
aIpreference to a vector to store found intersections. Intersection points are sorted with increasing distances from point aSeg.a.
Returns
number of intersections found

Definition at line 733 of file shape_line_chain.cpp.

734 {
735  for( int s = 0; s < SegmentCount(); s++ )
736  {
737  OPT_VECTOR2I p = CSegment( s ).Intersect( aSeg );
738 
739  if( p )
740  {
741  INTERSECTION is;
742  is.our = CSegment( s );
743  is.their = aSeg;
744  is.p = *p;
745  aIp.push_back( is );
746  }
747  }
748 
749  compareOriginDistance comp( aSeg.A );
750  sort( aIp.begin(), aIp.end(), comp );
751 
752  return aIp.size();
753 }
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
Definition: seg.cpp:119
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
int SegmentCount() const
Function SegmentCount()
const SEG CSegment(int aIndex) const
Function CSegment()
VECTOR2I A
Definition: seg.h:49

References SEG::A, CSegment(), SEG::Intersect(), SHAPE_LINE_CHAIN::INTERSECTION::our, SHAPE_LINE_CHAIN::INTERSECTION::p, SegmentCount(), and SHAPE_LINE_CHAIN::INTERSECTION::their.

Referenced by PNS::OPTIMIZER::customBreakouts(), CN_ITEM::GetAnchor(), PNS::LINE_PLACER::handleSelfIntersections(), Intersects(), CADSTAR_SCH_ARCHIVE_LOADER::loadNets(), PNS::NODE::NearestObstacle(), POLYGON_GEOM_MANAGER::updateLeaderPoints(), PNS::LINE::Walkaround(), and walkaround2().

◆ Intersect() [2/2]

int SHAPE_LINE_CHAIN::Intersect ( const SHAPE_LINE_CHAIN aChain,
INTERSECTIONS aIp 
) const

Function Intersect()

Finds all intersection points between our line chain and the line chain aChain.

Parameters
aChainthe line chain to find intersections with
aIpreference to a vector to store found intersections. Intersection points are sorted with increasing path lengths from the starting point of aChain.
Returns
number of intersections found

Definition at line 774 of file shape_line_chain.cpp.

775 {
776  BOX2I bb_other = aChain.BBox();
777 
778  for( int s1 = 0; s1 < SegmentCount(); s1++ )
779  {
780  const SEG& a = CSegment( s1 );
781  const BOX2I bb_cur( a.A, a.B - a.A );
782 
783  if( !bb_other.Intersects( bb_cur ) )
784  continue;
785 
786  for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ )
787  {
788  const SEG& b = aChain.CSegment( s2 );
789  INTERSECTION is;
790 
791  if( a.Collinear( b ) )
792  {
793  is.our = a;
794  is.their = b;
795 
796  if( a.Contains( b.A ) ) { is.p = b.A; addIntersection(aIp, PointCount(), is); }
797  if( a.Contains( b.B ) ) { is.p = b.B; addIntersection(aIp, PointCount(), is); }
798  if( b.Contains( a.A ) ) { is.p = a.A; addIntersection(aIp, PointCount(), is); }
799  if( b.Contains( a.B ) ) { is.p = a.B; addIntersection(aIp, PointCount(), is); }
800  }
801  else
802  {
803  OPT_VECTOR2I p = a.Intersect( b );
804 
805  if( p )
806  {
807  is.p = *p;
808  is.our = a;
809  is.their = b;
810  addIntersection(aIp, PointCount(), is);
811  }
812  }
813  }
814  }
815 
816  return aIp.size();
817 }
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
Definition: seg.cpp:119
int PointCount() const
Function PointCount()
BOX2 handles a 2-D bounding box, built on top of an origin point and size vector, both of templated c...
Definition: box2.h:43
bool Intersects(const BOX2< Vec > &aRect) const
Function Intersects.
Definition: box2.h:236
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
int SegmentCount() const
Function SegmentCount()
bool Collinear(const SEG &aSeg) const
Check if segment aSeg lies on the same line as (this).
Definition: seg.h:273
Definition: seg.h:41
const SEG CSegment(int aIndex) const
Function CSegment()
VECTOR2I A
Definition: seg.h:49
static void addIntersection(SHAPE_LINE_CHAIN::INTERSECTIONS &aIps, int aPc, const SHAPE_LINE_CHAIN::INTERSECTION &aP)
bool Contains(const SEG &aSeg) const
Definition: seg.h:336
VECTOR2I B
Definition: seg.h:50

References SEG::A, addIntersection(), SEG::B, BBox(), SEG::Collinear(), SEG::Contains(), CSegment(), SEG::Intersect(), BOX2< Vec >::Intersects(), SHAPE_LINE_CHAIN::INTERSECTION::our, SHAPE_LINE_CHAIN::INTERSECTION::p, PointCount(), SegmentCount(), and SHAPE_LINE_CHAIN::INTERSECTION::their.

◆ Intersects()

bool SHAPE_LINE_CHAIN::Intersects ( const SHAPE_LINE_CHAIN aChain) const

Definition at line 1231 of file shape_line_chain.cpp.

1232 {
1234  return Intersect( aChain, dummy ) != 0;
1235 }
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Function Intersect()
std::vector< INTERSECTION > INTERSECTIONS
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Definition: sch_symbol.cpp:69

References dummy(), and Intersect().

Referenced by PNS::DIFF_PAIR::BuildInitial().

◆ isArc()

bool SHAPE_LINE_CHAIN::isArc ( size_t  aSegment) const
inline

A segment is part of an arc except in the special case of two arcs next to each other but without a shared vertex. Here there is a segment between the end of the first arc and the start of the second arc.

Definition at line 752 of file shape_line_chain.h.

753  {
759  return ( aSegment < m_shapes.size() - 1
760  && m_shapes[aSegment] != SHAPE_IS_PT
761  && m_shapes[aSegment] == m_shapes[aSegment + 1] );
762  }
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References m_shapes, and SHAPE_IS_PT.

Referenced by PNS::LINE::Is45Degree(), and PNS::OPTIMIZER::mergeStep().

◆ IsClosed()

bool SHAPE_LINE_CHAIN::IsClosed ( ) const
inlineoverridevirtual

Function IsClosed()

Returns
aClosed: true, when our line is closed.

Implements SHAPE_LINE_CHAIN_BASE.

Definition at line 197 of file shape_line_chain.h.

198  {
199  return m_closed;
200  }
bool m_closed
is the line chain closed?

References m_closed.

Referenced by SHAPE_POLY_SET::AddOutline(), ZONE::AddPolygon(), BuildFootprintPolygonOutlines(), KIGFX::CAIRO_GAL_BASE::drawPoly(), KIGFX::OPENGL_GAL::DrawPolyline(), PLOTTER::PlotPoly(), PNS::pointInside2(), and SelfIntersecting().

◆ IsNull()

bool SHAPE::IsNull ( ) const
inlineinherited

Return true if the shape is a null shape.

Return values
trueif null :-)

Definition at line 150 of file shape.h.

151  {
152  return m_type == SH_NULL;
153  }
SHAPE_TYPE m_type
< type of our shape
Definition: shape.h:110
empty shape (no shape...),
Definition: shape.h:51

References SHAPE_BASE::m_type, and SH_NULL.

◆ IsSolid()

bool SHAPE_LINE_CHAIN::IsSolid ( ) const
inlineoverridevirtual

Implements SHAPE.

Definition at line 725 of file shape_line_chain.h.

726  {
727  return false;
728  }

◆ Length()

long long int SHAPE_LINE_CHAIN::Length ( ) const

Function Length()

Returns length of the line chain in Euclidean metric.

Returns
length of the line chain

Definition at line 232 of file shape_line_chain.cpp.

233 {
234  long long int l = 0;
235 
236  for( int i = 0; i < SegmentCount(); i++ )
237  l += CSegment( i ).Length();
238 
239  return l;
240 }
int Length() const
Return the length (this).
Definition: seg.h:355
int SegmentCount() const
Function SegmentCount()
const SEG CSegment(int aIndex) const
Function CSegment()

References CSegment(), SEG::Length(), and SegmentCount().

Referenced by PNS::COST_ESTIMATOR::Add(), PNS::LINE::dragSegment45(), PNS::OPTIMIZER::fanoutCleanup(), PNS::MEANDER_SHAPE::MaxTunableLength(), PNS::SHOVE::onCollidingArc(), PNS::SHOVE::onCollidingSegment(), PNS::COST_ESTIMATOR::Remove(), PNS::COST_ESTIMATOR::Replace(), PNS::LINE_PLACER::rhWalkOnly(), PNS::WALKAROUND::Route(), PNS::SHOVE::shoveLineFromLoneVia(), PNS::WALKAROUND::singleStep(), PNS::DIFF_PAIR::Skew(), PNS::DIFF_PAIR::TotalLength(), and PNS::DRAGGER::tryWalkaround().

◆ Mirror() [1/2]

void SHAPE_LINE_CHAIN::Mirror ( bool  aX = true,
bool  aY = false,
const VECTOR2I aRef = { 0, 0 } 
)

Mirrors the line points about y or x (or both)

Parameters
aXIf true, mirror about the y axis (flip X coordinate)
aYIf true, mirror about the x axis (flip Y coordinate)
aRefsets the reference point about which to mirror

Definition at line 243 of file shape_line_chain.cpp.

244 {
245  for( auto& pt : m_points )
246  {
247  if( aX )
248  pt.x = -pt.x + 2 * aRef.x;
249 
250  if( aY )
251  pt.y = -pt.y + 2 * aRef.y;
252  }
253 
254  for( auto& arc : m_arcs )
255  arc.Mirror( aX, aY, aRef );
256 }
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices

References m_arcs, m_points, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by PNS::MEANDER_SHAPE::genMeanderShape().

◆ Mirror() [2/2]

void SHAPE_LINE_CHAIN::Mirror ( const SEG axis)

Mirrors the line points using an given axis.

Parameters
axisAxis on which to mirror

Definition at line 259 of file shape_line_chain.cpp.

260 {
261  for( auto& pt : m_points )
262  pt = axis.ReflectPoint( pt );
263 
264  for( auto& arc : m_arcs )
265  arc.Mirror( axis );
266 }
const VECTOR2I ReflectPoint(const VECTOR2I &aP) const
Reflect a point using this segment as axis.
Definition: seg.h:458
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices

References m_arcs, m_points, and SEG::ReflectPoint().

◆ Move()

void SHAPE_LINE_CHAIN::Move ( const VECTOR2I aVector)
inlineoverridevirtual

Implements SHAPE.

Definition at line 694 of file shape_line_chain.h.

695  {
696  for( auto& pt : m_points )
697  pt += aVector;
698 
699  for( auto& arc : m_arcs )
700  arc.Move( aVector );
701  }
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices

References m_arcs, and m_points.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), PAD::BuildEffectiveShapes(), ZONE_FILLER::buildThermalSpokes(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), PCB_SELECTION_TOOL::hitTestDistance(), PCB_SHAPE::MakeEffectiveShapes(), and SHAPE_SIMPLE::Move().

◆ NearestPoint() [1/2]

const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint ( const VECTOR2I aP,
bool  aAllowInternalShapePoints = true 
) const

Finds a point on the line chain that is closest to point aP.

Parameters
aPis the point to find
aAllowInternalShapePointsif false will not return points internal to an arc (i.e. only the arc endpoints are possible candidates)
Returns
the nearest point.

Definition at line 1098 of file shape_line_chain.cpp.

1100 {
1101  int min_d = INT_MAX;
1102  int nearest = 0;
1103 
1104  for( int i = 0; i < SegmentCount(); i++ )
1105  {
1106  int d = CSegment( i ).Distance( aP );
1107 
1108  bool isInternalShapePoint = false;
1109 
1110  // An internal shape point here is everything after the start of an arc and before the
1111  // second-to-last vertex of the arc, because we are looking at segments here!
1112  if( i > 0 && i < SegmentCount() - 1 && m_shapes[i] >= 0 &&
1113  ( ( m_shapes[i - 1] >= 0 && m_shapes[i - 1] == m_shapes[i] ) &&
1114  ( m_shapes[i + 2] >= 0 && m_shapes[i + 2] == m_shapes[i] ) ) )
1115  {
1116  isInternalShapePoint = true;
1117  }
1118 
1119  if( ( d < min_d ) && ( aAllowInternalShapePoints || !isInternalShapePoint ) )
1120  {
1121  min_d = d;
1122  nearest = i;
1123  }
1124  }
1125 
1126  // Is this the start of an arc? If so, return it directly
1127  if( !aAllowInternalShapePoints &&
1128  ( ( nearest == 0 && m_shapes[nearest] >= 0 ) ||
1129  ( m_shapes[nearest] >= 0 && m_shapes[nearest] != m_shapes[nearest - 1] ) ) )
1130  {
1131  return m_points[nearest];
1132  }
1133  else if( !aAllowInternalShapePoints && nearest < SegmentCount() &&
1134  m_shapes[nearest] >= 0 && m_shapes[nearest + 1] == m_shapes[nearest] )
1135  {
1136  // If the nearest segment is the last of the arc, just return the arc endpoint
1137  return m_points[nearest + 1];
1138  }
1139 
1140  return CSegment( nearest ).NearestPoint( aP );
1141 }
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.h:239
std::vector< VECTOR2I > m_points
array of vertices
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.h:437
int SegmentCount() const
Function SegmentCount()
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
const SEG CSegment(int aIndex) const
Function CSegment()

References CSegment(), SEG::Distance(), m_points, m_shapes, SEG::NearestPoint(), and SegmentCount().

Referenced by PCB_GRID_HELPER::computeAnchors(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), CADSTAR_SCH_ARCHIVE_LOADER::loadBusses(), PNS::MoveDiagonal(), and PNS::DRAGGER::optimizeAndUpdateDraggedLine().

◆ NearestPoint() [2/2]

const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint ( const SEG aSeg,
int &  dist 
) const

Finds a point on the line chain that is closest to the line defined by the points of segment aSeg, also returns the distance.

Parameters
aSegSegment defining the line.
distreference receiving the distance to the nearest point.
Returns
the nearest point.

Definition at line 1144 of file shape_line_chain.cpp.

1145 {
1146  int nearest = 0;
1147 
1148  dist = INT_MAX;
1149  for( int i = 0; i < PointCount(); i++ )
1150  {
1151  int d = aSeg.LineDistance( CPoint( i ) );
1152 
1153  if( d < dist )
1154  {
1155  dist = d;
1156  nearest = i;
1157  }
1158  }
1159 
1160  return CPoint( nearest );
1161 }
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...
Definition: seg.h:420
int PointCount() const
Function PointCount()
const VECTOR2I & CPoint(int aIndex) const
Function Point()

References CPoint(), SEG::LineDistance(), and PointCount().

◆ NearestSegment()

int SHAPE_LINE_CHAIN::NearestSegment ( const VECTOR2I aP) const

Find the segment nearest the given point.

Parameters
aPpoint to compare with
Returns
the index of the segment closest to the point

Definition at line 1164 of file shape_line_chain.cpp.

1165 {
1166  int min_d = INT_MAX;
1167  int nearest = 0;
1168 
1169  for( int i = 0; i < SegmentCount(); i++ )
1170  {
1171  int d = CSegment( i ).Distance( aP );
1172 
1173  if( d < min_d )
1174  {
1175  min_d = d;
1176  nearest = i;
1177  }
1178  }
1179 
1180  return nearest;
1181 }
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.h:239
int SegmentCount() const
Function SegmentCount()
const SEG CSegment(int aIndex) const
Function CSegment()

References CSegment(), SEG::Distance(), and SegmentCount().

Referenced by SCH_SHEET_PIN::ConstrainOnEdge().

◆ NewFacet()

FACET * SHAPE::NewFacet ( )
inherited

Definition at line 705 of file wrlfacet.cpp.

706 {
707  FACET* fp = new FACET;
708  facets.push_back( fp );
709  return fp;
710 }
Definition: wrlfacet.h:41
std::list< FACET * > facets
Definition: wrlfacet.h:143

References SHAPE::facets.

Referenced by WRL1FACESET::TranslateToSG(), X3DIFACESET::TranslateToSG(), and WRL2FACESET::TranslateToSG().

◆ NextShape()

int SHAPE_LINE_CHAIN::NextShape ( int  aPointIndex,
bool  aForwards = true 
) const

Returns the vertex index of the next shape in the chain, or -1 if aPoint is in the last shape If aPoint is the start of a segment, this will be ( aPoint + 1 ).

If aPoint is part of an arc, this will be the index of the start of the next shape after the arc, in other words, the last point of the arc.

Parameters
aPointIndexis a vertex in the chain
aForwardsis true if the next shape is desired, false for previous shape
Returns
the vertex index of the start of the next shape after aPoint's shape

Definition at line 515 of file shape_line_chain.cpp.

516 {
517  if( aPointIndex < 0 )
518  aPointIndex += PointCount();
519 
520  // First or last point?
521  if( ( aForwards && aPointIndex == PointCount() - 1 ) ||
522  ( !aForwards && aPointIndex == 0 ) )
523  {
524  return -1;
525  }
526 
527  int delta = aForwards ? 1 : -1;
528 
529  if( m_shapes[aPointIndex] == SHAPE_IS_PT )
530  return aPointIndex + delta;
531 
532  int arcIndex = m_shapes[aPointIndex];
533  int arcStart = aPointIndex;
534 
535  while( aPointIndex < static_cast<int>( m_shapes.size() ) && m_shapes[aPointIndex] == arcIndex )
536  aPointIndex += delta;
537 
538  // We want the last vertex of the arc if the initial point was the start of one
539  // Well-formed arcs should generate more than one point to travel above
540  if( aPointIndex - arcStart > 1 )
541  aPointIndex -= delta;
542 
543  return aPointIndex;
544 }
int PointCount() const
Function PointCount()
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References m_shapes, PointCount(), and SHAPE_IS_PT.

Referenced by PrevShape().

◆ operator!=()

bool SHAPE_LINE_CHAIN::operator!= ( const SHAPE_LINE_CHAIN aRhs) const
inline

Definition at line 678 of file shape_line_chain.h.

679  {
680  if( PointCount() != aRhs.PointCount() )
681  return true;
682 
683  for( int i = 0; i < PointCount(); i++ )
684  {
685  if( CPoint( i ) != aRhs.CPoint( i ) )
686  return true;
687  }
688 
689  return false;
690  }
int PointCount() const
Function PointCount()
const VECTOR2I & CPoint(int aIndex) const
Function Point()

References CPoint(), and PointCount().

◆ operator=()

SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::operator= ( const SHAPE_LINE_CHAIN )
default

◆ Parse()

bool SHAPE_LINE_CHAIN::Parse ( std::stringstream &  aStream)
overridevirtual

Reimplemented from SHAPE.

Definition at line 1243 of file shape_line_chain.cpp.

1244 {
1245  size_t n_pts;
1246  size_t n_arcs;
1247 
1248  m_points.clear();
1249  aStream >> n_pts;
1250 
1251  // Rough sanity check, just make sure the loop bounds aren't absolutely outlandish
1252  if( n_pts > aStream.str().size() )
1253  return false;
1254 
1255  aStream >> m_closed;
1256  aStream >> n_arcs;
1257 
1258  if( n_arcs > aStream.str().size() )
1259  return false;
1260 
1261  for( size_t i = 0; i < n_pts; i++ )
1262  {
1263  int x, y;
1264  ssize_t ind;
1265  aStream >> x;
1266  aStream >> y;
1267  m_points.emplace_back( x, y );
1268 
1269  aStream >> ind;
1270  m_shapes.push_back( ind );
1271  }
1272 
1273  for( size_t i = 0; i < n_arcs; i++ )
1274  {
1275  VECTOR2I p0, pc;
1276  double angle;
1277 
1278  aStream >> pc.x;
1279  aStream >> pc.y;
1280  aStream >> p0.x;
1281  aStream >> p0.y;
1282  aStream >> angle;
1283 
1284  m_arcs.emplace_back( pc, p0, angle );
1285  }
1286 
1287  return true;
1288 }
Define a general 2D-vector/point.
Definition: vector2d.h:61
std::vector< SHAPE_ARC > m_arcs
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References PNS::angle(), m_arcs, m_closed, m_points, m_shapes, VECTOR2< T >::x, and VECTOR2< T >::y.

◆ PathLength()

int SHAPE_LINE_CHAIN::PathLength ( const VECTOR2I aP) const

Function PathLength()

Computes the walk path length from the beginning of the line chain and the point aP belonging to our line.

Returns
: path length in Euclidean metric or -1 if aP does not belong to the line chain.

Definition at line 820 of file shape_line_chain.cpp.

821 {
822  int sum = 0;
823 
824  for( int i = 0; i < SegmentCount(); i++ )
825  {
826  const SEG seg = CSegment( i );
827  int d = seg.Distance( aP );
828 
829  if( d <= 1 )
830  {
831  sum += ( aP - seg.A ).EuclideanNorm();
832  return sum;
833  }
834  else
835  sum += seg.Length();
836  }
837 
838  return -1;
839 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148
int Length() const
Return the length (this).
Definition: seg.h:355
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.h:239
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
const SEG CSegment(int aIndex) const
Function CSegment()
VECTOR2I A
Definition: seg.h:49

References SEG::A, CSegment(), SEG::Distance(), EuclideanNorm(), SEG::Length(), and SegmentCount().

Referenced by PNS::NODE::NearestObstacle().

◆ PointAlong()

const VECTOR2I SHAPE_LINE_CHAIN::PointAlong ( int  aPathLength) const

Definition at line 1291 of file shape_line_chain.cpp.

1292 {
1293  int total = 0;
1294 
1295  if( aPathLength == 0 )
1296  return CPoint( 0 );
1297 
1298  for( int i = 0; i < SegmentCount(); i++ )
1299  {
1300  const SEG& s = CSegment( i );
1301  int l = s.Length();
1302 
1303  if( total + l >= aPathLength )
1304  {
1305  VECTOR2I d( s.B - s.A );
1306  return s.A + d.Resize( aPathLength - total );
1307  }
1308 
1309  total += l;
1310  }
1311 
1312  return CPoint( -1 );
1313 }
int Length() const
Return the length (this).
Definition: seg.h:355
Define a general 2D-vector/point.
Definition: vector2d.h:61
const VECTOR2I & CPoint(int aIndex) const
Function Point()
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:404
const SEG CSegment(int aIndex) const
Function CSegment()
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50

References SEG::A, SEG::B, CPoint(), CSegment(), SEG::Length(), VECTOR2< T >::Resize(), and SegmentCount().

◆ PointCount()

int SHAPE_LINE_CHAIN::PointCount ( ) const
inline

Function PointCount()

Returns the number of points (vertices) in this line chain

Returns
number of points

Definition at line 248 of file shape_line_chain.h.

249  {
250  return m_points.size();
251  }
std::vector< VECTOR2I > m_points
array of vertices

References m_points.

Referenced by POLYGON_GEOM_MANAGER::AddPoint(), SHAPE_LINE_CHAIN::POINT_INSIDE_TRACKER::AddPolyline(), BOARD_ADAPTER::addSolidAreasShapes(), TRIANGLE_DISPLAY_LIST::AddToMiddleContourns(), CN_ZONE_LAYER::AnchorCount(), Append(), PNS::LINE::AppendVia(), ArePolylineEndPointsNearCircle(), ArePolylineMidPointsNearCircle(), PNS::NODE::AssembleLine(), PNS::TOPOLOGY::AssembleTuningPath(), BOOST_AUTO_TEST_CASE(), BuildConvexHull(), PAD::BuildEffectivePolygon(), PAD::BuildEffectiveShapes(), PCB_SHAPE::BuildPolyPointsList(), PNS::LINE::ChangedArea(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), CheckClearance(), CN_VISITOR::checkZoneZoneConnection(), CLastPoint(), PNS::LINE::ClipVertexRange(), convertToClipper(), PNS::coupledBypass(), CPoint(), PolygonTriangulation::createList(), CreatePadsShapesSection(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), POLYGON_GEOM_MANAGER::DeleteLastCorner(), DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate(), PNS::dragCornerInternal(), PNS::LINE::dragSegment45(), KIGFX::GERBVIEW_PAINTER::draw(), APERTURE_MACRO::DrawApertureMacroShape(), KIGFX::CAIRO_GAL_BASE::drawPoly(), KIGFX::OPENGL_GAL::DrawPolygon(), KIGFX::OPENGL_GAL::DrawPolyline(), KIGFX::PREVIEW::POLYGON_ITEM::drawPreviewShape(), EXPORTER_PCB_VRML::ExportVrmlBoard(), EXPORTER_PCB_VRML::ExportVrmlPolygonSet(), DSN::SPECCTRA_DB::fillBOUNDARY(), AR_AUTOPLACER::fillMatrix(), Find(), PNS::LINE_PLACER::FixRoute(), GERBER_PLOTTER::FlashPadChamferRoundRect(), PSLIKE_PLOTTER::FlashPadCustom(), DXF_PLOTTER::FlashPadCustom(), HPGL_PLOTTER::FlashPadCustom(), GERBER_PLOTTER::FlashPadCustom(), PSLIKE_PLOTTER::FlashPadRoundRect(), DXF_PLOTTER::FlashPadRoundRect(), HPGL_PLOTTER::FlashPadRoundRect(), GERBER_PLOTTER::FlashPadRoundRect(), PCB_IO::format(), Format(), CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromDrawsegments(), SHAPE_SIMPLE::GetPointCount(), GetPointCount(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), SHAPE_POLY_SET::GetRelativeIndices(), PNS::MOUSE_TRAIL_TRACER::GetTrailLeadVector(), PNS::LINE_PLACER::handlePullback(), PNS::LINE_PLACER::handleSelfIntersections(), DS_DRAW_ITEM_POLYPOLYGONS::HitTest(), Intersect(), POLYGON_GEOM_MANAGER::IsPolygonInProgress(), PCB_SHAPE::IsPolyShapeValid(), POLYGON_GEOM_MANAGER::IsSelfIntersecting(), FABMASTER::loadFootprints(), FABMASTER::loadGraphics(), FABMASTER::loadPolygon(), FABMASTER::loadZone(), DSN::SPECCTRA_DB::makePADSTACK(), PNS::LINE_PLACER::mergeHead(), PNS::OPTIMIZER::mergeObtuse(), NearestPoint(), POLYGON_GEOM_MANAGER::NewPointClosesOutline(), NextShape(), operator!=(), BOOST_TEST_PRINT_NAMESPACE_OPEN::print_log_value< SHAPE_LINE_CHAIN >::operator()(), PNS::LINE_PLACER::optimizeTailHeadTransition(), BITMAPCONV_INFO::outputOnePolygon(), ALTIUM_PCB::ParsePolygons6Data(), ALTIUM_PCB::ParseShapeBasedRegions6Data(), PlotDrawingSheet(), BRDITEMS_PLOTTER::PlotFilledAreas(), PLOTTER::PlotPoly(), SHAPE_SIMPLE::PointCount(), PNS::LINE::PointCount(), PNS::pointInside2(), polygon_Convert(), GERBER_DRAW_ITEM::PrintGerberPoly(), DS_DRAW_ITEM_POLYPOLYGONS::PrintWsItem(), Remove(), RemoveShape(), Replace(), PNS::OPTIMIZER::runSmartPads(), SetPoint(), KIGFX::PREVIEW::POLYGON_ITEM::SetPoints(), PNS::shovedArea(), PNS::SHOVE::shoveLineFromLoneVia(), PNS::SHOVE::shoveLineToHullSet(), Simplify(), Slice(), Split(), POLYGON_GEOM_MANAGER::updateLeaderPoints(), PNS::LINE::Walkaround(), walkaround2(), HYPERLYNX_EXPORTER::writeNetObjects(), GBR_TO_PCB_EXPORTER::writePcbPolygon(), and GBR_TO_PCB_EXPORTER::writePcbZoneItem().

◆ PointInside()

bool SHAPE_LINE_CHAIN_BASE::PointInside ( const VECTOR2I aPt,
int  aAccuracy = 0,
bool  aUseBBoxCache = false 
) const
inherited

Check if point aP lies inside a polygon (any type) defined by the line chain.

For closed shapes only.

Parameters
aPtpoint to check
aUseBBoxCachegives better peformance if the bounding box caches have been generated.
Returns
true if the point is inside the shape (edge is not treated as being inside).

To check for interior points, we draw a line in the positive x direction from the point. If it intersects an even number of segments, the point is outside the line chain (it had to first enter and then exit). Otherwise, it is inside the chain.

Note: slope might be denormal here in the case of a horizontal line but we require our y to move from above to below the point (or vice versa)

Note: we open-code CPoint() here so that we don't end up calculating the size of the vector number-of-points times. This has a non-trivial impact on zone fill times.

Definition at line 842 of file shape_line_chain.cpp.

844 {
845  /*
846  * Don't check the bounding box unless it's cached. Building it is about the same speed as
847  * the rigorous test below and so just slows things down by doing potentially two tests.
848  */
849  //if( aUseBBoxCache && !m_bbox.Contains( aPt ) )
850  //return false;
851 
852  // fixme: bbox cache...
853 
854  if( !IsClosed() || GetPointCount() < 3 )
855  return false;
856 
857  bool inside = false;
858 
870  int pointCount = GetPointCount();
871 
872  for( int i = 0; i < pointCount; )
873  {
874  const auto p1 = GetPoint( i++ );
875  const auto p2 = GetPoint( i == pointCount ? 0 : i );
876  const auto diff = p2 - p1;
877 
878  if( diff.y != 0 )
879  {
880  const int d = rescale( diff.x, ( aPt.y - p1.y ), diff.y );
881 
882  if( ( ( p1.y > aPt.y ) != ( p2.y > aPt.y ) ) && ( aPt.x - p1.x < d ) )
883  inside = !inside;
884  }
885  }
886 
887  // If accuracy is <= 1 (nm) then we skip the accuracy test for performance. Otherwise
888  // we use "OnEdge(accuracy)" as a proxy for "Inside(accuracy)".
889  if( aAccuracy <= 1 )
890  return inside;
891  else
892  return inside || PointOnEdge( aPt, aAccuracy );
893 }
virtual bool IsClosed() const =0
virtual size_t GetPointCount() const =0
bool PointOnEdge(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of the line chain.
T rescale(T aNumerator, T aValue, T aDenominator)
Function rescale()
Definition: util.h:95
virtual const VECTOR2I GetPoint(int aIndex) const =0

References SHAPE_LINE_CHAIN_BASE::GetPoint(), SHAPE_LINE_CHAIN_BASE::GetPointCount(), SHAPE_LINE_CHAIN_BASE::IsClosed(), SHAPE_LINE_CHAIN_BASE::PointOnEdge(), rescale(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Collide(), SHAPE_LINE_CHAIN_BASE::Collide(), POLY_GRID_PARTITION::containsPoint(), SHAPE_POLY_SET::containsSingle(), LIB_POLYLINE::HitTest(), ZONE::HitTestCutout(), MARKER_BASE::HitTestMarker(), SHAPE_LINE_CHAIN_BASE::SquaredDistance(), PNS::LINE::Walkaround(), and walkaround2().

◆ PointOnEdge()

bool SHAPE_LINE_CHAIN_BASE::PointOnEdge ( const VECTOR2I aP,
int  aAccuracy = 0 
) const
inherited

Check if point aP lies on an edge or vertex of the line chain.

Parameters
aPpoint to check
Returns
true if the point lies on the edge.

Definition at line 896 of file shape_line_chain.cpp.

897 {
898  return EdgeContainingPoint( aPt, aAccuracy ) >= 0;
899 }
int EdgeContainingPoint(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of the line chain.

References SHAPE_LINE_CHAIN_BASE::EdgeContainingPoint().

Referenced by LIB_POLYLINE::HitTest(), FABMASTER::loadZones(), SHAPE_LINE_CHAIN_BASE::PointInside(), PNS::LINE::Walkaround(), and walkaround2().

◆ PrevShape()

int SHAPE_LINE_CHAIN::PrevShape ( int  aPointIndex) const
inline

Definition at line 302 of file shape_line_chain.h.

303  {
304  return NextShape( aPointIndex, false );
305  }
int NextShape(int aPointIndex, bool aForwards=true) const
Returns the vertex index of the next shape in the chain, or -1 if aPoint is in the last shape If aPoi...

References NextShape().

Referenced by PNS::LINE_PLACER::handlePullback().

◆ Remove() [1/2]

void SHAPE_LINE_CHAIN::Remove ( int  aStartIndex,
int  aEndIndex 
)

Function Remove()

Removes the range of points [start_index, end_index] from the line chain.

Parameters
aStartIndexstart of the point range to be replaced (inclusive)
aEndIndexend of the point range to be replaced (inclusive)

Definition at line 360 of file shape_line_chain.cpp.

361 {
362  assert( m_shapes.size() == m_points.size() );
363 
364  if( aEndIndex < 0 )
365  aEndIndex += PointCount();
366 
367  if( aStartIndex < 0 )
368  aStartIndex += PointCount();
369 
370  if( aStartIndex >= PointCount() )
371  return;
372 
373  aEndIndex = std::min( aEndIndex, PointCount() );
374  std::set<size_t> extra_arcs;
375 
376  // Remove any overlapping arcs in the point range
377  for( int i = aStartIndex; i < aEndIndex; i++ )
378  {
379  if( m_shapes[i] != SHAPE_IS_PT )
380  extra_arcs.insert( m_shapes[i] );
381  }
382 
383  for( auto arc : extra_arcs )
384  convertArc( arc );
385 
386  m_shapes.erase( m_shapes.begin() + aStartIndex, m_shapes.begin() + aEndIndex + 1 );
387  m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 );
388  assert( m_shapes.size() == m_points.size() );
389 }
void convertArc(ssize_t aArcIndex)
Converts an arc to only a point chain by removing the arc and references.
int PointCount() const
Function PointCount()
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References convertArc(), m_points, m_shapes, PointCount(), and SHAPE_IS_PT.

Referenced by POLYGON_GEOM_MANAGER::AddPoint(), PNS::TOPOLOGY::AssembleTuningPath(), PNS::LINE_PLACER::buildInitialLine(), PNS::LINE::ClipToNearestObstacle(), POLYGON_GEOM_MANAGER::DeleteLastCorner(), PNS::DIFF_PAIR_PLACER::FixRoute(), PNS::LINE_PLACER::handleSelfIntersections(), PNS::OPTIMIZER::mergeColinear(), PNS::LINE_PLACER::mergeHead(), PNS::LINE_PLACER::reduceTail(), Remove(), RemoveShape(), Replace(), and PNS::WALKAROUND::Route().

◆ Remove() [2/2]

void SHAPE_LINE_CHAIN::Remove ( int  aIndex)
inline

Function Remove() removes the aIndex-th point from the line chain.

Parameters
aIndexis the index of the point to be removed.

Definition at line 508 of file shape_line_chain.h.

509  {
510  Remove( aIndex, aIndex );
511  }
void Remove(int aStartIndex, int aEndIndex)
Function Remove()

References Remove().

◆ RemoveShape()

void SHAPE_LINE_CHAIN::RemoveShape ( int  aPointIndex)

Removes the shape at the given index from the line chain.

If the given index is inside an arc, the entire arc will be removed. Otherwise this is equivalent to Remove( aPointIndex ).

Parameters
aPointIndexis the index of the point to remove

Definition at line 547 of file shape_line_chain.cpp.

548 {
549  if( aPointIndex < 0 )
550  aPointIndex += PointCount();
551 
552  if( m_shapes[aPointIndex] == SHAPE_IS_PT )
553  {
554  Remove( aPointIndex );
555  return;
556  }
557 
558  int start = aPointIndex;
559  int end = aPointIndex;
560  int arcIdx = m_shapes[aPointIndex];
561 
562  while( start >= 0 && m_shapes[start] == arcIdx )
563  start--;
564 
565  while( end < static_cast<int>( m_shapes.size() ) - 1 && m_shapes[end] == arcIdx )
566  end++;
567 
568  Remove( start, end );
569 }
int PointCount() const
Function PointCount()
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References m_shapes, PointCount(), Remove(), and SHAPE_IS_PT.

Referenced by PNS::LINE_PLACER::handlePullback().

◆ Replace() [1/2]

void SHAPE_LINE_CHAIN::Replace ( int  aStartIndex,
int  aEndIndex,
const VECTOR2I aP 
)

Function Replace()

Replaces points with indices in range [start_index, end_index] with a single point aP.

Parameters
aStartIndexstart of the point range to be replaced (inclusive)
aEndIndexend of the point range to be replaced (inclusive)
aPreplacement point

Definition at line 269 of file shape_line_chain.cpp.

270 {
271  if( aEndIndex < 0 )
272  aEndIndex += PointCount();
273 
274  if( aStartIndex < 0 )
275  aStartIndex += PointCount();
276 
277  aEndIndex = std::min( aEndIndex, PointCount() - 1 );
278 
279  // N.B. This works because convertArc changes m_shapes on the first run
280  for( int ind = aStartIndex; ind <= aEndIndex; ind++ )
281  {
282  if( m_shapes[ind] != SHAPE_IS_PT )
283  convertArc( ind );
284  }
285 
286  if( aStartIndex == aEndIndex )
287  m_points[aStartIndex] = aP;
288  else
289  {
290  m_points.erase( m_points.begin() + aStartIndex + 1, m_points.begin() + aEndIndex + 1 );
291  m_points[aStartIndex] = aP;
292 
293  m_shapes.erase( m_shapes.begin() + aStartIndex + 1, m_shapes.begin() + aEndIndex + 1 );
294  }
295 
296  assert( m_shapes.size() == m_points.size() );
297 }
void convertArc(ssize_t aArcIndex)
Converts an arc to only a point chain by removing the arc and references.
int PointCount() const
Function PointCount()
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References convertArc(), m_points, m_shapes, PointCount(), and SHAPE_IS_PT.

Referenced by PNS::TOPOLOGY::AssembleTuningPath(), PNS::coupledBypass(), PNS::LINE::dragSegment45(), CADSTAR_SCH_ARCHIVE_LOADER::loadNets(), PNS::OPTIMIZER::mergeDpStep(), PNS::OPTIMIZER::mergeObtuse(), PNS::LINE_PLACER::optimizeTailHeadTransition(), and PNS::Tighten().

◆ Replace() [2/2]

void SHAPE_LINE_CHAIN::Replace ( int  aStartIndex,
int  aEndIndex,
const SHAPE_LINE_CHAIN aLine 
)

Function Replace()

Replaces points with indices in range [start_index, end_index] with the points from line chain aLine.

Parameters
aStartIndexstart of the point range to be replaced (inclusive)
aEndIndexend of the point range to be replaced (inclusive)
aLinereplacement line chain.

Definition at line 300 of file shape_line_chain.cpp.

301 {
302  if( aEndIndex < 0 )
303  aEndIndex += PointCount();
304 
305  if( aStartIndex < 0 )
306  aStartIndex += PointCount();
307 
308  // We only process lines in order in this house
309  wxASSERT( aStartIndex <= aEndIndex );
310  wxASSERT( aEndIndex < m_points.size() );
311 
312  SHAPE_LINE_CHAIN newLine = aLine;
313 
314  // It's possible that the start or end lands on the end of an arc. If so, we'd better have a
315  // replacement line that matches up to the same coordinates, as we can't break the arc(s).
316  ssize_t startShape = m_shapes[aStartIndex];
317  ssize_t endShape = m_shapes[aEndIndex];
318 
319  if( startShape >= 0 )
320  {
321  wxASSERT( !newLine.PointCount() ||
322  ( newLine.m_points.front() == m_points[aStartIndex] &&
323  aStartIndex < m_points.size() - 1 ) );
324  aStartIndex++;
325  newLine.Remove( 0 );
326  }
327 
328  if( endShape >= 0 )
329  {
330  wxASSERT( !newLine.PointCount() ||
331  ( newLine.m_points.back() == m_points[aEndIndex] && aEndIndex > 0 ) );
332  aEndIndex--;
333  newLine.Remove( -1 );
334  }
335 
336  Remove( aStartIndex, aEndIndex );
337 
338  if( !aLine.PointCount() )
339  return;
340 
341  // The total new arcs index is added to the new arc indices
342  size_t prev_arc_count = m_arcs.size();
343  std::vector<ssize_t> new_shapes = newLine.m_shapes;
344 
345  for( ssize_t& shape : new_shapes )
346  {
347  if( shape >= 0 )
348  shape += prev_arc_count;
349  }
350 
351  m_shapes.insert( m_shapes.begin() + aStartIndex, new_shapes.begin(), new_shapes.end() );
352  m_points.insert( m_points.begin() + aStartIndex, newLine.m_points.begin(),
353  newLine.m_points.end() );
354  m_arcs.insert( m_arcs.end(), newLine.m_arcs.begin(), newLine.m_arcs.end() );
355 
356  assert( m_shapes.size() == m_points.size() );
357 }
int PointCount() const
Function PointCount()
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
SHAPE_LINE_CHAIN.

References m_arcs, m_points, m_shapes, PointCount(), and Remove().

◆ Reverse()

const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Reverse ( ) const

Function Reverse()

Reverses point order in the line chain.

Returns
line chain with reversed point order (original A-B-C-D: returned D-C-B-A)

Definition at line 209 of file shape_line_chain.cpp.

210 {
211  SHAPE_LINE_CHAIN a( *this );
212 
213  reverse( a.m_points.begin(), a.m_points.end() );
214  reverse( a.m_shapes.begin(), a.m_shapes.end() );
215  reverse( a.m_arcs.begin(), a.m_arcs.end() );
216 
217  for( auto& sh : a.m_shapes )
218  {
219  if( sh != SHAPE_IS_PT )
220  sh = a.m_arcs.size() - sh - 1;
221  }
222 
223  for( SHAPE_ARC& arc : a.m_arcs )
224  arc.Reverse();
225 
226  a.m_closed = m_closed;
227 
228  return a;
229 }
bool m_closed
is the line chain closed?
void Reverse()
Definition: shape_arc.cpp:507
static constexpr ssize_t SHAPE_IS_PT
SHAPE_LINE_CHAIN.

References m_arcs, m_closed, m_points, m_shapes, SHAPE_ARC::Reverse(), and SHAPE_IS_PT.

Referenced by PNS::ArcHull(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS::SHOVE::checkShoveDirection(), PNS::coupledBypass(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::LINE::dragCorner45(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), CADSTAR_SCH_ARCHIVE_LOADER::loadNets(), PNS::DP_GATEWAY::Reverse(), PNS::LINE::Reverse(), PNS::SegmentHull(), PNS::OPTIMIZER::smartPadsSingle(), PNS::LINE::Walkaround(), and walkaround2().

◆ Rotate()

void SHAPE_LINE_CHAIN::Rotate ( double  aAngle,
const VECTOR2I aCenter = VECTOR2I( 0, 0 ) 
)
overridevirtual

Function Rotate rotates all vertices by a given angle.

Parameters
aCenteris the rotation center
aAnglerotation angle in radians

Implements SHAPE.

Definition at line 141 of file shape_line_chain.cpp.

142 {
143  for( auto& pt : m_points )
144  {
145  pt -= aCenter;
146  pt = pt.Rotate( aAngle );
147  pt += aCenter;
148  }
149 
150  for( auto& arc : m_arcs )
151  arc.Rotate( aAngle, aCenter );
152 }
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
Definition: vector2d.h:371

References m_arcs, m_points, and VECTOR2< T >::Rotate().

Referenced by PAD::BuildEffectiveShapes(), ZONE_FILLER::buildThermalSpokes(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), and PCB_SHAPE::MakeEffectiveShapes().

◆ Segment()

SEG SHAPE_LINE_CHAIN::Segment ( int  aIndex)
inline

Function Segment()

Returns a copy of the aIndex-th segment in the line chain.

Parameters
aIndexindex of the segment in the line chain. Negative values are counted from the end (i.e. -1 means the last segment in the line chain)
Returns
SEG - aIndex-th segment in the line chain

Definition at line 261 of file shape_line_chain.h.

262  {
263  if( aIndex < 0 )
264  aIndex += SegmentCount();
265 
266  if( aIndex == (int)( m_points.size() - 1 ) && m_closed )
267  return SEG( m_points[aIndex], m_points[0], aIndex );
268  else
269  return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
270  }
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41

References m_closed, m_points, and SegmentCount().

Referenced by POLY_GRID_PARTITION::build(), BuildFootprintPolygonOutlines(), POLY_GRID_PARTITION::checkClearance(), PNS::DIFF_PAIR::CoupledSegmentPairs(), BOARD_ADAPTER::createPadWithClearance(), KIGFX::PCB_PAINTER::draw(), findEndSegments(), CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices(), PCB_SHAPE::MakeEffectiveShapes(), PNS::WALKAROUND::Route(), and unfracture().

◆ SegmentCount()

int SHAPE_LINE_CHAIN::SegmentCount ( ) const
inline

Function SegmentCount()

Returns number of segments in this line chain.

Returns
number of segments

Definition at line 226 of file shape_line_chain.h.

227  {
228  int c = m_points.size() - 1;
229  if( m_closed )
230  c++;
231 
232  return std::max( 0, c );
233  }
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices

References m_closed, and m_points.

Referenced by PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), PNS::NODE::AssembleLine(), POLY_GRID_PARTITION::build(), BuildFootprintPolygonOutlines(), PNS::LINE_PLACER::buildInitialLine(), PNS::PRESERVE_VERTEX_CONSTRAINT::Check(), CheckClearance(), PNS::NODE::CheckColliding(), PNS::DIFF_PAIR::CheckConnectionAngle(), PNS::checkGap(), PNS::MEANDERED_LINE::CheckSelfIntersections(), PNS::closestProjectedPoint(), PCB_GRID_HELPER::computeAnchors(), PNS::COST_ESTIMATOR::CornerCost(), PNS::LINE::CountCorners(), PNS::DIFF_PAIR::CoupledLength(), PNS::DIFF_PAIR::CoupledSegmentPairs(), BOARD_ADAPTER::createPadWithClearance(), CSegment(), PNS::LINE::dragCorner45(), PNS::dragCornerInternal(), PNS::LINE::dragSegment45(), KIGFX::PCB_PAINTER::draw(), KIGFX::OPENGL_GAL::DrawPolygon(), PNS::DIFF_PAIR::Empty(), PNS::findCoupledVertices(), findEndSegments(), FindSegment(), PNS::DIFF_PAIR_PLACER::FixRoute(), PNS::LINE_PLACER::FixRoute(), PCB_SHAPE::GetLength(), SHAPE_SIMPLE::GetSegmentCount(), GetSegmentCount(), PNS::LINE_PLACER::handlePullback(), PNS::DP_MEANDER_PLACER::HasPlacedAnything(), PNS::DIFF_PAIR_PLACER::HasPlacedAnything(), Intersect(), PNS::LINE::Is45Degree(), Length(), CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices(), PCB_SHAPE::MakeEffectiveShapes(), PNS::OPTIMIZER::mergeColinear(), PNS::OPTIMIZER::mergeDpSegments(), PNS::OPTIMIZER::mergeDpStep(), PNS::OPTIMIZER::mergeFull(), PNS::OPTIMIZER::mergeObtuse(), PNS::OPTIMIZER::mergeStep(), PNS::NODE::NearestObstacle(), NearestPoint(), NearestSegment(), PathLength(), PointAlong(), PNS::pointInside2(), KIGFX::VIEW_OVERLAY::Polyline(), PNS::LINE_PLACER::reduceTail(), PNS::WALKAROUND::Route(), Segment(), PNS::LINE::SegmentCount(), segmentCrossesHullBoundary(), SelfIntersecting(), PNS::OPTIMIZER::smartPadsSingle(), PNS::LINE::snapDraggedCorner(), PNS::LINE::snapToNeighbourSegments(), Split(), POLYGON_GEOM_MANAGER::updateLeaderPoints(), PNS::LINE::Walkaround(), walkaround2(), and HYPERLYNX_EXPORTER::writeBoardInfo().

◆ SelfIntersecting()

const OPT< SHAPE_LINE_CHAIN::INTERSECTION > SHAPE_LINE_CHAIN::SelfIntersecting ( ) const

Function SelfIntersecting()

Checks if the line chain is self-intersecting.

Returns
(optional) first found self-intersection point.

Definition at line 950 of file shape_line_chain.cpp.

951 {
952  for( int s1 = 0; s1 < SegmentCount(); s1++ )
953  {
954  for( int s2 = s1 + 1; s2 < SegmentCount(); s2++ )
955  {
956  const VECTOR2I s2a = CSegment( s2 ).A, s2b = CSegment( s2 ).B;
957 
958  if( s1 + 1 != s2 && CSegment( s1 ).Contains( s2a ) )
959  {
960  INTERSECTION is;
961  is.our = CSegment( s1 );
962  is.their = CSegment( s2 );
963  is.p = s2a;
964  return is;
965  }
966  else if( CSegment( s1 ).Contains( s2b ) &&
967  // for closed polylines, the ending point of the
968  // last segment == starting point of the first segment
969  // this is a normal case, not self intersecting case
970  !( IsClosed() && s1 == 0 && s2 == SegmentCount()-1 ) )
971  {
972  INTERSECTION is;
973  is.our = CSegment( s1 );
974  is.their = CSegment( s2 );
975  is.p = s2b;
976  return is;
977  }
978  else
979  {
980  OPT_VECTOR2I p = CSegment( s1 ).Intersect( CSegment( s2 ), true );
981 
982  if( p )
983  {
984  INTERSECTION is;
985  is.our = CSegment( s1 );
986  is.their = CSegment( s2 );
987  is.p = *p;
988  return is;
989  }
990  }
991  }
992  }
993 
995 }
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
Definition: seg.cpp:119
Define a general 2D-vector/point.
Definition: vector2d.h:61
bool IsClosed() const override
Function IsClosed()
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
int SegmentCount() const
Function SegmentCount()
const SEG CSegment(int aIndex) const
Function CSegment()
VECTOR2I A
Definition: seg.h:49
boost::optional< T > OPT
Definition: optional.h:7
VECTOR2I B
Definition: seg.h:50

References SEG::A, SEG::B, CSegment(), SEG::Intersect(), IsClosed(), SHAPE_LINE_CHAIN::INTERSECTION::our, SHAPE_LINE_CHAIN::INTERSECTION::p, SegmentCount(), and SHAPE_LINE_CHAIN::INTERSECTION::their.

Referenced by PNS::DIFF_PAIR::BuildInitial(), PNS::clipToLoopStart(), and DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate().

◆ SetClosed()

void SHAPE_LINE_CHAIN::SetClosed ( bool  aClosed)
inline

Function SetClosed()

Marks the line chain as closed (i.e. with a segment connecting the last point with the first point).

Parameters
aClosedwhether the line chain is to be closed or not.

Definition at line 187 of file shape_line_chain.h.

188  {
189  m_closed = aClosed;
190  }
bool m_closed
is the line chain closed?

References m_closed.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), ZONE::AddPolygon(), PNS::ArcHull(), POLY_GRID_PARTITION::build(), buildBoardBoundingBoxPoly(), BuildFootprintPolygonOutlines(), KI_TEST::BuildRectChain(), ZONE_FILLER::buildThermalSpokes(), SHAPE_POLY_SET::chamferFilletPolygon(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), CN_ZONE_LAYER::CN_ZONE_LAYER(), KI_TEST::CommonTestData::CommonTestData(), PCB_GRID_HELPER::computeAnchors(), PNS::ConvexHull(), CovertPolygonToBlocks(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), KIGFX::GERBVIEW_PAINTER::draw(), SHAPE_POLY_SET::fractureSingle(), CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromDrawsegments(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), HelperShapeLineChainFromAltiumVertices(), LIB_POLYLINE::HitTest(), IteratorFixture::IteratorFixture(), CONVERT_TOOL::makePolysFromRects(), CONVERT_TOOL::makePolysFromSegs(), GEOM_TEST::MakeSquarePolyLine(), SHAPE_POLY_SET::NewHole(), SHAPE_POLY_SET::NewOutline(), PNS::OctagonalHull(), SHAPE_RECT::Outline(), EAGLE_PLUGIN::packagePolygon(), SHAPE_POLY_SET::Parse(), ALTIUM_PCB::ParseRegions6Data(), BRDITEMS_PLOTTER::PlotFootprintGraphicItem(), polygonArea(), CONVERT_TOOL::PolyToLines(), RENDER_3D_LEGACY::reload(), PNS::SegmentHull(), SHAPE_SIMPLE::SHAPE_SIMPLE(), MARKER_BASE::ShapeToPolygon(), TestConcaveSquareFillet(), TransformCircleToPolygon(), TransformRoundRectToPolygon(), unfracture(), and SHAPE_POLY_SET::unfractureSingle().

◆ SetPoint()

void SHAPE_LINE_CHAIN::SetPoint ( int  aIndex,
const VECTOR2I aPos 
)
inline

Accessor Function to move a point to a specific location.

Parameters
aIndexIndex (wrapping) of the point to move
aPosNew absolute location of the point

Definition at line 312 of file shape_line_chain.h.

313  {
314  if( aIndex < 0 )
315  aIndex += PointCount();
316  else if( aIndex >= PointCount() )
317  aIndex -= PointCount();
318 
319  m_points[aIndex] = aPos;
320 
321  if( m_shapes[aIndex] != SHAPE_IS_PT )
322  convertArc( m_shapes[aIndex] );
323  }
void convertArc(ssize_t aArcIndex)
Converts an arc to only a point chain by removing the arc and references.
int PointCount() const
Function PointCount()
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References convertArc(), m_points, m_shapes, PointCount(), and SHAPE_IS_PT.

Referenced by PNS::LINE_PLACER::buildInitialLine(), and PNS::LINE::dragCornerFree().

◆ SetWidth()

void SHAPE_LINE_CHAIN::SetWidth ( int  aWidth)
inline

Sets the width of all segments in the chain.

Parameters
aWidthwidth in internal units

Definition at line 206 of file shape_line_chain.h.

207  {
208  m_width = aWidth;
209  }
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...

References m_width.

Referenced by ROUTER_PREVIEW_ITEM::Line(), CONVERT_TOOL::makePolysFromRects(), CONVERT_TOOL::makePolysFromSegs(), PNS::LINE::SetShape(), PNS::LINE::SetWidth(), and PNS::DIFF_PAIR::SetWidth().

◆ ShapeCount()

int SHAPE_LINE_CHAIN::ShapeCount ( ) const

Returns the number of shapes (line segments or arcs) in this line chain.

This is kind of like SegmentCount() but will only count arcs as 1 segment

Returns
ArcCount() + the number of non-arc segments

Definition at line 476 of file shape_line_chain.cpp.

477 {
478  if( m_points.empty() )
479  return 0;
480 
481  int numPoints = static_cast<int>( m_shapes.size() );
482  int numShapes = 0;
483  int arcIdx = -1;
484 
485  for( int i = 0; i < m_points.size() - 1; i++ )
486  {
487  if( m_shapes[i] == SHAPE_IS_PT )
488  {
489  numShapes++;
490  }
491  else
492  {
493  arcIdx = m_shapes[i];
494  numShapes++;
495 
496  // Now skip the rest of the arc
497  while( i < numPoints && m_shapes[i] == arcIdx )
498  i++;
499 
500  // Add the "hidden" segment at the end of the arc, if it exists
501  if( i < numPoints &&
502  m_points[i] != m_points[i - 1] )
503  {
504  numShapes++;
505  }
506 
507  i--;
508  }
509  }
510 
511  return numShapes;
512 }
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References m_points, m_shapes, and SHAPE_IS_PT.

Referenced by PNS::LINE_PLACER::mergeHead(), PNS::LINE_PLACER::optimizeTailHeadTransition(), and PNS::LINE::ShapeCount().

◆ Simplify()

SHAPE_LINE_CHAIN & SHAPE_LINE_CHAIN::Simplify ( bool  aRemoveColinear = true)

Function Simplify()

Simplifies the line chain by removing colinear adjacent segments and duplicate vertices.

Parameters
aRemoveColinearcontrosl the removal of colinear adjacent segments
Returns
reference to self.

Definition at line 998 of file shape_line_chain.cpp.

999 {
1000  std::vector<VECTOR2I> pts_unique;
1001  std::vector<ssize_t> shapes_unique;
1002 
1003  if( PointCount() < 2 )
1004  {
1005  return *this;
1006  }
1007  else if( PointCount() == 2 )
1008  {
1009  if( m_points[0] == m_points[1] )
1010  m_points.pop_back();
1011 
1012  return *this;
1013  }
1014 
1015  int i = 0;
1016  int np = PointCount();
1017 
1018  // stage 1: eliminate duplicate vertices
1019  while( i < np )
1020  {
1021  int j = i + 1;
1022 
1023  // We can eliminate duplicate vertices as long as they are part of the same shape, OR if
1024  // one of them is part of a shape and one is not.
1025  while( j < np && m_points[i] == m_points[j] &&
1026  ( m_shapes[i] == m_shapes[j] ||
1027  m_shapes[i] == SHAPE_IS_PT ||
1028  m_shapes[j] == SHAPE_IS_PT ) )
1029  {
1030  j++;
1031  }
1032 
1033  int shapeToKeep = m_shapes[i];
1034 
1035  if( shapeToKeep == SHAPE_IS_PT )
1036  shapeToKeep = m_shapes[j - 1];
1037 
1038  wxASSERT( shapeToKeep < static_cast<int>( m_arcs.size() ) );
1039 
1040  pts_unique.push_back( CPoint( i ) );
1041  shapes_unique.push_back( shapeToKeep );
1042 
1043  i = j;
1044  }
1045 
1046  m_points.clear();
1047  m_shapes.clear();
1048  np = pts_unique.size();
1049 
1050  i = 0;
1051 
1052  // stage 2: eliminate colinear segments
1053  while( i < np - 2 )
1054  {
1055  const VECTOR2I p0 = pts_unique[i];
1056  const VECTOR2I p1 = pts_unique[i + 1];
1057  int n = i;
1058 
1059  if( aRemoveColinear && shapes_unique[i] < 0 && shapes_unique[i + 1] < 0 )
1060  {
1061  while( n < np - 2
1062  && ( SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1
1063  || SEG( p0, p1 ).Collinear( SEG( p1, pts_unique[n + 2] ) ) ) )
1064  n++;
1065  }
1066 
1067  m_points.push_back( p0 );
1068  m_shapes.push_back( shapes_unique[i] );
1069 
1070  if( n > i )
1071  i = n;
1072 
1073  if( n == np - 2 )
1074  {
1075  m_points.push_back( pts_unique[np - 1] );
1076  m_shapes.push_back( shapes_unique[np - 1] );
1077  return *this;
1078  }
1079 
1080  i++;
1081  }
1082 
1083  if( np > 1 )
1084  {
1085  m_points.push_back( pts_unique[np - 2] );
1086  m_shapes.push_back( shapes_unique[np - 2] );
1087  }
1088 
1089  m_points.push_back( pts_unique[np - 1] );
1090  m_shapes.push_back( shapes_unique[np - 1] );
1091 
1092  assert( m_points.size() == m_shapes.size() );
1093 
1094  return *this;
1095 }
Define a general 2D-vector/point.
Definition: vector2d.h:61
int PointCount() const
Function PointCount()
std::vector< SHAPE_ARC > m_arcs
const VECTOR2I & CPoint(int aIndex) const
Function Point()
std::vector< VECTOR2I > m_points
array of vertices
Definition: seg.h:41
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT

References CPoint(), m_arcs, m_points, m_shapes, PointCount(), and SHAPE_IS_PT.

Referenced by PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), PNS::NODE::AssembleLine(), PNS::DIFF_PAIR_PLACER::attemptWalk(), DIRECTION_45::BuildInitialTrace(), PNS::LINE::ChangedArea(), CN_ZONE_LAYER::CN_ZONE_LAYER(), CompareGeometry(), PNS::DIFF_PAIR::CoupledSegmentPairs(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::MEANDER_PLACER::doMove(), DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate(), PNS::LINE::dragCornerFree(), PNS::LINE::dragSegment45(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), PNS::OPTIMIZER::mergeDpStep(), PNS::OPTIMIZER::mergeFull(), PNS::LINE_PLACER::mergeHead(), PNS::DP_MEANDER_PLACER::Move(), PNS::SHOVE::onCollidingSolid(), PNS::LINE_PLACER::optimizeTailHeadTransition(), PNS::LINE_PLACER::rhShoveOnly(), PNS::WALKAROUND::Route(), PNS::OPTIMIZER::runSmartPads(), PNS::TOPOLOGY::SimplifyLine(), PNS::LINE_PLACER::simplifyNewLine(), PNS::OPTIMIZER::smartPadsSingle(), PNS::Tighten(), PNS::LINE_PLACER::Trace(), and PNS::LINE::Walkaround().

◆ Slice()

const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice ( int  aStartIndex,
int  aEndIndex = -1 
) const

Function Slice()

Returns a subset of this line chain containing the [start_index, end_index] range of points.

Parameters
aStartIndexstart of the point range to be returned (inclusive)
aEndIndexend of the point range to be returned (inclusive)
Returns
cut line chain.

Definition at line 572 of file shape_line_chain.cpp.

573 {
574  SHAPE_LINE_CHAIN rv;
575 
576  if( aEndIndex < 0 )
577  aEndIndex += PointCount();
578 
579  if( aStartIndex < 0 )
580  aStartIndex += PointCount();
581 
582  int numPoints = static_cast<int>( m_points.size() );
583 
584  for( int i = aStartIndex; i <= aEndIndex && i < numPoints; i++ )
585  {
586  if( m_shapes[i] != SHAPE_IS_PT )
587  {
588  int arcIdx = m_shapes[i];
589  bool wholeArc = true;
590  int arcStart = i;
591 
592  if( i > 0 && m_shapes[i - 1] >= 0 && m_shapes[i - 1] != arcIdx )
593  wholeArc = false;
594 
595  while( i < numPoints && m_shapes[i] == arcIdx )
596  i++;
597 
598  i--;
599 
600  if( i > aEndIndex )
601  wholeArc = false;
602 
603  if( wholeArc )
604  {
605  rv.Append( m_arcs[arcIdx] );
606  }
607  else
608  {
609  rv.Append( m_points[arcStart] );
610  i = arcStart;
611  }
612  }
613  else
614  {
615  rv.Append( m_points[i] );
616  }
617  }
618 
619  return rv;
620 }
int PointCount() const
Function PointCount()
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static constexpr ssize_t SHAPE_IS_PT
SHAPE_LINE_CHAIN.

References Append(), m_arcs, m_points, m_shapes, PointCount(), and SHAPE_IS_PT.

Referenced by PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS::clipToLoopStart(), PNS::LINE::ClipVertexRange(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::LINE::dragCorner45(), PNS::dragCornerInternal(), PNS::LINE_PLACER::optimizeTailHeadTransition(), PNS::LINE_PLACER::rhWalkOnly(), PNS::Tighten(), and PNS::LINE::Walkaround().

◆ Split()

int SHAPE_LINE_CHAIN::Split ( const VECTOR2I aP)

Function Split()

Inserts the point aP belonging to one of the our segments, splitting the adjacent segment in two.

Parameters
aPthe point to be inserted
Returns
index of the newly inserted point (or a negative value if aP does not lie on our line)

Definition at line 412 of file shape_line_chain.cpp.

413 {
414  int ii = -1;
415  int min_dist = 2;
416 
417  int found_index = Find( aP );
418 
419  for( int s = 0; s < SegmentCount(); s++ )
420  {
421  const SEG seg = CSegment( s );
422  int dist = seg.Distance( aP );
423 
424  // make sure we are not producing a 'slightly concave' primitive. This might happen
425  // if aP lies very close to one of already existing points.
426  if( dist < min_dist && seg.A != aP && seg.B != aP )
427  {
428  min_dist = dist;
429  if( found_index < 0 )
430  ii = s;
431  else if( s < found_index )
432  ii = s;
433  }
434  }
435 
436  if( ii < 0 )
437  ii = found_index;
438 
439  if( ii >= 0 )
440  {
441  // Are we splitting at the beginning of an arc? If so, let's split right before so that
442  // the shape is preserved
443  if( ii < PointCount() - 1 && m_shapes[ii] >= 0 && m_shapes[ii] == m_shapes[ii + 1] )
444  ii--;
445 
446  m_points.insert( m_points.begin() + ( ii + 1 ), aP );
447  m_shapes.insert( m_shapes.begin() + ( ii + 1 ), ssize_t( SHAPE_IS_PT ) );
448 
449  return ii + 1;
450  }
451 
452  return -1;
453 }
int Find(const VECTOR2I &aP) const
Function Find()
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.h:239
int PointCount() const
Function PointCount()
std::vector< VECTOR2I > m_points
array of vertices
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
std::vector< ssize_t > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
const SEG CSegment(int aIndex) const
Function CSegment()
static constexpr ssize_t SHAPE_IS_PT
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50

References SEG::A, SEG::B, CSegment(), SEG::Distance(), Find(), m_points, m_shapes, PointCount(), SegmentCount(), and SHAPE_IS_PT.

Referenced by PNS::clipToLoopStart(), PNS::LINE::ClipToNearestObstacle(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::LINE_PLACER::rhWalkOnly(), PNS::LINE::Walkaround(), and walkaround2().

◆ SquaredDistance()

SEG::ecoord SHAPE_LINE_CHAIN_BASE::SquaredDistance ( const VECTOR2I aP,
bool  aOutlineOnly = false 
) const
inherited

Definition at line 398 of file shape_line_chain.cpp.

399 {
401 
402  if( IsClosed() && PointInside( aP ) && !aOutlineOnly )
403  return 0;
404 
405  for( size_t s = 0; s < GetSegmentCount(); s++ )
406  d = std::min( d, GetSegment( s ).SquaredDistance( aP ) );
407 
408  return d;
409 }
virtual bool IsClosed() const =0
ecoord SquaredDistance(const SEG &aSeg) const
Definition: seg.cpp:39
virtual size_t GetSegmentCount() const =0
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
VECTOR2I::extended_type ecoord
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.
virtual const SEG GetSegment(int aIndex) const =0

References VECTOR2< T >::ECOORD_MAX, SHAPE_LINE_CHAIN_BASE::GetSegment(), SHAPE_LINE_CHAIN_BASE::GetSegmentCount(), SHAPE_LINE_CHAIN_BASE::IsClosed(), SHAPE_LINE_CHAIN_BASE::PointInside(), and SEG::SquaredDistance().

Referenced by Distance().

◆ Type()

SHAPE_TYPE SHAPE_BASE::Type ( ) const
inlineinherited

◆ Width()

int SHAPE_LINE_CHAIN::Width ( ) const
inline

Gets the current width of the segments in the chain.

Returns
width in internal units

Definition at line 215 of file shape_line_chain.h.

216  {
217  return m_width;
218  }
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...

References m_width.

Referenced by ROUTER_PREVIEW_ITEM::drawShape().

Member Data Documentation

◆ m_arcs

std::vector<SHAPE_ARC> SHAPE_LINE_CHAIN::m_arcs
private

◆ m_bbox

BOX2I SHAPE_LINE_CHAIN::m_bbox
mutableprivate

cached bounding box

Definition at line 796 of file shape_line_chain.h.

Referenced by Append(), BBoxFromCache(), and GenerateBBoxCache().

◆ m_closed

bool SHAPE_LINE_CHAIN::m_closed
private

is the line chain closed?

Definition at line 786 of file shape_line_chain.h.

Referenced by Area(), Clear(), CSegment(), Format(), IsClosed(), Parse(), Reverse(), Segment(), SegmentCount(), and SetClosed().

◆ m_points

◆ m_shapes

std::vector<ssize_t> SHAPE_LINE_CHAIN::m_shapes
private

Array of indices that refer to the index of the shape if the point is part of a larger shape, e.g.

arc or spline. If the value is -1, the point is just a point.

Definition at line 781 of file shape_line_chain.h.

Referenced by Append(), ArcIndex(), Clear(), convertArc(), CShapes(), Insert(), isArc(), NearestPoint(), NextShape(), Parse(), Remove(), RemoveShape(), Replace(), Reverse(), SetPoint(), SHAPE_LINE_CHAIN(), ShapeCount(), Simplify(), Slice(), and Split().

◆ m_type

SHAPE_TYPE SHAPE_BASE::m_type
protectedinherited

< type of our shape

Definition at line 110 of file shape.h.

Referenced by SHAPE::IsNull(), and SHAPE_BASE::Type().

◆ m_width

int SHAPE_LINE_CHAIN::m_width
private

Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to account for where we need a width and where not Alternatively, we could split the class into a LINE_CHAIN (no width) and SHAPE_LINE_CHAIN that derives from SHAPE as well that does have a width.

Not sure yet on the correct path. TODO Note that we also have SHAPE_SIMPLE which is a closed, filled SHAPE_LINE_CHAIN.

Definition at line 793 of file shape_line_chain.h.

Referenced by BBox(), GenerateBBoxCache(), SetWidth(), and Width().

◆ MIN_PRECISION_IU

const int SHAPE::MIN_PRECISION_IU = 4
staticinherited

This is the minimum precision for all the points in a shape.

Definition at line 122 of file shape.h.

Referenced by BOOST_AUTO_TEST_CASE(), DIRECTION_45::BuildInitialTrace(), CompareLength(), EDIT_TOOL::FilletTracks(), and CIRCLE::IntersectLine().

◆ SHAPE_IS_PT

constexpr ssize_t SHAPE_LINE_CHAIN::SHAPE_IS_PT = -1
staticprivate

The documentation for this class was generated from the following files: