KiCad PCB EDA Suite
shape_line_chain.h
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013 CERN
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  * Copyright (C) 2013-2021 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #ifndef __SHAPE_LINE_CHAIN
27 #define __SHAPE_LINE_CHAIN
28 
29 
30 #include <clipper.hpp>
31 #include <geometry/seg.h>
32 #include <geometry/shape.h>
33 #include <geometry/shape_arc.h>
34 #include <math/vector2d.h>
35 
41 {
43  {
44  m_FirstArcIdx = -1;
45  m_SecondArcIdx = -1;
46  }
47 
48  CLIPPER_Z_VALUE( const std::pair<ssize_t, ssize_t> aShapeIndices, ssize_t aOffset = 0 )
49  {
50  m_FirstArcIdx = aShapeIndices.first;
51  m_SecondArcIdx = aShapeIndices.second;
52 
53  auto offsetVal = [&]( ssize_t& aVal )
54  {
55  if( aVal >= 0 )
56  aVal += aOffset;
57  };
58 
59  offsetVal( m_FirstArcIdx );
60  offsetVal( m_SecondArcIdx );
61  }
62 
63  ssize_t m_FirstArcIdx;
64  ssize_t m_SecondArcIdx;
65 };
66 
67 
77 {
78 private:
79  typedef std::vector<VECTOR2I>::iterator point_iter;
80  typedef std::vector<VECTOR2I>::const_iterator point_citer;
81 
82 public:
86  struct INTERSECTION
87  {
90 
92  int index_our;
93 
97 
100 
105 
109  bool valid;
110  };
111 
112 
118  {
119  public:
120  POINT_INSIDE_TRACKER( const VECTOR2I& aPoint );
121 
122  void AddPolyline( const SHAPE_LINE_CHAIN& aPolyline );
123  bool IsInside();
124 
125  private:
126 
127  bool processVertex ( const VECTOR2I& ip, const VECTOR2I& ipNext );
128 
133  int m_state;
134  int m_count;
135  };
136 
137  typedef std::vector<INTERSECTION> INTERSECTIONS;
138 
139 
145  m_closed( false ),
146  m_width( 0 )
147  {}
148 
151  m_points( aShape.m_points ),
152  m_shapes( aShape.m_shapes ),
153  m_arcs( aShape.m_arcs ),
154  m_closed( aShape.m_closed ),
155  m_width( aShape.m_width ),
156  m_bbox( aShape.m_bbox )
157  {}
158 
159  SHAPE_LINE_CHAIN( const std::vector<int>& aV );
160 
161  SHAPE_LINE_CHAIN( const std::vector<wxPoint>& aV, bool aClosed = false ) :
163  m_closed( aClosed ),
164  m_width( 0 )
165  {
166  m_points.reserve( aV.size() );
167 
168  for( auto pt : aV )
169  m_points.emplace_back( pt.x, pt.y );
170 
171  m_shapes = std::vector<std::pair<ssize_t, ssize_t>>( aV.size(), SHAPES_ARE_PT );
172  }
173 
174  SHAPE_LINE_CHAIN( const std::vector<VECTOR2I>& aV, bool aClosed = false ) :
176  m_closed( aClosed ),
177  m_width( 0 )
178  {
179  m_points = aV;
180  m_shapes = std::vector<std::pair<ssize_t, ssize_t>>( aV.size(), SHAPES_ARE_PT );
181  }
182 
183  SHAPE_LINE_CHAIN( const SHAPE_ARC& aArc, bool aClosed = false ) :
185  m_closed( aClosed ),
186  m_width( 0 )
187  {
189  m_arcs.emplace_back( aArc );
190  m_shapes = std::vector<std::pair<ssize_t, ssize_t>>( m_points.size(), SHAPES_ARE_PT );
191  }
192 
193  SHAPE_LINE_CHAIN( const ClipperLib::Path& aPath,
194  const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
195  const std::vector<SHAPE_ARC>& aArcBuffer );
196 
198  {}
199 
200  SHAPE_LINE_CHAIN& operator=( const SHAPE_LINE_CHAIN& ) = default;
201 
202  SHAPE* Clone() const override;
203 
207  void Clear()
208  {
209  m_points.clear();
210  m_arcs.clear();
211  m_shapes.clear();
212  m_closed = false;
213  }
214 
221  void SetClosed( bool aClosed )
222  {
223  m_closed = aClosed;
224  }
225 
229  bool IsClosed() const override
230  {
231  return m_closed;
232  }
233 
239  void SetWidth( int aWidth )
240  {
241  m_width = aWidth;
242  }
243 
249  int Width() const
250  {
251  return m_width;
252  }
253 
259  int SegmentCount() const
260  {
261  int c = m_points.size() - 1;
262  if( m_closed )
263  c++;
264 
265  return std::max( 0, c );
266  }
267 
275  int ShapeCount() const;
276 
282  int PointCount() const
283  {
284  return m_points.size();
285  }
286 
294  SEG Segment( int aIndex )
295  {
296  if( aIndex < 0 )
297  aIndex += SegmentCount();
298 
299  if( aIndex == (int)( m_points.size() - 1 ) && m_closed )
300  return SEG( m_points[aIndex], m_points[0], aIndex );
301  else
302  return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
303  }
304 
312  const SEG CSegment( int aIndex ) const
313  {
314  if( aIndex < 0 )
315  aIndex += SegmentCount();
316 
317  if( aIndex == (int)( m_points.size() - 1 ) && m_closed )
318  return SEG( m_points[aIndex], m_points[0], aIndex );
319  else
320  return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
321  }
322 
336  int NextShape( int aPointIndex, bool aForwards = true ) const;
337 
338  int PrevShape( int aPointIndex ) const
339  {
340  return NextShape( aPointIndex, false );
341  }
342 
349  void SetPoint( int aIndex, const VECTOR2I& aPos );
350 
357  const VECTOR2I& CPoint( int aIndex ) const
358  {
359  if( aIndex < 0 )
360  aIndex += PointCount();
361  else if( aIndex >= PointCount() )
362  aIndex -= PointCount();
363 
364  return m_points[aIndex];
365  }
366 
367  const std::vector<VECTOR2I>& CPoints() const
368  {
369  return m_points;
370  }
371 
375  const VECTOR2I& CLastPoint() const
376  {
377  return m_points[static_cast<size_t>( PointCount() ) - 1];
378  }
379 
383  const std::vector<SHAPE_ARC>& CArcs() const
384  {
385  return m_arcs;
386  }
387 
391  const std::vector<std::pair<ssize_t, ssize_t>>& CShapes() const
392  {
393  return m_shapes;
394  }
395 
397  const BOX2I BBox( int aClearance = 0 ) const override
398  {
399  BOX2I bbox;
400  bbox.Compute( m_points );
401 
402  if( aClearance != 0 || m_width != 0 )
403  bbox.Inflate( aClearance + m_width );
404 
405  return bbox;
406  }
407 
408  void GenerateBBoxCache() const
409  {
411 
412  if( m_width != 0 )
414  }
415 
416  BOX2I* GetCachedBBox() const override
417  {
418  return &m_bbox;
419  }
420 
427  int Distance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
428 
434  const SHAPE_LINE_CHAIN Reverse() const;
435 
441  void ClearArcs();
442 
448  long long int Length() const;
449 
459  void Append( int aX, int aY, bool aAllowDuplication = false )
460  {
461  VECTOR2I v( aX, aY );
462  Append( v, aAllowDuplication );
463  }
464 
473  void Append( const VECTOR2I& aP, bool aAllowDuplication = false )
474  {
475  if( m_points.size() == 0 )
476  m_bbox = BOX2I( aP, VECTOR2I( 0, 0 ) );
477 
478  if( m_points.size() == 0 || aAllowDuplication || CPoint( -1 ) != aP )
479  {
480  m_points.push_back( aP );
481  m_shapes.push_back( SHAPES_ARE_PT );
482  m_bbox.Merge( aP );
483  }
484  }
485 
491  void Append( const SHAPE_LINE_CHAIN& aOtherLine );
492 
493  void Append( const SHAPE_ARC& aArc );
494 
495  void Insert( size_t aVertex, const VECTOR2I& aP );
496 
497  void Insert( size_t aVertex, const SHAPE_ARC& aArc );
498 
506  void Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP );
507 
516  void Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine );
517 
524  void Remove( int aStartIndex, int aEndIndex );
525 
531  void Remove( int aIndex )
532  {
533  Remove( aIndex, aIndex );
534  }
535 
544  void RemoveShape( int aPointIndex );
545 
553  int Split( const VECTOR2I& aP );
554 
561  int Find( const VECTOR2I& aP, int aThreshold = 0 ) const;
562 
569  int FindSegment( const VECTOR2I& aP, int aThreshold = 1 ) const;
570 
578  const SHAPE_LINE_CHAIN Slice( int aStartIndex, int aEndIndex = -1 ) const;
579 
581  {
582  compareOriginDistance( const VECTOR2I& aOrigin ):
583  m_origin( aOrigin )
584  {}
585 
586  bool operator()( const INTERSECTION& aA, const INTERSECTION& aB )
587  {
588  return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm();
589  }
590 
592  };
593 
594  bool Intersects( const SHAPE_LINE_CHAIN& aChain ) const;
595 
604  int Intersect( const SEG& aSeg, INTERSECTIONS& aIp ) const;
605 
614  int Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp,
615  bool aExcludeColinearAndTouching = false ) const;
616 
623  int PathLength( const VECTOR2I& aP, int aIndex = -1 ) const;
624 
632  bool CheckClearance( const VECTOR2I& aP, const int aDist) const;
633 
639  const OPT<INTERSECTION> SelfIntersecting() const;
640 
647  SHAPE_LINE_CHAIN& Simplify( bool aRemoveColinear = true );
648 
655  int NearestSegment( const VECTOR2I& aP ) const;
656 
665  const VECTOR2I NearestPoint( const VECTOR2I& aP, bool aAllowInternalShapePoints = true ) const;
666 
675  const VECTOR2I NearestPoint( const SEG& aSeg, int& dist ) const;
676 
678  const std::string Format() const override;
679 
681  bool Parse( std::stringstream& aStream ) override;
682 
683  bool operator!=( const SHAPE_LINE_CHAIN& aRhs ) const
684  {
685  if( PointCount() != aRhs.PointCount() )
686  return true;
687 
688  for( int i = 0; i < PointCount(); i++ )
689  {
690  if( CPoint( i ) != aRhs.CPoint( i ) )
691  return true;
692  }
693 
694  return false;
695  }
696 
697  bool CompareGeometry( const SHAPE_LINE_CHAIN& aOther ) const;
698 
699  void Move( const VECTOR2I& aVector ) override
700  {
701  for( auto& pt : m_points )
702  pt += aVector;
703 
704  for( auto& arc : m_arcs )
705  arc.Move( aVector );
706  }
707 
715  void Mirror( bool aX = true, bool aY = false, const VECTOR2I& aRef = { 0, 0 } );
716 
722  void Mirror( const SEG& axis );
723 
730  void Rotate( double aAngle, const VECTOR2I& aCenter = VECTOR2I( 0, 0 ) ) override;
731 
732  bool IsSolid() const override
733  {
734  return false;
735  }
736 
737  const VECTOR2I PointAlong( int aPathLength ) const;
738 
744  double Area( bool aAbsolute = true ) const;
745 
746  size_t ArcCount() const
747  {
748  return m_arcs.size();
749  }
750 
754  ssize_t ArcIndex( size_t aSegment ) const
755  {
756  if( IsSharedPt( aSegment ) )
757  return m_shapes[aSegment].second;
758  else
759  return m_shapes[aSegment].first;
760  }
761 
762  const SHAPE_ARC& Arc( size_t aArc ) const
763  {
764  return m_arcs[aArc];
765  }
766 
772  bool IsSharedPt( size_t aIndex ) const
773  {
774  return aIndex < m_shapes.size() - 1
775  && m_shapes[aIndex].first != SHAPE_IS_PT
776  && m_shapes[aIndex].second != SHAPE_IS_PT;
777  }
778 
779 
780  bool IsPtOnArc( size_t aPtIndex ) const
781  {
782  return aPtIndex < m_shapes.size() && m_shapes[aPtIndex] != SHAPES_ARE_PT;
783  }
784 
785 
786  bool IsArcSegment( size_t aSegment ) const
787  {
788  /*
789  * A segment is part of an arc except in the special case of two arcs next to each other
790  * but without a shared vertex. Here there is a segment between the end of the first arc
791  * and the start of the second arc.
792  */
793  size_t nextIdx = aSegment + 1;
794 
795  if( nextIdx > m_shapes.size() - 1 )
796  return false; // Always false, even if the shape is closed
797 
798  return ( IsPtOnArc( aSegment )
799  && ( IsSharedPt( aSegment )
800  || m_shapes[aSegment].first == m_shapes[nextIdx].first ) );
801  }
802 
803 
804  bool IsArcStart( size_t aIndex ) const
805  {
806  if( aIndex == 0 )
807  return IsPtOnArc( aIndex );
808 
809  return ( IsSharedPt( aIndex ) || ( IsPtOnArc( aIndex ) && !IsArcSegment( aIndex - 1 ) ) );
810  }
811 
812 
813  bool IsArcEnd( size_t aIndex ) const
814  {
815  if( aIndex == static_cast<size_t>( PointCount() ) - 1 )
816  return IsPtOnArc( aIndex );
817 
818  return ( IsSharedPt( aIndex ) || ( IsPtOnArc( aIndex ) && !IsArcSegment( aIndex ) ) );
819  }
820 
821  virtual const VECTOR2I GetPoint( int aIndex ) const override { return CPoint(aIndex); }
822  virtual const SEG GetSegment( int aIndex ) const override { return CSegment(aIndex); }
823  virtual size_t GetPointCount() const override { return PointCount(); }
824  virtual size_t GetSegmentCount() const override { return SegmentCount(); }
825 
826 protected:
827  friend class SHAPE_POLY_SET;
828 
834  void convertArc( ssize_t aArcIndex );
835 
848  void splitArc( ssize_t aPtIndex, bool aCoincident = false );
849 
850  void amendArc( size_t aArcIndex, const VECTOR2I& aNewStart, const VECTOR2I& aNewEnd );
851 
852  void amendArcStart( size_t aArcIndex, const VECTOR2I& aNewStart )
853  {
854  amendArc( aArcIndex, aNewStart, m_arcs[aArcIndex].GetP1() );
855  }
856 
857  void amendArcEnd( size_t aArcIndex, const VECTOR2I& aNewEnd )
858  {
859  amendArc( aArcIndex, m_arcs[aArcIndex].GetP0(), aNewEnd );
860  }
861 
865  ssize_t reversedArcIndex( size_t aSegment ) const
866  {
867  if( IsSharedPt( aSegment ) )
868  return m_shapes[aSegment].first;
869  else
870  return m_shapes[aSegment].second;
871  }
872 
876  ClipperLib::Path convertToClipper( bool aRequiredOrientation,
877  std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
878  std::vector<SHAPE_ARC>& aArcBuffer ) const;
879 
880 private:
881 
882  static const ssize_t SHAPE_IS_PT;
883 
884  static const std::pair<ssize_t, ssize_t> SHAPES_ARE_PT;
885 
887  std::vector<VECTOR2I> m_points;
888 
903  std::vector<std::pair<ssize_t, ssize_t>> m_shapes;
904 
905  std::vector<SHAPE_ARC> m_arcs;
906 
908  bool m_closed;
909 
915  int m_width;
916 
918  mutable BOX2I m_bbox;
919 };
920 
921 
922 #endif // __SHAPE_LINE_CHAIN
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:146
Represent an intersection between two line segments.
int PrevShape(int aPointIndex) const
const std::vector< std::pair< ssize_t, ssize_t > > & CShapes() const
BOX2I m_bbox
cached bounding box
compareOriginDistance(const VECTOR2I &aOrigin)
void Append(const VECTOR2I &aP, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const SHAPE_ARC & Arc(size_t aArc) const
long long int Length() const
Return length of the line chain in Euclidean metric.
int Split(const VECTOR2I &aP)
Insert the point aP belonging to one of the our segments, splitting the adjacent segment in two.
BOX2< VECTOR2I > BOX2I
Definition: box2.h:506
bool operator!=(const SHAPE_LINE_CHAIN &aRhs) const
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Find all intersection points between our line chain and the segment aSeg.
ClipperLib::Path convertToClipper(bool aRequiredOrientation, std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, std::vector< SHAPE_ARC > &aArcBuffer) const
Create a new Clipper path from the SHAPE_LINE_CHAIN in a given orientation.
virtual size_t GetSegmentCount() const override
std::vector< INTERSECTION > INTERSECTIONS
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.
virtual size_t GetPointCount() const override
void RemoveShape(int aPointIndex)
Remove the shape at the given index from the line chain.
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
void SetPoint(int aIndex, const VECTOR2I &aPos)
Move a point to a specific location.
static const ssize_t SHAPE_IS_PT
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Return a subset of this line chain containing the [start_index, end_index] range of points.
SHAPE_LINE_CHAIN(const SHAPE_LINE_CHAIN &aShape)
VECTOR2I p
< Point of intersection between our and their.
void Move(const VECTOR2I &aVector) override
int Width() const
Get the current width of the segments in the chain.
std::vector< VECTOR2I >::const_iterator point_citer
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Definition: box2.h:75
SHAPE_LINE_CHAIN(const SHAPE_ARC &aArc, bool aClosed=false)
int Distance(const VECTOR2I &aP, bool aOutlineOnly=false) const
Compute the minimum distance between the line chain and a point aP.
virtual ~SHAPE_LINE_CHAIN()
size_t ArcCount() const
void AddPolyline(const SHAPE_LINE_CHAIN &aPolyline)
double Area(bool aAbsolute=true) const
Return the area of this chain.
const SHAPE_LINE_CHAIN Reverse() const
Reverse point order in the line chain.
const std::vector< SHAPE_ARC > & CArcs() const
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
void convertArc(ssize_t aArcIndex)
Convert an arc to only a point chain by removing the arc and references.
int PointCount() const
Return the number of points (vertices) in this line chain.
int FindSegment(const VECTOR2I &aP, int aThreshold=1) const
Search for segment containing point aP.
void splitArc(ssize_t aPtIndex, bool aCoincident=false)
Splits an arc into two arcs at aPtIndex.
const OPT< INTERSECTION > SelfIntersecting() const
Check if the line chain is self-intersecting.
SHAPE_LINE_CHAIN(const std::vector< VECTOR2I > &aV, bool aClosed=false)
bool operator()(const INTERSECTION &aA, const INTERSECTION &aB)
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
std::vector< SHAPE_ARC > m_arcs
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
bool Parse(std::stringstream &aStream) override
void Insert(size_t aVertex, const VECTOR2I &aP)
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
bool IsArcStart(size_t aIndex) const
void SetWidth(int aWidth)
Set the width of all segments in the chain.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
bool m_closed
is the line chain closed?
SHAPE_LINE_CHAIN()
Initialize an empty line chain.
SHAPE_LINE_CHAIN & operator=(const SHAPE_LINE_CHAIN &)=default
int PathLength(const VECTOR2I &aP, int aIndex=-1) const
Compute the walk path length from the beginning of the line chain and the point aP belonging to our l...
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
bool IsArcSegment(size_t aSegment) const
bool IsClosed() const override
const std::vector< VECTOR2I > & CPoints() const
bool is_corner_their
Auxiliary flag to avoid copying intersection info to intersection refining code, used by the refining...
int Find(const VECTOR2I &aP, int aThreshold=0) const
Search for point aP.
void ClearArcs()
Remove all arc references in the line chain, resulting in a chain formed only of straight segments.
Represent a set of closed polygons.
std::vector< VECTOR2I > m_points
array of vertices
bool CheckClearance(const VECTOR2I &aP, const int aDist) const
Check if point aP is closer to (or on) an edge or vertex of the line chain.
virtual const SEG GetSegment(int aIndex) const override
bool Intersects(const SHAPE_LINE_CHAIN &aChain) const
int ShapeCount() const
Return the number of shapes (line segments or arcs) in this line chain.
bool IsSolid() const override
An abstract shape on 2D plane.
Definition: shape.h:116
void amendArcStart(size_t aArcIndex, const VECTOR2I &aNewStart)
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:363
void amendArc(size_t aArcIndex, const VECTOR2I &aNewStart, const VECTOR2I &aNewEnd)
const std::string Format() const override
void Remove(int aIndex)
Remove the aIndex-th point from the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
virtual const VECTOR2I GetPoint(int aIndex) const override
bool IsPtOnArc(size_t aPtIndex) const
CLIPPER_Z_VALUE(const std::pair< ssize_t, ssize_t > aShapeIndices, ssize_t aOffset=0)
SHAPE_LINE_CHAIN(const std::vector< wxPoint > &aV, bool aClosed=false)
void Rotate(double aAngle, const VECTOR2I &aCenter=VECTOR2I(0, 0)) override
Rotate all vertices by a given angle.
Definition: seg.h:40
std::vector< std::pair< ssize_t, 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 NearestSegment(const VECTOR2I &aP) const
Find the segment nearest the given point.
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:281
SEG Segment(int aIndex)
Return a copy of the aIndex-th segment in the line chain.
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=DefaultAccuracyForPCB(), double *aEffectiveAccuracy=nullptr) const
Construct a SHAPE_LINE_CHAIN of segments from a given arc.
Definition: shape_arc.cpp:498
int index_their
When true, the corner [index_our] of the 'our' line lies exactly on 'their' line.
bool is_corner_our
When true, the corner [index_their] of the 'their' line lies exactly on 'our' line.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
ssize_t reversedArcIndex(size_t aSegment) const
Return the arc index for the given segment index, looking backwards.
Represent a polyline (an zero-thickness chain of connected line segments).
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
bool IsArcEnd(size_t aIndex) const
line chain (polyline)
Definition: shape.h:45
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
boost::optional< T > OPT
Definition: optional.h:7
A dynamic state checking if a point lies within polygon with a dynamically built outline ( with each ...
BOX2I * GetCachedBBox() const override
void Clear()
Remove all points from the line chain.
SHAPE * Clone() const override
Return a dynamically allocated copy of the shape.
void GenerateBBoxCache() const
std::vector< VECTOR2I >::iterator point_iter
Holds information on each point of a SHAPE_LINE_CHAIN that is retrievable after an operation with Cli...
void Replace(int aStartIndex, int aEndIndex, const VECTOR2I &aP)
Replace points with indices in range [start_index, end_index] with a single point aP.
int NextShape(int aPointIndex, bool aForwards=true) const
Return the vertex index of the next shape in the chain, or -1 if aPointIndex is the last shape.
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT
void amendArcEnd(size_t aArcIndex, const VECTOR2I &aNewEnd)
int index_our
index of the intersecting corner/segment in the 'their' (Intersect() method parameter) line.
const VECTOR2I PointAlong(int aPathLength) const
bool processVertex(const VECTOR2I &ip, const VECTOR2I &ipNext)
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both).
bool CompareGeometry(const SHAPE_LINE_CHAIN &aOther) const