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 <[email protected]>
6 * Copyright (C) 2013-2022 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 <clipper2/clipper.h>
32#include <geometry/seg.h>
33#include <geometry/shape.h>
34#include <geometry/shape_arc.h>
35#include <math/vector2d.h>
36
42{
44 {
45 m_FirstArcIdx = -1;
46 m_SecondArcIdx = -1;
47 }
48
49 CLIPPER_Z_VALUE( const std::pair<ssize_t, ssize_t> aShapeIndices, ssize_t aOffset = 0 )
50 {
51 m_FirstArcIdx = aShapeIndices.first;
52 m_SecondArcIdx = aShapeIndices.second;
53
54 auto offsetVal = [&]( ssize_t& aVal )
55 {
56 if( aVal >= 0 )
57 aVal += aOffset;
58 };
59
60 offsetVal( m_FirstArcIdx );
61 offsetVal( m_SecondArcIdx );
62 }
63
66};
67
68
82{
83private:
84 typedef std::vector<VECTOR2I>::iterator point_iter;
85 typedef std::vector<VECTOR2I>::const_iterator point_citer;
86
87public:
92 {
95
98
102
105
110
114 bool valid;
115
117 index_our( -1 ),
118 index_their( -1 ),
119 is_corner_our( false ),
120 is_corner_their( false ),
121 valid( false )
122 {
123 }
124 };
125
126
132 {
133 public:
134 POINT_INSIDE_TRACKER( const VECTOR2I& aPoint );
135
136 void AddPolyline( const SHAPE_LINE_CHAIN& aPolyline );
137 bool IsInside();
138
139 private:
140
141 bool processVertex ( const VECTOR2I& ip, const VECTOR2I& ipNext );
142
149 };
150
151 typedef std::vector<INTERSECTION> INTERSECTIONS;
152
153
159 m_closed( false ),
160 m_width( 0 )
161 {}
162
165 m_points( aShape.m_points ),
166 m_shapes( aShape.m_shapes ),
167 m_arcs( aShape.m_arcs ),
168 m_closed( aShape.m_closed ),
169 m_width( aShape.m_width ),
170 m_bbox( aShape.m_bbox )
171 {}
172
173 SHAPE_LINE_CHAIN( const std::vector<int>& aV );
174
175 SHAPE_LINE_CHAIN( const std::vector<VECTOR2I>& aV, bool aClosed = false ) :
177 m_closed( aClosed ),
178 m_width( 0 )
179 {
180 m_points = aV;
181 m_shapes = std::vector<std::pair<ssize_t, ssize_t>>( aV.size(), SHAPES_ARE_PT );
182 }
183
184 SHAPE_LINE_CHAIN( const SHAPE_ARC& aArc, bool aClosed = false ) :
186 m_closed( aClosed ),
187 m_width( 0 )
188 {
190 m_arcs.emplace_back( aArc );
191 m_arcs.back().SetWidth( 0 );
192 m_shapes = std::vector<std::pair<ssize_t, ssize_t>>( m_points.size(), { 0, SHAPE_IS_PT } );
193 }
194
195 SHAPE_LINE_CHAIN( const ClipperLib::Path& aPath,
196 const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
197 const std::vector<SHAPE_ARC>& aArcBuffer );
198
199 SHAPE_LINE_CHAIN( const Clipper2Lib::Path64& aPath,
200 const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
201 const std::vector<SHAPE_ARC>& aArcBuffer );
202
204 {}
205
218 virtual bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr,
219 VECTOR2I* aLocation = nullptr ) const override;
220
233 virtual bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr,
234 VECTOR2I* aLocation = nullptr ) const override;
235
237
238 SHAPE* Clone() const override;
239
243 void Clear()
244 {
245 m_points.clear();
246 m_arcs.clear();
247 m_shapes.clear();
248 m_closed = false;
249 }
250
257 void SetClosed( bool aClosed )
258 {
259 m_closed = aClosed;
261 }
262
266 bool IsClosed() const override
267 {
268 return m_closed;
269 }
270
276 void SetWidth( int aWidth )
277 {
278 m_width = aWidth;
279 }
280
286 int Width() const
287 {
288 return m_width;
289 }
290
296 int SegmentCount() const
297 {
298 int c = m_points.size() - 1;
299
300 if( m_closed )
301 c++;
302
303 return std::max( 0, c );
304 }
305
313 int ShapeCount() const;
314
320 int PointCount() const
321 {
322 return m_points.size();
323 }
324
332 SEG Segment( int aIndex )
333 {
334 if( aIndex < 0 )
335 aIndex += SegmentCount();
336
337 if( aIndex == (int)( m_points.size() - 1 ) && m_closed )
338 return SEG( m_points[aIndex], m_points[0], aIndex );
339 else
340 return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
341 }
342
350 const SEG CSegment( int aIndex ) const
351 {
352 if( aIndex < 0 )
353 aIndex += SegmentCount();
354
355 if( aIndex == (int)( m_points.size() - 1 ) && m_closed )
356 return SEG( m_points[aIndex], m_points[0], aIndex );
357 else
358 return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
359 }
360
374 int NextShape( int aPointIndex, bool aForwards = true ) const;
375
376 int PrevShape( int aPointIndex ) const
377 {
378 return NextShape( aPointIndex, false );
379 }
380
387 void SetPoint( int aIndex, const VECTOR2I& aPos );
388
395 const VECTOR2I& CPoint( int aIndex ) const
396 {
397 if( aIndex < 0 )
398 aIndex += PointCount();
399 else if( aIndex >= PointCount() )
400 aIndex -= PointCount();
401
402 return m_points[aIndex];
403 }
404
405 const std::vector<VECTOR2I>& CPoints() const
406 {
407 return m_points;
408 }
409
413 const VECTOR2I& CLastPoint() const
414 {
415 return m_points[static_cast<size_t>( PointCount() ) - 1];
416 }
417
421 const std::vector<SHAPE_ARC>& CArcs() const
422 {
423 return m_arcs;
424 }
425
429 const std::vector<std::pair<ssize_t, ssize_t>>& CShapes() const
430 {
431 return m_shapes;
432 }
433
435 const BOX2I BBox( int aClearance = 0 ) const override
436 {
437 BOX2I bbox;
438 bbox.Compute( m_points );
439
440 if( aClearance != 0 || m_width != 0 )
441 bbox.Inflate( aClearance + m_width );
442
443 return bbox;
444 }
445
446 void GenerateBBoxCache() const
447 {
449
450 if( m_width != 0 )
452 }
453
454 BOX2I* GetCachedBBox() const override
455 {
456 return &m_bbox;
457 }
458
465 int Distance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
466
472 const SHAPE_LINE_CHAIN Reverse() const;
473
479 void ClearArcs();
480
486 long long int Length() const;
487
497 void Append( int aX, int aY, bool aAllowDuplication = false )
498 {
499 VECTOR2I v( aX, aY );
500 Append( v, aAllowDuplication );
501 }
502
511 void Append( const VECTOR2I& aP, bool aAllowDuplication = false )
512 {
513 if( m_points.size() == 0 )
514 m_bbox = BOX2I( aP, VECTOR2I( 0, 0 ) );
515
516 if( m_points.size() == 0 || aAllowDuplication || CPoint( -1 ) != aP )
517 {
518 m_points.push_back( aP );
519 m_shapes.push_back( SHAPES_ARE_PT );
520 m_bbox.Merge( aP );
521 }
522 }
523
529 void Append( const SHAPE_LINE_CHAIN& aOtherLine );
530
531 void Append( const SHAPE_ARC& aArc );
532 void Append( const SHAPE_ARC& aArc, double aAccuracy );
533
534 void Insert( size_t aVertex, const VECTOR2I& aP );
535
536 void Insert( size_t aVertex, const SHAPE_ARC& aArc );
537
545 void Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP );
546
555 void Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine );
556
563 void Remove( int aStartIndex, int aEndIndex );
564
570 void Remove( int aIndex )
571 {
572 Remove( aIndex, aIndex );
573 }
574
583 void RemoveShape( int aPointIndex );
584
592 int Split( const VECTOR2I& aP );
593
600 int Find( const VECTOR2I& aP, int aThreshold = 0 ) const;
601
608 int FindSegment( const VECTOR2I& aP, int aThreshold = 1 ) const;
609
617 const SHAPE_LINE_CHAIN Slice( int aStartIndex, int aEndIndex = -1 ) const;
618
620 {
622 m_origin( aOrigin )
623 {}
624
625 bool operator()( const INTERSECTION& aA, const INTERSECTION& aB )
626 {
627 return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm();
628 }
629
631 };
632
633 bool Intersects( const SHAPE_LINE_CHAIN& aChain ) const;
634
643 int Intersect( const SEG& aSeg, INTERSECTIONS& aIp ) const;
644
653 int Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp,
654 bool aExcludeColinearAndTouching = false,
655 BOX2I* aChainBBox = nullptr ) const;
656
663 int PathLength( const VECTOR2I& aP, int aIndex = -1 ) const;
664
672 bool CheckClearance( const VECTOR2I& aP, const int aDist) const;
673
679 const std::optional<INTERSECTION> SelfIntersecting() const;
680
687 SHAPE_LINE_CHAIN& Simplify( bool aRemoveColinear = true );
688
695 int NearestSegment( const VECTOR2I& aP ) const;
696
705 const VECTOR2I NearestPoint( const VECTOR2I& aP, bool aAllowInternalShapePoints = true ) const;
706
715 const VECTOR2I NearestPoint( const SEG& aSeg, int& dist ) const;
716
718 const std::string Format( bool aCplusPlus = true ) const override;
719
721 bool Parse( std::stringstream& aStream ) override;
722
723 bool operator!=( const SHAPE_LINE_CHAIN& aRhs ) const
724 {
725 if( PointCount() != aRhs.PointCount() )
726 return true;
727
728 for( int i = 0; i < PointCount(); i++ )
729 {
730 if( CPoint( i ) != aRhs.CPoint( i ) )
731 return true;
732 }
733
734 return false;
735 }
736
737 bool CompareGeometry( const SHAPE_LINE_CHAIN& aOther ) const;
738
739 void Move( const VECTOR2I& aVector ) override
740 {
741 for( auto& pt : m_points )
742 pt += aVector;
743
744 for( auto& arc : m_arcs )
745 arc.Move( aVector );
746
747 m_bbox.Move( aVector );
748 }
749
757 void Mirror( bool aX = true, bool aY = false, const VECTOR2I& aRef = { 0, 0 } );
758
764 void Mirror( const SEG& axis );
765
772 void Rotate( const EDA_ANGLE& aAngle, const VECTOR2I& aCenter = { 0, 0 } ) override;
773
774 bool IsSolid() const override
775 {
776 return false;
777 }
778
779 const VECTOR2I PointAlong( int aPathLength ) const;
780
786 double Area( bool aAbsolute = true ) const;
787
788 size_t ArcCount() const
789 {
790 return m_arcs.size();
791 }
792
796 ssize_t ArcIndex( size_t aSegment ) const
797 {
798 if( IsSharedPt( aSegment ) )
799 return m_shapes[aSegment].second;
800 else
801 return m_shapes[aSegment].first;
802 }
803
804 const SHAPE_ARC& Arc( size_t aArc ) const
805 {
806 return m_arcs[aArc];
807 }
808
814 bool IsSharedPt( size_t aIndex ) const
815 {
816 return aIndex < m_shapes.size()
817 && m_shapes[aIndex].first != SHAPE_IS_PT
818 && m_shapes[aIndex].second != SHAPE_IS_PT;
819 }
820
821
822 bool IsPtOnArc( size_t aPtIndex ) const
823 {
824 return aPtIndex < m_shapes.size() && m_shapes[aPtIndex] != SHAPES_ARE_PT;
825 }
826
827
828 bool IsArcSegment( size_t aSegment ) const
829 {
830 /*
831 * A segment is part of an arc except in the special case of two arcs next to each other
832 * but without a shared vertex. Here there is a segment between the end of the first arc
833 * and the start of the second arc.
834 */
835 size_t nextIdx = aSegment + 1;
836
837 if( nextIdx > m_shapes.size() - 1 )
838 {
839 if( nextIdx == m_shapes.size() && m_closed )
840 nextIdx = 0; // segment between end point and first point
841 else
842 return false;
843 }
844
845 return ( IsPtOnArc( aSegment )
846 && ( IsSharedPt( aSegment )
847 || m_shapes[aSegment].first == m_shapes[nextIdx].first ) );
848 }
849
850
851 bool IsArcStart( size_t aIndex ) const
852 {
853 if( aIndex == 0 )
854 return IsPtOnArc( aIndex );
855
856 return ( IsSharedPt( aIndex ) || ( IsPtOnArc( aIndex ) && !IsArcSegment( aIndex - 1 ) ) );
857 }
858
859
860 bool IsArcEnd( size_t aIndex ) const
861 {
862 return ( IsSharedPt( aIndex ) || ( IsPtOnArc( aIndex ) && !IsArcSegment( aIndex ) ) );
863 }
864
865 virtual const VECTOR2I GetPoint( int aIndex ) const override { return CPoint(aIndex); }
866 virtual const SEG GetSegment( int aIndex ) const override { return CSegment(aIndex); }
867 virtual size_t GetPointCount() const override { return PointCount(); }
868 virtual size_t GetSegmentCount() const override { return SegmentCount(); }
869
870protected:
871 friend class SHAPE_POLY_SET;
872
878 void convertArc( ssize_t aArcIndex );
879
892 void splitArc( ssize_t aPtIndex, bool aCoincident = false );
893
894 void amendArc( size_t aArcIndex, const VECTOR2I& aNewStart, const VECTOR2I& aNewEnd );
895
896 void amendArcStart( size_t aArcIndex, const VECTOR2I& aNewStart )
897 {
898 amendArc( aArcIndex, aNewStart, m_arcs[aArcIndex].GetP1() );
899 }
900
901 void amendArcEnd( size_t aArcIndex, const VECTOR2I& aNewEnd )
902 {
903 amendArc( aArcIndex, m_arcs[aArcIndex].GetP0(), aNewEnd );
904 }
905
909 ssize_t reversedArcIndex( size_t aSegment ) const
910 {
911 if( IsSharedPt( aSegment ) )
912 return m_shapes[aSegment].first;
913 else
914 return m_shapes[aSegment].second;
915 }
916
920 ClipperLib::Path convertToClipper( bool aRequiredOrientation,
921 std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
922 std::vector<SHAPE_ARC>& aArcBuffer ) const;
923
927 Clipper2Lib::Path64 convertToClipper2( bool aRequiredOrientation,
928 std::vector<CLIPPER_Z_VALUE> &aZValueBuffer,
929 std::vector<SHAPE_ARC> &aArcBuffer ) const;
930
934 void fixIndicesRotation();
935
940
941private:
942
943 static const ssize_t SHAPE_IS_PT;
944
945 static const std::pair<ssize_t, ssize_t> SHAPES_ARE_PT;
946
948 std::vector<VECTOR2I> m_points;
949
964 std::vector<std::pair<ssize_t, ssize_t>> m_shapes;
965
966 std::vector<SHAPE_ARC> m_arcs;
967
970
977
979 mutable BOX2I m_bbox;
980};
981
982
983#endif // __SHAPE_LINE_CHAIN
BOX2< VECTOR2I > BOX2I
Definition: box2.h:847
void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
Definition: box2.h:111
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:506
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Definition: box2.h:82
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:588
Definition: seg.h:42
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:470
A dynamic state checking if a point lies within polygon with a dynamically built outline ( with each ...
bool processVertex(const VECTOR2I &ip, const VECTOR2I &ipNext)
void AddPolyline(const SHAPE_LINE_CHAIN &aPolyline)
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
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,...
const SHAPE_LINE_CHAIN Reverse() const
Reverse point order in the line chain.
void Move(const VECTOR2I &aVector) override
bool IsPtOnArc(size_t aPtIndex) const
void amendArcStart(size_t aArcIndex, const VECTOR2I &aNewStart)
void Remove(int aIndex)
Remove the aIndex-th point from the line chain.
void amendArcEnd(size_t aArcIndex, const VECTOR2I &aNewEnd)
int Width() const
Get the current width of the segments in the chain.
const SHAPE_ARC & Arc(size_t aArc) const
void splitArc(ssize_t aPtIndex, bool aCoincident=false)
Splits an arc into two arcs at aPtIndex.
void Append(const VECTOR2I &aP, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const std::optional< INTERSECTION > SelfIntersecting() const
Check if the line chain is self-intersecting.
bool Parse(std::stringstream &aStream) override
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.
std::vector< SHAPE_ARC > m_arcs
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
bool IsClosed() const override
virtual const VECTOR2I GetPoint(int aIndex) const override
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.
void SetPoint(int aIndex, const VECTOR2I &aPos)
Move a point to a specific location.
const VECTOR2I PointAlong(int aPathLength) const
int Split(const VECTOR2I &aP)
Insert the point aP belonging to one of the our segments, splitting the adjacent segment in two.
int PrevShape(int aPointIndex) const
SHAPE_LINE_CHAIN & operator=(const SHAPE_LINE_CHAIN &)=default
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.
void fixIndicesRotation()
Fix indices of this chain to ensure arcs are not split between the end and start indices.
std::vector< VECTOR2I > m_points
array of vertices
void GenerateBBoxCache() const
int FindSegment(const VECTOR2I &aP, int aThreshold=1) const
Search for segment containing point aP.
int ShapeCount() const
Return the number of shapes (line segments or arcs) in this line chain.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
ssize_t reversedArcIndex(size_t aSegment) const
Return the arc index for the given segment index, looking backwards.
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Find all intersection points between our line chain and the segment aSeg.
bool Intersects(const SHAPE_LINE_CHAIN &aChain) const
SHAPE_LINE_CHAIN()
Initialize an empty line chain.
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
virtual ~SHAPE_LINE_CHAIN()
int PointCount() const
Return the number of points (vertices) in this line chain.
bool IsArcEnd(size_t aIndex) const
void Replace(int aStartIndex, int aEndIndex, const VECTOR2I &aP)
Replace points with indices in range [start_index, end_index] with a single point aP.
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.
void ClearArcs()
Remove all arc references in the line chain, resulting in a chain formed only of straight segments.
void mergeFirstLastPointIfNeeded()
Merge the first and last point if they are the same and this chain is closed.
bool CompareGeometry(const SHAPE_LINE_CHAIN &aOther) const
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
void Clear()
Remove all points from the line chain.
SHAPE_LINE_CHAIN(const SHAPE_ARC &aArc, bool aClosed=false)
BOX2I m_bbox
cached bounding box
BOX2I * GetCachedBBox() const override
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.
bool m_closed
is the line chain closed?
const std::vector< SHAPE_ARC > & CArcs() const
int NearestSegment(const VECTOR2I &aP) const
Find the segment nearest the given point.
double Area(bool aAbsolute=true) const
Return the area of this chain.
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both).
void amendArc(size_t aArcIndex, const VECTOR2I &aNewStart, const VECTOR2I &aNewEnd)
virtual size_t GetPointCount() const override
SHAPE_LINE_CHAIN(const std::vector< VECTOR2I > &aV, bool aClosed=false)
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
virtual const SEG GetSegment(int aIndex) const override
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
bool operator!=(const SHAPE_LINE_CHAIN &aRhs) const
const std::vector< std::pair< ssize_t, ssize_t > > & CShapes() const
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
std::vector< VECTOR2I >::iterator point_iter
int SegmentCount() const
Return the number of segments in this line chain.
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...
int Distance(const VECTOR2I &aP, bool aOutlineOnly=false) const
Compute the minimum distance between the line chain and a point aP.
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
const std::string Format(bool aCplusPlus=true) const override
SHAPE_LINE_CHAIN(const SHAPE_LINE_CHAIN &aShape)
Clipper2Lib::Path64 convertToClipper2(bool aRequiredOrientation, std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, std::vector< SHAPE_ARC > &aArcBuffer) const
Create a new Clipper2 path from the SHAPE_LINE_CHAIN in a given orientation.
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT
void convertArc(ssize_t aArcIndex)
Convert an arc to only a point chain by removing the arc and references.
virtual size_t GetSegmentCount() const override
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
size_t ArcCount() const
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
bool IsArcSegment(size_t aSegment) const
void RemoveShape(int aPointIndex)
Remove the shape at the given index from the line chain.
void Insert(size_t aVertex, const VECTOR2I &aP)
bool IsArcStart(size_t aIndex) const
void SetWidth(int aWidth)
Set the width of all segments in the chain.
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.
std::vector< INTERSECTION > INTERSECTIONS
long long int Length() const
Return length of the line chain in Euclidean metric.
int Find(const VECTOR2I &aP, int aThreshold=0) const
Search for point aP.
const std::vector< VECTOR2I > & CPoints() const
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
std::vector< VECTOR2I >::const_iterator point_citer
SHAPE * Clone() const override
Return a dynamically allocated copy of the shape.
bool IsSolid() const override
static const ssize_t SHAPE_IS_PT
SEG Segment(int aIndex)
Return a copy of the aIndex-th segment in the line chain.
Represent a set of closed polygons.
An abstract shape on 2D plane.
Definition: shape.h:123
@ SH_LINE_CHAIN
line chain (polyline)
Definition: shape.h:46
Holds information on each point of a SHAPE_LINE_CHAIN that is retrievable after an operation with Cli...
CLIPPER_Z_VALUE(const std::pair< ssize_t, ssize_t > aShapeIndices, ssize_t aOffset=0)
Represent an intersection between two line segments.
bool is_corner_their
Auxiliary flag to avoid copying intersection info to intersection refining code, used by the refining...
bool is_corner_our
When true, the corner [index_their] of the 'their' line lies exactly on 'our' line.
int index_our
index of the intersecting corner/segment in the 'their' (Intersect() method parameter) line.
VECTOR2I p
< Point of intersection between our and their.
int index_their
When true, the corner [index_our] of the 'our' line lies exactly on 'their' line.
compareOriginDistance(const VECTOR2I &aOrigin)
bool operator()(const INTERSECTION &aA, const INTERSECTION &aB)
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:129
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618