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 
335  int NextShape( int aPointIndex, bool aForwards = true ) const;
336 
337  int PrevShape( int aPointIndex ) const
338  {
339  return NextShape( aPointIndex, false );
340  }
341 
348  void SetPoint( int aIndex, const VECTOR2I& aPos );
349 
356  const VECTOR2I& CPoint( int aIndex ) const
357  {
358  if( aIndex < 0 )
359  aIndex += PointCount();
360  else if( aIndex >= PointCount() )
361  aIndex -= PointCount();
362 
363  return m_points[aIndex];
364  }
365 
366  const std::vector<VECTOR2I>& CPoints() const
367  {
368  return m_points;
369  }
370 
374  const VECTOR2I& CLastPoint() const
375  {
376  return m_points[static_cast<size_t>( PointCount() ) - 1];
377  }
378 
382  const std::vector<SHAPE_ARC>& CArcs() const
383  {
384  return m_arcs;
385  }
386 
390  const std::vector<std::pair<ssize_t, ssize_t>>& CShapes() const
391  {
392  return m_shapes;
393  }
394 
396  const BOX2I BBox( int aClearance = 0 ) const override
397  {
398  BOX2I bbox;
399  bbox.Compute( m_points );
400 
401  if( aClearance != 0 || m_width != 0 )
402  bbox.Inflate( aClearance + m_width );
403 
404  return bbox;
405  }
406 
407  void GenerateBBoxCache() const
408  {
410 
411  if( m_width != 0 )
413  }
414 
415  const BOX2I BBoxFromCache() const
416  {
417  return m_bbox;
418  }
419 
426  int Distance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
427 
433  const SHAPE_LINE_CHAIN Reverse() const;
434 
440  void ClearArcs();
441 
447  long long int Length() const;
448 
458  void Append( int aX, int aY, bool aAllowDuplication = false )
459  {
460  VECTOR2I v( aX, aY );
461  Append( v, aAllowDuplication );
462  }
463 
472  void Append( const VECTOR2I& aP, bool aAllowDuplication = false )
473  {
474  if( m_points.size() == 0 )
475  m_bbox = BOX2I( aP, VECTOR2I( 0, 0 ) );
476 
477  if( m_points.size() == 0 || aAllowDuplication || CPoint( -1 ) != aP )
478  {
479  m_points.push_back( aP );
480  m_shapes.push_back( SHAPES_ARE_PT );
481  m_bbox.Merge( aP );
482  }
483  }
484 
490  void Append( const SHAPE_LINE_CHAIN& aOtherLine );
491 
492  void Append( const SHAPE_ARC& aArc );
493 
494  void Insert( size_t aVertex, const VECTOR2I& aP );
495 
496  void Insert( size_t aVertex, const SHAPE_ARC& aArc );
497 
505  void Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP );
506 
515  void Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine );
516 
523  void Remove( int aStartIndex, int aEndIndex );
524 
530  void Remove( int aIndex )
531  {
532  Remove( aIndex, aIndex );
533  }
534 
543  void RemoveShape( int aPointIndex );
544 
552  int Split( const VECTOR2I& aP );
553 
560  int Find( const VECTOR2I& aP, int aThreshold = 0 ) const;
561 
568  int FindSegment( const VECTOR2I& aP, int aThreshold = 1 ) const;
569 
577  const SHAPE_LINE_CHAIN Slice( int aStartIndex, int aEndIndex = -1 ) const;
578 
580  {
581  compareOriginDistance( const VECTOR2I& aOrigin ):
582  m_origin( aOrigin )
583  {}
584 
585  bool operator()( const INTERSECTION& aA, const INTERSECTION& aB )
586  {
587  return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm();
588  }
589 
591  };
592 
593  bool Intersects( const SHAPE_LINE_CHAIN& aChain ) const;
594 
603  int Intersect( const SEG& aSeg, INTERSECTIONS& aIp ) const;
604 
613  int Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp,
614  bool aExcludeColinearAndTouching = false ) const;
615 
622  int PathLength( const VECTOR2I& aP, int aIndex = -1 ) const;
623 
631  bool CheckClearance( const VECTOR2I& aP, const int aDist) const;
632 
638  const OPT<INTERSECTION> SelfIntersecting() const;
639 
646  SHAPE_LINE_CHAIN& Simplify( bool aRemoveColinear = true );
647 
654  int NearestSegment( const VECTOR2I& aP ) const;
655 
664  const VECTOR2I NearestPoint( const VECTOR2I& aP, bool aAllowInternalShapePoints = true ) const;
665 
674  const VECTOR2I NearestPoint( const SEG& aSeg, int& dist ) const;
675 
677  const std::string Format() const override;
678 
680  bool Parse( std::stringstream& aStream ) override;
681 
682  bool operator!=( const SHAPE_LINE_CHAIN& aRhs ) const
683  {
684  if( PointCount() != aRhs.PointCount() )
685  return true;
686 
687  for( int i = 0; i < PointCount(); i++ )
688  {
689  if( CPoint( i ) != aRhs.CPoint( i ) )
690  return true;
691  }
692 
693  return false;
694  }
695 
696  bool CompareGeometry( const SHAPE_LINE_CHAIN& aOther ) const;
697 
698  void Move( const VECTOR2I& aVector ) override
699  {
700  for( auto& pt : m_points )
701  pt += aVector;
702 
703  for( auto& arc : m_arcs )
704  arc.Move( aVector );
705  }
706 
714  void Mirror( bool aX = true, bool aY = false, const VECTOR2I& aRef = { 0, 0 } );
715 
721  void Mirror( const SEG& axis );
722 
729  void Rotate( double aAngle, const VECTOR2I& aCenter = VECTOR2I( 0, 0 ) ) override;
730 
731  bool IsSolid() const override
732  {
733  return false;
734  }
735 
736  const VECTOR2I PointAlong( int aPathLength ) const;
737 
743  double Area( bool aAbsolute = true ) const;
744 
745  size_t ArcCount() const
746  {
747  return m_arcs.size();
748  }
749 
753  ssize_t ArcIndex( size_t aSegment ) const
754  {
755  if( IsSharedPt( aSegment ) )
756  return m_shapes[aSegment].second;
757  else
758  return m_shapes[aSegment].first;
759  }
760 
761  const SHAPE_ARC& Arc( size_t aArc ) const
762  {
763  return m_arcs[aArc];
764  }
765 
771  bool IsSharedPt( size_t aIndex ) const
772  {
773  return aIndex < m_shapes.size() - 1
774  && m_shapes[aIndex].first != SHAPE_IS_PT
775  && m_shapes[aIndex].second != SHAPE_IS_PT;
776  }
777 
778 
779  bool IsPtOnArc( size_t aPtIndex ) const
780  {
781  return aPtIndex < m_shapes.size() && m_shapes[aPtIndex] != SHAPES_ARE_PT;
782  }
783 
784 
785  bool IsArcSegment( size_t aSegment ) const
786  {
787  /*
788  * A segment is part of an arc except in the special case of two arcs next to each other
789  * but without a shared vertex. Here there is a segment between the end of the first arc
790  * and the start of the second arc.
791  */
792  size_t nextIdx = aSegment + 1;
793 
794  if( nextIdx > m_shapes.size() - 1 )
795  return false; // Always false, even if the shape is closed
796 
797  return ( IsPtOnArc( aSegment )
798  && ( IsSharedPt( aSegment )
799  || m_shapes[aSegment].first == m_shapes[nextIdx].first ) );
800  }
801 
802 
803  bool IsArcStart( size_t aIndex ) const
804  {
805  if( aIndex == 0 )
806  return IsPtOnArc( aIndex );
807 
808  return ( IsSharedPt( aIndex ) || ( IsPtOnArc( aIndex ) && !IsArcSegment( aIndex - 1 ) ) );
809  }
810 
811 
812  bool IsArcEnd( size_t aIndex ) const
813  {
814  if( aIndex == static_cast<size_t>( PointCount() ) - 1 )
815  return IsPtOnArc( aIndex );
816 
817  return ( IsSharedPt( aIndex ) || ( IsPtOnArc( aIndex ) && !IsArcSegment( aIndex ) ) );
818  }
819 
820  virtual const VECTOR2I GetPoint( int aIndex ) const override { return CPoint(aIndex); }
821  virtual const SEG GetSegment( int aIndex ) const override { return CSegment(aIndex); }
822  virtual size_t GetPointCount() const override { return PointCount(); }
823  virtual size_t GetSegmentCount() const override { return SegmentCount(); }
824 
825 protected:
826  friend class SHAPE_POLY_SET;
827 
833  void convertArc( ssize_t aArcIndex );
834 
847  void splitArc( ssize_t aPtIndex, bool aCoincident = false );
848 
849  void amendArc( size_t aArcIndex, const VECTOR2I& aNewStart, const VECTOR2I& aNewEnd );
850 
851  void amendArcStart( size_t aArcIndex, const VECTOR2I& aNewStart )
852  {
853  amendArc( aArcIndex, aNewStart, m_arcs[aArcIndex].GetP1() );
854  }
855 
856  void amendArcEnd( size_t aArcIndex, const VECTOR2I& aNewEnd )
857  {
858  amendArc( aArcIndex, m_arcs[aArcIndex].GetP0(), aNewEnd );
859  }
860 
864  ClipperLib::Path convertToClipper( bool aRequiredOrientation,
865  std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
866  std::vector<SHAPE_ARC>& aArcBuffer ) const;
867 
868 private:
869 
870  static const ssize_t SHAPE_IS_PT;
871 
872  static const std::pair<ssize_t, ssize_t> SHAPES_ARE_PT;
873 
875  std::vector<VECTOR2I> m_points;
876 
891  std::vector<std::pair<ssize_t, ssize_t>> m_shapes;
892 
893  std::vector<SHAPE_ARC> m_arcs;
894 
896  bool m_closed;
897 
903  int m_width;
904 
906  mutable BOX2I m_bbox;
907 };
908 
909 
910 #endif // __SHAPE_LINE_CHAIN
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148
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:459
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.
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 ...
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 aPoint is in the last shape.
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT
void amendArcEnd(size_t aArcIndex, const VECTOR2I &aNewEnd)
const BOX2I BBoxFromCache() const
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