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 <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
65};
66
67
81{
82private:
83 typedef std::vector<VECTOR2I>::iterator point_iter;
84 typedef std::vector<VECTOR2I>::const_iterator point_citer;
85
86public:
91 {
94
97
101
104
109
113 bool valid;
114
116 index_our( -1 ),
117 index_their( -1 ),
118 is_corner_our( false ),
119 is_corner_their( false ),
120 valid( false )
121 {
122 }
123 };
124
125
131 {
132 public:
133 POINT_INSIDE_TRACKER( const VECTOR2I& aPoint );
134
135 void AddPolyline( const SHAPE_LINE_CHAIN& aPolyline );
136 bool IsInside();
137
138 private:
139
140 bool processVertex ( const VECTOR2I& ip, const VECTOR2I& ipNext );
141
148 };
149
150 typedef std::vector<INTERSECTION> INTERSECTIONS;
151
152
158 m_closed( false ),
159 m_width( 0 )
160 {}
161
164 m_points( aShape.m_points ),
165 m_shapes( aShape.m_shapes ),
166 m_arcs( aShape.m_arcs ),
167 m_closed( aShape.m_closed ),
168 m_width( aShape.m_width ),
169 m_bbox( aShape.m_bbox )
170 {}
171
172 SHAPE_LINE_CHAIN( const std::vector<int>& aV );
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_arcs.back().SetWidth( 0 );
191 m_shapes = std::vector<std::pair<ssize_t, ssize_t>>( m_points.size(), { 0, SHAPE_IS_PT } );
192 }
193
194 SHAPE_LINE_CHAIN( const ClipperLib::Path& aPath,
195 const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
196 const std::vector<SHAPE_ARC>& aArcBuffer );
197
199 {}
200
213 virtual bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr,
214 VECTOR2I* aLocation = nullptr ) const override;
215
228 virtual bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr,
229 VECTOR2I* aLocation = nullptr ) const override;
230
232
233 SHAPE* Clone() const override;
234
238 void Clear()
239 {
240 m_points.clear();
241 m_arcs.clear();
242 m_shapes.clear();
243 m_closed = false;
244 }
245
252 void SetClosed( bool aClosed )
253 {
254 m_closed = aClosed;
256 }
257
261 bool IsClosed() const override
262 {
263 return m_closed;
264 }
265
271 void SetWidth( int aWidth )
272 {
273 m_width = aWidth;
274 }
275
281 int Width() const
282 {
283 return m_width;
284 }
285
291 int SegmentCount() const
292 {
293 int c = m_points.size() - 1;
294
295 if( m_closed )
296 c++;
297
298 return std::max( 0, c );
299 }
300
308 int ShapeCount() const;
309
315 int PointCount() const
316 {
317 return m_points.size();
318 }
319
327 SEG Segment( int aIndex )
328 {
329 if( aIndex < 0 )
330 aIndex += SegmentCount();
331
332 if( aIndex == (int)( m_points.size() - 1 ) && m_closed )
333 return SEG( m_points[aIndex], m_points[0], aIndex );
334 else
335 return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
336 }
337
345 const SEG CSegment( int aIndex ) const
346 {
347 if( aIndex < 0 )
348 aIndex += SegmentCount();
349
350 if( aIndex == (int)( m_points.size() - 1 ) && m_closed )
351 return SEG( m_points[aIndex], m_points[0], aIndex );
352 else
353 return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
354 }
355
369 int NextShape( int aPointIndex, bool aForwards = true ) const;
370
371 int PrevShape( int aPointIndex ) const
372 {
373 return NextShape( aPointIndex, false );
374 }
375
382 void SetPoint( int aIndex, const VECTOR2I& aPos );
383
390 const VECTOR2I& CPoint( int aIndex ) const
391 {
392 if( aIndex < 0 )
393 aIndex += PointCount();
394 else if( aIndex >= PointCount() )
395 aIndex -= PointCount();
396
397 return m_points[aIndex];
398 }
399
400 const std::vector<VECTOR2I>& CPoints() const
401 {
402 return m_points;
403 }
404
408 const VECTOR2I& CLastPoint() const
409 {
410 return m_points[static_cast<size_t>( PointCount() ) - 1];
411 }
412
416 const std::vector<SHAPE_ARC>& CArcs() const
417 {
418 return m_arcs;
419 }
420
424 const std::vector<std::pair<ssize_t, ssize_t>>& CShapes() const
425 {
426 return m_shapes;
427 }
428
430 const BOX2I BBox( int aClearance = 0 ) const override
431 {
432 BOX2I bbox;
433 bbox.Compute( m_points );
434
435 if( aClearance != 0 || m_width != 0 )
436 bbox.Inflate( aClearance + m_width );
437
438 return bbox;
439 }
440
441 void GenerateBBoxCache() const
442 {
444
445 if( m_width != 0 )
447 }
448
449 BOX2I* GetCachedBBox() const override
450 {
451 return &m_bbox;
452 }
453
460 int Distance( const VECTOR2I& aP, bool aOutlineOnly = false ) const;
461
467 const SHAPE_LINE_CHAIN Reverse() const;
468
474 void ClearArcs();
475
481 long long int Length() const;
482
492 void Append( int aX, int aY, bool aAllowDuplication = false )
493 {
494 VECTOR2I v( aX, aY );
495 Append( v, aAllowDuplication );
496 }
497
506 void Append( const VECTOR2I& aP, bool aAllowDuplication = false )
507 {
508 if( m_points.size() == 0 )
509 m_bbox = BOX2I( aP, VECTOR2I( 0, 0 ) );
510
511 if( m_points.size() == 0 || aAllowDuplication || CPoint( -1 ) != aP )
512 {
513 m_points.push_back( aP );
514 m_shapes.push_back( SHAPES_ARE_PT );
515 m_bbox.Merge( aP );
516 }
517 }
518
524 void Append( const SHAPE_LINE_CHAIN& aOtherLine );
525
526 void Append( const SHAPE_ARC& aArc );
527
528 void Insert( size_t aVertex, const VECTOR2I& aP );
529
530 void Insert( size_t aVertex, const SHAPE_ARC& aArc );
531
539 void Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP );
540
549 void Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine );
550
557 void Remove( int aStartIndex, int aEndIndex );
558
564 void Remove( int aIndex )
565 {
566 Remove( aIndex, aIndex );
567 }
568
577 void RemoveShape( int aPointIndex );
578
586 int Split( const VECTOR2I& aP );
587
594 int Find( const VECTOR2I& aP, int aThreshold = 0 ) const;
595
602 int FindSegment( const VECTOR2I& aP, int aThreshold = 1 ) const;
603
611 const SHAPE_LINE_CHAIN Slice( int aStartIndex, int aEndIndex = -1 ) const;
612
614 {
616 m_origin( aOrigin )
617 {}
618
619 bool operator()( const INTERSECTION& aA, const INTERSECTION& aB )
620 {
621 return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm();
622 }
623
625 };
626
627 bool Intersects( const SHAPE_LINE_CHAIN& aChain ) const;
628
637 int Intersect( const SEG& aSeg, INTERSECTIONS& aIp ) const;
638
647 int Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp,
648 bool aExcludeColinearAndTouching = false,
649 BOX2I* aChainBBox = nullptr ) const;
650
657 int PathLength( const VECTOR2I& aP, int aIndex = -1 ) const;
658
666 bool CheckClearance( const VECTOR2I& aP, const int aDist) const;
667
673 const std::optional<INTERSECTION> SelfIntersecting() const;
674
681 SHAPE_LINE_CHAIN& Simplify( bool aRemoveColinear = true );
682
689 int NearestSegment( const VECTOR2I& aP ) const;
690
699 const VECTOR2I NearestPoint( const VECTOR2I& aP, bool aAllowInternalShapePoints = true ) const;
700
709 const VECTOR2I NearestPoint( const SEG& aSeg, int& dist ) const;
710
712 const std::string Format() const override;
713
715 bool Parse( std::stringstream& aStream ) override;
716
717 bool operator!=( const SHAPE_LINE_CHAIN& aRhs ) const
718 {
719 if( PointCount() != aRhs.PointCount() )
720 return true;
721
722 for( int i = 0; i < PointCount(); i++ )
723 {
724 if( CPoint( i ) != aRhs.CPoint( i ) )
725 return true;
726 }
727
728 return false;
729 }
730
731 bool CompareGeometry( const SHAPE_LINE_CHAIN& aOther ) const;
732
733 void Move( const VECTOR2I& aVector ) override
734 {
735 for( auto& pt : m_points )
736 pt += aVector;
737
738 for( auto& arc : m_arcs )
739 arc.Move( aVector );
740 }
741
749 void Mirror( bool aX = true, bool aY = false, const VECTOR2I& aRef = { 0, 0 } );
750
756 void Mirror( const SEG& axis );
757
764 void Rotate( const EDA_ANGLE& aAngle, const VECTOR2I& aCenter = { 0, 0 } ) override;
765
766 bool IsSolid() const override
767 {
768 return false;
769 }
770
771 const VECTOR2I PointAlong( int aPathLength ) const;
772
778 double Area( bool aAbsolute = true ) const;
779
780 size_t ArcCount() const
781 {
782 return m_arcs.size();
783 }
784
788 ssize_t ArcIndex( size_t aSegment ) const
789 {
790 if( IsSharedPt( aSegment ) )
791 return m_shapes[aSegment].second;
792 else
793 return m_shapes[aSegment].first;
794 }
795
796 const SHAPE_ARC& Arc( size_t aArc ) const
797 {
798 return m_arcs[aArc];
799 }
800
806 bool IsSharedPt( size_t aIndex ) const
807 {
808 return aIndex < m_shapes.size()
809 && m_shapes[aIndex].first != SHAPE_IS_PT
810 && m_shapes[aIndex].second != SHAPE_IS_PT;
811 }
812
813
814 bool IsPtOnArc( size_t aPtIndex ) const
815 {
816 return aPtIndex < m_shapes.size() && m_shapes[aPtIndex] != SHAPES_ARE_PT;
817 }
818
819
820 bool IsArcSegment( size_t aSegment ) const
821 {
822 /*
823 * A segment is part of an arc except in the special case of two arcs next to each other
824 * but without a shared vertex. Here there is a segment between the end of the first arc
825 * and the start of the second arc.
826 */
827 size_t nextIdx = aSegment + 1;
828
829 if( nextIdx > m_shapes.size() - 1 )
830 {
831 if( nextIdx == m_shapes.size() && m_closed )
832 nextIdx = 0; // segment between end point and first point
833 else
834 return false;
835 }
836
837 return ( IsPtOnArc( aSegment )
838 && ( IsSharedPt( aSegment )
839 || m_shapes[aSegment].first == m_shapes[nextIdx].first ) );
840 }
841
842
843 bool IsArcStart( size_t aIndex ) const
844 {
845 if( aIndex == 0 )
846 return IsPtOnArc( aIndex );
847
848 return ( IsSharedPt( aIndex ) || ( IsPtOnArc( aIndex ) && !IsArcSegment( aIndex - 1 ) ) );
849 }
850
851
852 bool IsArcEnd( size_t aIndex ) const
853 {
854 return ( IsSharedPt( aIndex ) || ( IsPtOnArc( aIndex ) && !IsArcSegment( aIndex ) ) );
855 }
856
857 virtual const VECTOR2I GetPoint( int aIndex ) const override { return CPoint(aIndex); }
858 virtual const SEG GetSegment( int aIndex ) const override { return CSegment(aIndex); }
859 virtual size_t GetPointCount() const override { return PointCount(); }
860 virtual size_t GetSegmentCount() const override { return SegmentCount(); }
861
862protected:
863 friend class SHAPE_POLY_SET;
864
870 void convertArc( ssize_t aArcIndex );
871
884 void splitArc( ssize_t aPtIndex, bool aCoincident = false );
885
886 void amendArc( size_t aArcIndex, const VECTOR2I& aNewStart, const VECTOR2I& aNewEnd );
887
888 void amendArcStart( size_t aArcIndex, const VECTOR2I& aNewStart )
889 {
890 amendArc( aArcIndex, aNewStart, m_arcs[aArcIndex].GetP1() );
891 }
892
893 void amendArcEnd( size_t aArcIndex, const VECTOR2I& aNewEnd )
894 {
895 amendArc( aArcIndex, m_arcs[aArcIndex].GetP0(), aNewEnd );
896 }
897
901 ssize_t reversedArcIndex( size_t aSegment ) const
902 {
903 if( IsSharedPt( aSegment ) )
904 return m_shapes[aSegment].first;
905 else
906 return m_shapes[aSegment].second;
907 }
908
912 ClipperLib::Path convertToClipper( bool aRequiredOrientation,
913 std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
914 std::vector<SHAPE_ARC>& aArcBuffer ) const;
915
919 void fixIndicesRotation();
920
925
926private:
927
928 static const ssize_t SHAPE_IS_PT;
929
930 static const std::pair<ssize_t, ssize_t> SHAPES_ARE_PT;
931
933 std::vector<VECTOR2I> m_points;
934
949 std::vector<std::pair<ssize_t, ssize_t>> m_shapes;
950
951 std::vector<SHAPE_ARC> m_arcs;
952
955
962
964 mutable BOX2I m_bbox;
965};
966
967
968#endif // __SHAPE_LINE_CHAIN
BOX2< VECTOR2I > BOX2I
Definition: box2.h:847
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:461
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.
const std::string Format() const override
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.
SHAPE_LINE_CHAIN(const SHAPE_LINE_CHAIN &aShape)
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