KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2024 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>
36#include <math/vector2d.h>
37
43{
45 {
46 m_FirstArcIdx = -1;
47 m_SecondArcIdx = -1;
48 }
49
50 CLIPPER_Z_VALUE( const std::pair<ssize_t, ssize_t> aShapeIndices, ssize_t aOffset = 0 )
51 {
52 m_FirstArcIdx = aShapeIndices.first;
53 m_SecondArcIdx = aShapeIndices.second;
54
55 auto offsetVal = [&]( ssize_t& aVal )
56 {
57 if( aVal >= 0 )
58 aVal += aOffset;
59 };
60
61 offsetVal( m_FirstArcIdx );
62 offsetVal( m_SecondArcIdx );
63 }
64
67};
68
69
83{
84public:
85 typedef std::vector<VECTOR2I>::iterator point_iter;
86 typedef std::vector<VECTOR2I>::const_iterator point_citer;
87
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 );
176
177 SHAPE_LINE_CHAIN( const SHAPE_ARC& aArc, bool aClosed = false );
178
179 SHAPE_LINE_CHAIN( const ClipperLib::Path& aPath,
180 const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
181 const std::vector<SHAPE_ARC>& aArcBuffer );
182
183 SHAPE_LINE_CHAIN( const Clipper2Lib::Path64& aPath,
184 const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
185 const std::vector<SHAPE_ARC>& aArcBuffer );
186
188 {}
189
202 virtual bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr,
203 VECTOR2I* aLocation = nullptr ) const override;
204
217 virtual bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr,
218 VECTOR2I* aLocation = nullptr ) const override;
219
229 bool ClosestPoints( const SHAPE_LINE_CHAIN& aOther, VECTOR2I& aPt0, VECTOR2I& aPt1 ) const;
230
231 static bool ClosestPoints( const point_citer& aMyStart, const point_citer& aMyEnd,
232 const point_citer& aOtherStart, const point_citer& aOtherEnd,
233 VECTOR2I& aPt0, VECTOR2I& aPt1, int64_t& aDistSq );
234
235 static bool ClosestSegments( const VECTOR2I& aMyPrevPt, const point_citer& aMyStart,
236 const point_citer& aMyEnd, const VECTOR2I& aOtherPrevPt,
237 const point_citer& aOtherStart, const point_citer& aOtherEnd,
238 VECTOR2I& aPt0, VECTOR2I& aPt1, int64_t& aDistSq );
239
251 bool ClosestSegmentsFast( const SHAPE_LINE_CHAIN& aOther, VECTOR2I& aPt0,
252 VECTOR2I& aPt1 ) const;
253
255
256 SHAPE* Clone() const override;
257
261 void Clear()
262 {
263 m_points.clear();
264 m_arcs.clear();
265 m_shapes.clear();
266 m_closed = false;
267 }
268
275 void SetClosed( bool aClosed )
276 {
277 m_closed = aClosed;
279 }
280
284 bool IsClosed() const override
285 {
286 return m_closed;
287 }
288
294 void SetWidth( int aWidth )
295 {
296 m_width = aWidth;
297 }
298
304 int Width() const
305 {
306 return m_width;
307 }
308
314 int SegmentCount() const
315 {
316 int c = m_points.size() - 1;
317
318 if( m_closed )
319 c++;
320
321 return std::max( 0, c );
322 }
323
331 int ShapeCount() const;
332
333
338
345 void Simplify( int aMaxError = 0 );
346
347 // legacy function, used by the router. Please do not remove until I'll figure out
348 // the root cause of rounding errors - Tom
349 SHAPE_LINE_CHAIN& Simplify2( bool aRemoveColinear = true );
350
356 int PointCount() const
357 {
358 return m_points.size();
359 }
360
368 SEG Segment( int aIndex ) const;
369
377 const SEG CSegment( int aIndex ) const { return Segment( aIndex ); }
378
391 int NextShape( int aPointIndex ) const;
392
399 void SetPoint( int aIndex, const VECTOR2I& aPos );
400
407 const VECTOR2I& CPoint( int aIndex ) const
408 {
409 if( aIndex < 0 )
410 aIndex += PointCount();
411 else if( aIndex >= PointCount() )
412 aIndex -= PointCount();
413
414 return m_points[aIndex];
415 }
416
417 const std::vector<VECTOR2I>& CPoints() const
418 {
419 return m_points;
420 }
421
425 const VECTOR2I& CLastPoint() const
426 {
427 return m_points[static_cast<size_t>( PointCount() ) - 1];
428 }
429
433 const std::vector<SHAPE_ARC>& CArcs() const
434 {
435 return m_arcs;
436 }
437
441 const std::vector<std::pair<ssize_t, ssize_t>>& CShapes() const
442 {
443 return m_shapes;
444 }
445
447 const BOX2I BBox( int aClearance = 0 ) const override
448 {
449 BOX2I bbox;
450 bbox.Compute( m_points );
451
452 if( aClearance != 0 || m_width != 0 )
453 bbox.Inflate( aClearance + m_width );
454
455 return bbox;
456 }
457
458 void GenerateBBoxCache() const
459 {
461
462 if( m_width != 0 )
464 }
465
466 BOX2I* GetCachedBBox() const override
467 {
468 return &m_bbox;
469 }
470
476 const SHAPE_LINE_CHAIN Reverse() const;
477
483 void ClearArcs();
484
490 long long int Length() const;
491
495 void ReservePoints( size_t aSize )
496 {
497 m_points.reserve( aSize );
498 }
499
509 void Append( int aX, int aY, bool aAllowDuplication = false )
510 {
511 VECTOR2I v( aX, aY );
512 Append( v, aAllowDuplication );
513 }
514
523 void Append( const VECTOR2I& aP, bool aAllowDuplication = false )
524 {
525 if( m_points.size() == 0 )
526 m_bbox = BOX2I( aP, VECTOR2I( 0, 0 ) );
527
528 if( m_points.size() == 0 || aAllowDuplication || CPoint( -1 ) != aP )
529 {
530 m_points.push_back( aP );
531 m_shapes.push_back( SHAPES_ARE_PT );
532 m_bbox.Merge( aP );
533 }
534 }
535
541 void Append( const SHAPE_LINE_CHAIN& aOtherLine );
542
543 void Append( const SHAPE_ARC& aArc );
544 void Append( const SHAPE_ARC& aArc, double aAccuracy );
545
546 void Insert( size_t aVertex, const VECTOR2I& aP );
547
548 void Insert( size_t aVertex, const SHAPE_ARC& aArc );
549
557 void Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP );
558
567 void Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine );
568
575 void Remove( int aStartIndex, int aEndIndex );
576
582 void Remove( int aIndex )
583 {
584 Remove( aIndex, aIndex );
585 }
586
595 void RemoveShape( int aPointIndex );
596
605 int Split( const VECTOR2I& aP, bool aExact = false );
606
613 int Find( const VECTOR2I& aP, int aThreshold = 0 ) const;
614
621 int FindSegment( const VECTOR2I& aP, int aThreshold = 1 ) const;
622
630 const SHAPE_LINE_CHAIN Slice( int aStartIndex, int aEndIndex = -1 ) const;
631
633 {
635 m_origin( aOrigin )
636 {}
637
638 bool operator()( const INTERSECTION& aA, const INTERSECTION& aB )
639 {
640 return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm();
641 }
642
644 };
645
646 bool Intersects( const SHAPE_LINE_CHAIN& aChain ) const;
647
656 int Intersect( const SEG& aSeg, INTERSECTIONS& aIp ) const;
657
666 int Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp,
667 bool aExcludeColinearAndTouching = false,
668 BOX2I* aChainBBox = nullptr ) const;
669
676 int PathLength( const VECTOR2I& aP, int aIndex = -1 ) const;
677
685 bool CheckClearance( const VECTOR2I& aP, const int aDist) const;
686
692 const std::optional<INTERSECTION> SelfIntersecting() const;
693
699 const std::optional<INTERSECTION> SelfIntersectingWithArcs() const;
700
707 int NearestSegment( const VECTOR2I& aP ) const;
708
717 const VECTOR2I NearestPoint( const VECTOR2I& aP, bool aAllowInternalShapePoints = true ) const;
718
727 const VECTOR2I NearestPoint( const SEG& aSeg, int& dist ) const;
728
730 const std::string Format( bool aCplusPlus = true ) const override;
731
733 bool Parse( std::stringstream& aStream ) override;
734
735 bool operator!=( const SHAPE_LINE_CHAIN& aRhs ) const
736 {
737 if( PointCount() != aRhs.PointCount() )
738 return true;
739
740 for( int i = 0; i < PointCount(); i++ )
741 {
742 if( CPoint( i ) != aRhs.CPoint( i ) )
743 return true;
744 }
745
746 return false;
747 }
748
749 bool CompareGeometry( const SHAPE_LINE_CHAIN& aOther ) const;
750
751 void Move( const VECTOR2I& aVector ) override
752 {
753 for( auto& pt : m_points )
754 pt += aVector;
755
756 for( auto& arc : m_arcs )
757 arc.Move( aVector );
758
759 m_bbox.Move( aVector );
760 }
761
768 void Mirror( const VECTOR2I& aRef, FLIP_DIRECTION aFlipDirection );
769
775 void Mirror( const SEG& axis );
776
783 void Rotate( const EDA_ANGLE& aAngle, const VECTOR2I& aCenter = { 0, 0 } ) override;
784
785 bool IsSolid() const override
786 {
787 return false;
788 }
789
790 const VECTOR2I PointAlong( int aPathLength ) const;
791
797 double Area( bool aAbsolute = true ) const;
798
808 void Split( const VECTOR2I& aStart, const VECTOR2I& aEnd, SHAPE_LINE_CHAIN& aPre,
809 SHAPE_LINE_CHAIN& aMid, SHAPE_LINE_CHAIN& aPost ) const;
810
821 bool OffsetLine( int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError,
822 SHAPE_LINE_CHAIN& aLeft, SHAPE_LINE_CHAIN& aRight,
823 bool aSimplify = false ) const;
824
825 size_t ArcCount() const
826 {
827 return m_arcs.size();
828 }
829
833 ssize_t ArcIndex( size_t aSegment ) const
834 {
835 if( IsSharedPt( aSegment ) )
836 return m_shapes[aSegment].second;
837 else
838 return m_shapes[aSegment].first;
839 }
840
841 const SHAPE_ARC& Arc( size_t aArc ) const
842 {
843 return m_arcs[aArc];
844 }
845
851 bool IsSharedPt( size_t aIndex ) const;
852
853 bool IsPtOnArc( size_t aPtIndex ) const;
854
855 bool IsArcSegment( size_t aSegment ) const;
856
857 bool IsArcStart( size_t aIndex ) const;
858
859 bool IsArcEnd( size_t aIndex ) const;
860
861 using SHAPE::Distance;
862
863 int Distance( const VECTOR2I& aP, bool aOutlineOnly ) const
864 {
865 return sqrt( SquaredDistance( aP, aOutlineOnly ) );
866 }
867
868 virtual const VECTOR2I GetPoint( int aIndex ) const override { return CPoint(aIndex); }
869 virtual const SEG GetSegment( int aIndex ) const override { return CSegment(aIndex); }
870 virtual size_t GetPointCount() const override { return PointCount(); }
871 virtual size_t GetSegmentCount() const override { return SegmentCount(); }
872
873 void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
874 ERROR_LOC aErrorLoc ) const override;
875
876protected:
877 friend class SHAPE_POLY_SET;
878
884 void convertArc( ssize_t aArcIndex );
885
898 void splitArc( ssize_t aPtIndex, bool aCoincident = false );
899
900 void amendArc( size_t aArcIndex, const VECTOR2I& aNewStart, const VECTOR2I& aNewEnd );
901
902 void amendArcStart( size_t aArcIndex, const VECTOR2I& aNewStart )
903 {
904 amendArc( aArcIndex, aNewStart, m_arcs[aArcIndex].GetP1() );
905 }
906
907 void amendArcEnd( size_t aArcIndex, const VECTOR2I& aNewEnd )
908 {
909 amendArc( aArcIndex, m_arcs[aArcIndex].GetP0(), aNewEnd );
910 }
911
915 ssize_t reversedArcIndex( size_t aSegment ) const
916 {
917 if( IsSharedPt( aSegment ) )
918 return m_shapes[aSegment].first;
919 else
920 return m_shapes[aSegment].second;
921 }
922
926 ClipperLib::Path convertToClipper( bool aRequiredOrientation,
927 std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
928 std::vector<SHAPE_ARC>& aArcBuffer ) const;
929
933 Clipper2Lib::Path64 convertToClipper2( bool aRequiredOrientation,
934 std::vector<CLIPPER_Z_VALUE> &aZValueBuffer,
935 std::vector<SHAPE_ARC> &aArcBuffer ) const;
936
940 void fixIndicesRotation();
941
946
947private:
948
949 static const ssize_t SHAPE_IS_PT;
950
951 static const std::pair<ssize_t, ssize_t> SHAPES_ARE_PT;
952
954 std::vector<VECTOR2I> m_points;
955
970 std::vector<std::pair<ssize_t, ssize_t>> m_shapes;
971
972 std::vector<SHAPE_ARC> m_arcs;
973
976
983
985 mutable BOX2I m_bbox;
986};
987
988
989#endif // __SHAPE_LINE_CHAIN
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
Definition: approximation.h:32
BOX2< VECTOR2I > BOX2I
Definition: box2.h:922
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:558
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:658
constexpr void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
Definition: box2.h:138
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Definition: box2.h:109
Definition: seg.h:42
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)
SEG::ecoord SquaredDistance(const VECTOR2I &aP, bool aOutlineOnly=false) const override
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
int Distance(const VECTOR2I &aP, bool aOutlineOnly) const
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, bool aExact=false)
Insert the point aP belonging to one of the our segments, splitting the adjacent segment in two.
SHAPE_LINE_CHAIN & operator=(const SHAPE_LINE_CHAIN &)=default
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
void Simplify(int aMaxError=0)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
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.
void TransformToPolygon(SHAPE_POLY_SET &aBuffer, int aError, ERROR_LOC aErrorLoc) const override
Fills a SHAPE_POLY_SET with a polygon representation of this shape.
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 ReservePoints(size_t aSize)
Allocate a number of points all at once (for performance).
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.
SEG Segment(int aIndex) const
Return a copy of the aIndex-th segment in the line chain.
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
const std::optional< INTERSECTION > SelfIntersectingWithArcs() const
Check if the line chain is self-intersecting.
int NearestSegment(const VECTOR2I &aP) const
Find the segment nearest the given point.
int NextShape(int aPointIndex) const
Return the vertex index of the next shape in the chain, or -1 if aPointIndex is the last shape.
double Area(bool aAbsolute=true) const
Return the area of this chain.
SHAPE_LINE_CHAIN & Simplify2(bool aRemoveColinear=true)
void amendArc(size_t aArcIndex, const VECTOR2I &aNewStart, const VECTOR2I &aNewEnd)
virtual size_t GetPointCount() const override
bool ClosestPoints(const SHAPE_LINE_CHAIN &aOther, VECTOR2I &aPt0, VECTOR2I &aPt1) const
Finds closest points between this and the other line chain.
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...
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
void Mirror(const VECTOR2I &aRef, FLIP_DIRECTION aFlipDirection)
Mirror the line points about y or x (or both).
bool ClosestSegmentsFast(const SHAPE_LINE_CHAIN &aOther, VECTOR2I &aPt0, VECTOR2I &aPt1) const
Finds closest points between segments of this and the other line chain.
const std::string Format(bool aCplusPlus=true) const override
static bool ClosestSegments(const VECTOR2I &aMyPrevPt, const point_citer &aMyStart, const point_citer &aMyEnd, const VECTOR2I &aOtherPrevPt, const point_citer &aOtherStart, const point_citer &aOtherEnd, VECTOR2I &aPt0, VECTOR2I &aPt1, int64_t &aDistSq)
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.
void RemoveDuplicatePoints()
Remove the duplicate points 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
bool OffsetLine(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, SHAPE_LINE_CHAIN &aLeft, SHAPE_LINE_CHAIN &aRight, bool aSimplify=false) const
Creates line chains aLeft and aRight offset to this line chain.
Represent a set of closed polygons.
An abstract shape on 2D plane.
Definition: shape.h:126
virtual int Distance(const VECTOR2I &aP) const
Returns the minimum distance from a given point to this shape.
Definition: shape.cpp:108
CORNER_STRATEGY
define how inflate transform build inflated polygon
FLIP_DIRECTION
Definition: mirror.h:27
@ SH_LINE_CHAIN
line chain (polyline)
Definition: shape.h:49
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
When true, the corner [index_their] of the 'their' line lies exactly on 'our' line.
bool is_corner_our
When true, the corner [index_our] of the 'our' line lies exactly on 'their' line.
int index_our
Index of the intersecting corner/segment in the 'our' (== this) line.
VECTOR2I p
Point of intersection between our and their.
bool valid
Auxiliary flag to avoid copying intersection info to intersection refining code, used by the refining...
int index_their
index of the intersecting corner/segment in the 'their' (Intersect() method parameter) line.
compareOriginDistance(const VECTOR2I &aOrigin)
bool operator()(const INTERSECTION &aA, const INTERSECTION &aB)
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691