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 The 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, see <https://www.gnu.org/licenses/>.
20 */
21
22#ifndef __SHAPE_LINE_CHAIN
23#define __SHAPE_LINE_CHAIN
24
25
26#include <clipper2/clipper.h>
27#include <geometry/seg.h>
28#include <geometry/shape.h>
29#include <geometry/shape_arc.h>
31#include <math/vector2d.h>
32
38{
44
45 CLIPPER_Z_VALUE( const std::pair<ssize_t, ssize_t> aShapeIndices, ssize_t aOffset = 0 )
46 {
47 m_FirstArcIdx = aShapeIndices.first;
48 m_SecondArcIdx = aShapeIndices.second;
49
50 auto offsetVal = [&]( ssize_t& aVal )
51 {
52 if( aVal >= 0 )
53 aVal += aOffset;
54 };
55
56 offsetVal( m_FirstArcIdx );
57 offsetVal( m_SecondArcIdx );
58 }
59
62};
63
64
78{
79public:
80 typedef std::vector<VECTOR2I>::iterator point_iter;
81 typedef std::vector<VECTOR2I>::const_iterator point_citer;
82
87 {
90
93
97
100
105
109 bool valid;
110
112 index_our( -1 ),
113 index_their( -1 ),
114 is_corner_our( false ),
115 is_corner_their( false ),
116 valid( false )
117 {
118 }
119 };
120
121
127 {
128 public:
129 POINT_INSIDE_TRACKER( const VECTOR2I& aPoint );
130
131 void AddPolyline( const SHAPE_LINE_CHAIN& aPolyline );
132 bool IsInside();
133
134 private:
135
136 bool processVertex ( const VECTOR2I& ip, const VECTOR2I& ipNext );
137
144 };
145
146 typedef std::vector<INTERSECTION> INTERSECTIONS;
147
148
154 m_accuracy( 0 ),
155 m_closed( false ),
156 m_width( 0 )
157 {}
158
161 m_points( aShape.m_points ),
162 m_shapes( aShape.m_shapes ),
163 m_arcs( aShape.m_arcs ),
164 m_accuracy( aShape.m_accuracy ),
165 m_closed( aShape.m_closed ),
166 m_width( aShape.m_width ),
167 m_bbox( aShape.m_bbox )
168 {}
169
170 SHAPE_LINE_CHAIN( const std::vector<int>& aV );
171
172 SHAPE_LINE_CHAIN( const std::vector<VECTOR2I>& aV, bool aClosed = false );
173
174 SHAPE_LINE_CHAIN( const SHAPE_ARC& aArc, bool aClosed = false, std::optional<int> aMaxError = {} );
175
176 SHAPE_LINE_CHAIN( const Clipper2Lib::Path64& aPath,
177 const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
178 const std::vector<SHAPE_ARC>& aArcBuffer );
179
181 {}
182
196 virtual bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr,
197 VECTOR2I* aLocation = nullptr ) const override;
198
212 virtual bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr,
213 VECTOR2I* aLocation = nullptr ) const override;
214
223 bool ClosestPoints( const SHAPE_LINE_CHAIN& aOther, VECTOR2I& aPt0, VECTOR2I& aPt1 ) const;
224
225 static bool ClosestPoints( const point_citer& aMyStart, const point_citer& aMyEnd,
226 const point_citer& aOtherStart, const point_citer& aOtherEnd,
227 VECTOR2I& aPt0, VECTOR2I& aPt1, int64_t& aDistSq );
228
229 static bool ClosestSegments( const VECTOR2I& aMyPrevPt, const point_citer& aMyStart,
230 const point_citer& aMyEnd, const VECTOR2I& aOtherPrevPt,
231 const point_citer& aOtherStart, const point_citer& aOtherEnd,
232 VECTOR2I& aPt0, VECTOR2I& aPt1, int64_t& aDistSq );
233
244 bool ClosestSegmentsFast( const SHAPE_LINE_CHAIN& aOther, VECTOR2I& aPt0,
245 VECTOR2I& aPt1 ) const;
246
248
249 // Move assignment operator
251 {
252 if (this != &aOther)
253 {
254 SHAPE_LINE_CHAIN_BASE::operator=( aOther );
255
256 m_points = std::move( aOther.m_points );
257 m_shapes = std::move( aOther.m_shapes );
258 m_arcs = std::move( aOther.m_arcs );
259
260 m_accuracy = aOther.m_accuracy;
261 m_closed = aOther.m_closed;
262 m_width = aOther.m_width;
263 m_bbox = aOther.m_bbox;
264 }
265
266 return *this;
267 }
268
269 SHAPE* Clone() const override;
270
274 void Clear()
275 {
276 m_points.clear();
277 m_arcs.clear();
278 m_shapes.clear();
279 m_closed = false;
280 }
281
288 void SetClosed( bool aClosed )
289 {
290 m_closed = aClosed;
292 }
293
297 bool IsClosed() const override
298 {
299 return m_closed;
300 }
301
307 void SetWidth( int aWidth ) override
308 {
309 m_width = aWidth;
310 }
311
317 int Width() const
318 {
319 return m_width;
320 }
321
327 int SegmentCount() const
328 {
329 int c = m_points.size() - 1;
330
331 if( m_closed )
332 c++;
333
334 return std::max( 0, c );
335 }
336
344 int ShapeCount() const;
345
346
351
358 void Simplify( int aTolerance = 0 );
359
360 // legacy function, used by the router. Please do not remove until I'll figure out
361 // the root cause of rounding errors - Tom
362 SHAPE_LINE_CHAIN& Simplify2( bool aRemoveColinear = true );
363
369 int PointCount() const
370 {
371 return m_points.size();
372 }
373
381 SEG Segment( int aIndex ) const;
382
390 const SEG CSegment( int aIndex ) const { return Segment( aIndex ); }
391
404 int NextShape( int aPointIndex ) const;
405
412 void SetPoint( int aIndex, const VECTOR2I& aPos );
413
420 const VECTOR2I& CPoint( int aIndex ) const
421 {
422 if( aIndex < 0 )
423 aIndex += PointCount();
424 else if( aIndex >= PointCount() )
425 aIndex -= PointCount();
426
427 return m_points[aIndex];
428 }
429
430 const std::vector<VECTOR2I>& CPoints() const { return m_points; }
431
435 const VECTOR2I& CLastPoint() const
436 {
437 return m_points[static_cast<size_t>( PointCount() ) - 1];
438 }
439
443 const std::vector<SHAPE_ARC>& CArcs() const
444 {
445 return m_arcs;
446 }
447
451 const std::vector<std::pair<ssize_t, ssize_t>>& CShapes() const
452 {
453 return m_shapes;
454 }
455
457 const BOX2I BBox( int aClearance = 0 ) const override
458 {
459 BOX2I bbox;
460 bbox.Compute( m_points );
461
462 if( aClearance != 0 || m_width != 0 )
463 bbox.Inflate( aClearance + m_width );
464
465 return bbox;
466 }
467
468 void GenerateBBoxCache() const
469 {
470 m_bbox.Compute( m_points );
471
472 if( m_width != 0 )
473 m_bbox.Inflate( m_width );
474 }
475
476 BOX2I* GetCachedBBox() const override
477 {
478 return &m_bbox;
479 }
480
486 const SHAPE_LINE_CHAIN Reverse() const;
487
493 void ClearArcs();
494
500 long long int Length() const;
501
505 void ReservePoints( size_t aSize )
506 {
507 m_points.reserve( aSize );
508 m_shapes.reserve( aSize );
509 }
510
520 void Append( int aX, int aY, bool aAllowDuplication = false )
521 {
522 VECTOR2I v( aX, aY );
523 Append( v, aAllowDuplication );
524 }
525
534 void Append( const VECTOR2I& aP, bool aAllowDuplication = false )
535 {
536 if( m_points.size() == 0 )
537 m_bbox = BOX2I( aP, VECTOR2I( 0, 0 ) );
538
539 if( m_points.size() == 0 || aAllowDuplication || CLastPoint() != aP )
540 {
541 m_points.push_back( aP );
542 m_shapes.push_back( SHAPES_ARE_PT );
543 m_bbox.Merge( aP );
544 }
545 }
546
552 void Append( const SHAPE_LINE_CHAIN& aOtherLine );
553
554 void Append( const SHAPE_ARC& aArc );
555 void Append( const SHAPE_ARC& aArc, int aMaxError );
556
557 void Insert( size_t aVertex, const VECTOR2I& aP );
558
559 void Insert( size_t aVertex, const SHAPE_ARC& aArc );
560 void Insert( size_t aVertex, const SHAPE_ARC& aArc, int aMaxError );
561
569 void Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP );
570
579 void Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine );
580
587 void Remove( int aStartIndex, int aEndIndex );
588
594 void Remove( int aIndex )
595 {
596 Remove( aIndex, aIndex );
597 }
598
607 void RemoveShape( int aPointIndex );
608
617 int Split( const VECTOR2I& aP, bool aExact = false );
618
626 int Find( const VECTOR2I& aP, int aThreshold = 0 ) const;
627
635 int FindSegment( const VECTOR2I& aP, int aThreshold = 1 ) const;
636
644 const SHAPE_LINE_CHAIN Slice( int aStartIndex, int aEndIndex ) const;
645 const SHAPE_LINE_CHAIN Slice( int aStartIndex, int aEndIndex, int aMaxError ) const;
646
648 {
650 m_origin( aOrigin )
651 {}
652
653 bool operator()( const INTERSECTION& aA, const INTERSECTION& aB )
654 {
655 return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm();
656 }
657
659 };
660
661 bool Intersects( const SEG& aSeg) const;
662 bool Intersects( const SHAPE_LINE_CHAIN& aChain ) const;
663
672 int Intersect( const SEG& aSeg, INTERSECTIONS& aIp ) const;
673
684 int Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp,
685 bool aExcludeColinearAndTouching = false,
686 BOX2I* aChainBBox = nullptr ) const;
687
694 int PathLength( const VECTOR2I& aP, int aIndex = -1 ) const;
695
703 bool CheckClearance( const VECTOR2I& aP, const int aDist) const;
704
710 const std::optional<INTERSECTION> SelfIntersecting() const;
711
717 const std::optional<INTERSECTION> SelfIntersectingWithArcs() const;
718
725 int NearestSegment( const VECTOR2I& aP ) const;
726
735 const VECTOR2I NearestPoint( const VECTOR2I& aP, bool aAllowInternalShapePoints = true ) const;
736
745 const VECTOR2I NearestPoint( const SEG& aSeg, int& dist ) const;
746
748 const std::string Format( bool aCplusPlus = true ) const override;
749
751 bool Parse( std::stringstream& aStream ) override;
752
753 bool operator!=( const SHAPE_LINE_CHAIN& aRhs ) const
754 {
755 if( PointCount() != aRhs.PointCount() )
756 return true;
757
758 for( int i = 0; i < PointCount(); i++ )
759 {
760 if( CPoint( i ) != aRhs.CPoint( i ) )
761 return true;
762 }
763
764 return false;
765 }
766
776 bool CompareGeometry( const SHAPE_LINE_CHAIN& aOther, bool aCyclicalCompare = false, int aEpsilon = 0 ) const;
777
778 void Move( const VECTOR2I& aVector ) override
779 {
780 for( auto& pt : m_points )
781 pt += aVector;
782
783 for( auto& arc : m_arcs )
784 arc.Move( aVector );
785
786 m_bbox.Move( aVector );
787 }
788
795 void Mirror( const VECTOR2I& aRef, FLIP_DIRECTION aFlipDirection );
796
802 void Mirror( const SEG& axis );
803
810 void Rotate( const EDA_ANGLE& aAngle, const VECTOR2I& aCenter = { 0, 0 } ) override;
811
812 bool IsSolid() const override
813 {
814 return false;
815 }
816
817 const VECTOR2I PointAlong( int aPathLength ) const;
818
824 double Area( bool aAbsolute = true ) const;
825
835 void Split( const VECTOR2I& aStart, const VECTOR2I& aEnd, SHAPE_LINE_CHAIN& aPre,
836 SHAPE_LINE_CHAIN& aMid, SHAPE_LINE_CHAIN& aPost ) const;
837
848 bool OffsetLine( int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError,
849 SHAPE_LINE_CHAIN& aLeft, SHAPE_LINE_CHAIN& aRight,
850 bool aSimplify = false ) const;
851
852 size_t ArcCount() const
853 {
854 return m_arcs.size();
855 }
856
860 ssize_t ArcIndex( size_t aSegment ) const
861 {
862 if( IsSharedPt( aSegment ) )
863 return m_shapes[aSegment].second;
864 else
865 return m_shapes[aSegment].first;
866 }
867
868 const SHAPE_ARC& Arc( size_t aArc ) const
869 {
870 return m_arcs[aArc];
871 }
872
878 bool IsSharedPt( size_t aIndex ) const;
879
880 bool IsPtOnArc( size_t aPtIndex ) const;
881
882 bool IsArcSegment( size_t aSegment ) const;
883
884 bool IsArcStart( size_t aIndex ) const;
885
886 bool IsArcEnd( size_t aIndex ) const;
887
888 using SHAPE::Distance;
889
890 int Distance( const VECTOR2I& aP, bool aOutlineOnly ) const
891 {
892 return sqrt( SquaredDistance( aP, aOutlineOnly ) );
893 }
894
895 virtual const VECTOR2I GetPoint( int aIndex ) const override { return CPoint(aIndex); }
896 virtual const SEG GetSegment( int aIndex ) const override { return CSegment(aIndex); }
897 virtual size_t GetPointCount() const override { return PointCount(); }
898 virtual size_t GetSegmentCount() const override { return SegmentCount(); }
899
900 bool PointInside( const VECTOR2I& aPt, int aAccuracy = 0,
901 bool aUseBBoxCache = false ) const override;
902
903 void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
904 ERROR_LOC aErrorLoc ) const override;
905
906protected:
907 friend class SHAPE_POLY_SET;
908
914 void convertArc( ssize_t aArcIndex );
915
928 void splitArc( ssize_t aPtIndex, bool aCoincident = false );
929
930 void amendArc( size_t aArcIndex, const VECTOR2I& aNewStart, const VECTOR2I& aNewEnd );
931
932 void amendArcStart( size_t aArcIndex, const VECTOR2I& aNewStart )
933 {
934 amendArc( aArcIndex, aNewStart, m_arcs[aArcIndex].GetP1() );
935 }
936
937 void amendArcEnd( size_t aArcIndex, const VECTOR2I& aNewEnd )
938 {
939 amendArc( aArcIndex, m_arcs[aArcIndex].GetP0(), aNewEnd );
940 }
941
945 ssize_t reversedArcIndex( size_t aSegment ) const
946 {
947 if( IsSharedPt( aSegment ) )
948 return m_shapes[aSegment].first;
949 else
950 return m_shapes[aSegment].second;
951 }
952
956 Clipper2Lib::Path64 convertToClipper2( bool aRequiredOrientation,
957 std::vector<CLIPPER_Z_VALUE> &aZValueBuffer,
958 std::vector<SHAPE_ARC> &aArcBuffer ) const;
959
963 void fixIndicesRotation();
964
969
970private:
971
972 static const ssize_t SHAPE_IS_PT;
973
974 static const std::pair<ssize_t, ssize_t> SHAPES_ARE_PT;
975
977 std::vector<VECTOR2I> m_points;
978
993 std::vector<std::pair<ssize_t, ssize_t>> m_shapes;
994
995 std::vector<SHAPE_ARC> m_arcs;
996
997 // the maxError to use when converting arcs to points
999
1002
1009
1011 mutable BOX2I m_bbox;
1012};
1013
1014
1015#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...
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:553
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Definition box2.h:106
Definition seg.h:38
bool processVertex(const VECTOR2I &ip, const VECTOR2I &ipNext)
void AddPolyline(const SHAPE_LINE_CHAIN &aPolyline)
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition shape.h:318
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
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.
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.
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.
void Simplify(int aTolerance=0)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
void SetWidth(int aWidth) override
Set the width of all segments in the 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
bool m_closed
is the line chain closed?
friend class SHAPE_POLY_SET
const std::vector< SHAPE_ARC > & CArcs() const
const std::optional< INTERSECTION > SelfIntersectingWithArcs() const
Check if the line chain is self-intersecting.
bool Intersects(const SEG &aSeg) const
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
bool CompareGeometry(const SHAPE_LINE_CHAIN &aOther, bool aCyclicalCompare=false, int aEpsilon=0) const
Compare this line chain with another one.
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
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex) const
Return a subset of this line chain containing the [start_index, end_index] range of points.
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
SHAPE_LINE_CHAIN & operator=(SHAPE_LINE_CHAIN &&aOther) noexcept
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const override
Check if point aP lies inside a closed shape.
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:124
virtual int Distance(const VECTOR2I &aP) const
Returns the minimum distance from a given point to this shape.
Definition shape.cpp:105
CORNER_STRATEGY
define how inflate transform build inflated polygon
FLIP_DIRECTION
Definition mirror.h:23
@ SH_LINE_CHAIN
line chain (polyline)
Definition shape.h:45
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:708