65 VECTOR2I( 183450000, 128360000 ), 0 );
69 VECTOR2I( 183850000, 128360000 ), 0 );
73 VECTOR2I( 183450000, 128360000 ), 0 );
77 VECTOR2I( 183500000, 129204974 ), 0 );
81 VECTOR2I( 283850000, 228360000 ), 0 );
126BOOST_FIXTURE_TEST_SUITE( TestShapeLineChain,
SLC_CASES )
134 ClipperLib::Path pathClipper1 = {
135 { { 125663951, 120099260, 24 }, { 125388111, 120170850, 25 }, { 125124975, 120280270, 26 },
136 { 124879705, 120425376, 27 }, { 124657110, 120603322, 28 }, { 124461556, 120810617, 29 },
137 { 124296876, 121043198, 30 }, { 124166301, 121296503, 31 }, { 124072391, 121565564, 32 },
138 { 124016988, 121845106, 33 }, { 124001177, 122129646, 34 }, { 124025270, 122413605, 35 },
139 { 124088794, 122691414, 36 }, { 124190502, 122957625, 37 }, { 124328401, 123207018, 38 },
140 { 124499787, 123434703, 39 }, { 124598846, 123537154, 40 }, { 127171000, 123786000, 4 },
141 { 127287862, 123704439, 5 }, { 127499716, 123513831, 6 }, { 127682866, 123295498, 7 },
142 { 127833720, 123053722, 8 }, { 127949321, 122793242, 9 }, { 128027402, 122519168, 10 },
143 { 128066430, 122236874, 11 }, { 128065642, 121951896, 12 }, { 128025053, 121669823, 13 },
144 { 127945457, 121396185, 14 }, { 127828417, 121136349, 15 }, { 127676227, 120895410, 16 },
145 { 127491873, 120678094, 17 }, { 127278968, 120488661, 18 }, { 127041689, 120330827, 19 },
146 { 126784688, 120207687, 20 }, { 126513005, 120121655, 21 }, { 126231968, 120074419, 22 },
147 { 125947087, 120066905, 23 } }
149 Clipper2Lib::Path64 pathClipper2 = {
150 { { 125663951, 120099260, 24 }, { 125388111, 120170850, 25 }, { 125124975, 120280270, 26 },
151 { 124879705, 120425376, 27 }, { 124657110, 120603322, 28 }, { 124461556, 120810617, 29 },
152 { 124296876, 121043198, 30 }, { 124166301, 121296503, 31 }, { 124072391, 121565564, 32 },
153 { 124016988, 121845106, 33 }, { 124001177, 122129646, 34 }, { 124025270, 122413605, 35 },
154 { 124088794, 122691414, 36 }, { 124190502, 122957625, 37 }, { 124328401, 123207018, 38 },
155 { 124499787, 123434703, 39 }, { 124598846, 123537154, 40 }, { 127171000, 123786000, 4 },
156 { 127287862, 123704439, 5 }, { 127499716, 123513831, 6 }, { 127682866, 123295498, 7 },
157 { 127833720, 123053722, 8 }, { 127949321, 122793242, 9 }, { 128027402, 122519168, 10 },
158 { 128066430, 122236874, 11 }, { 128065642, 121951896, 12 }, { 128025053, 121669823, 13 },
159 { 127945457, 121396185, 14 }, { 127828417, 121136349, 15 }, { 127676227, 120895410, 16 },
160 { 127491873, 120678094, 17 }, { 127278968, 120488661, 18 }, { 127041689, 120330827, 19 },
161 { 126784688, 120207687, 20 }, { 126513005, 120121655, 21 }, { 126231968, 120074419, 22 },
162 { 125947087, 120066905, 23 } }
165 std::vector<CLIPPER_Z_VALUE> z_values = {
166 { { -1, -1 }, 0 }, { { -1, -1 }, 0 }, { { -1, -1 }, 0 }, { { -1, -1 }, 0 },
167 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
168 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
169 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
170 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
171 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
172 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
173 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
174 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
175 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
179 std::vector<SHAPE_ARC> arcs = {
180 SHAPE_ARC( { 127171000, 123786000 }, { 126231718, 120077003 }, { 124598846, 123537154 }, 0 )
189 BOOST_CHECK_EQUAL( clipper1chain.
PointCount(), 37 );
190 BOOST_CHECK_EQUAL( clipper2chain.
PointCount(), 37 );
192 BOOST_CHECK_EQUAL( clipper1chain.
ArcCount(), 1 );
193 BOOST_CHECK_EQUAL( clipper2chain.
ArcCount(), 1 );
195 BOOST_CHECK_EQUAL( clipper1chain.
ShapeCount(), 2 );
196 BOOST_CHECK_EQUAL( clipper2chain.
ShapeCount(), 2 );
198 BOOST_CHECK_EQUAL( clipper1chain.
IsClosed(),
true );
199 BOOST_CHECK_EQUAL( clipper2chain.
IsClosed(),
true );
217 BOOST_CHECK_EQUAL( base_chain.CShapes().size(), base_chain.CPoints().size() );
218 BOOST_CHECK_EQUAL( arc_insert1.CShapes().size(), arc_insert1.CPoints().size() );
219 BOOST_CHECK_EQUAL( arc_insert2.
CShapes().size(), arc_insert2.
CPoints().size() );
227 BOOST_CHECK_EQUAL( base_chain.CShapes().size(), base_chain.CPoints().size() );
229 base_chain.Replace( 0, 2, chain_insert );
231 BOOST_CHECK_EQUAL( base_chain.CShapes().size(), base_chain.CPoints().size() );
249 BOOST_CHECK_EQUAL( base_chain.PointCount(), 11 );
251 base_chain.Insert( 9,
VECTOR2I( 250000, 0 ) );
253 BOOST_CHECK_EQUAL( base_chain.PointCount(), 12 );
254 BOOST_CHECK_EQUAL( base_chain.ArcCount(), 2 );
256 base_chain.Replace( 5, 6, chain_insert );
258 BOOST_CHECK_EQUAL( base_chain.PointCount(), 13 );
259 BOOST_CHECK_EQUAL( base_chain.ArcCount(), 3 );
261 base_chain.Replace( 4, 6,
VECTOR2I( 550000, 0 ) );
263 BOOST_CHECK_EQUAL( base_chain.PointCount(), 11 );
264 BOOST_CHECK_EQUAL( base_chain.ArcCount(), 3 );
267 base_chain.SetClosed(
true );
268 double areaPriorToArcRemoval = base_chain.Area();
269 base_chain.ClearArcs();
272 BOOST_CHECK_EQUAL( base_chain.CPoints().size(), base_chain.CShapes().size() );
273 BOOST_CHECK_EQUAL( base_chain.PointCount(), 11 );
274 BOOST_CHECK_EQUAL( base_chain.ArcCount(), 0 );
275 BOOST_CHECK_EQUAL( base_chain.Area(), areaPriorToArcRemoval );
285 SHAPE_ARC( { -859598, 2559876 }, { -1632771, 1022403 }, { -3170244, 249230 }, 0 ) );
288 SHAPE_ARC( { -3170244, -1657832 }, { -292804, -317564 }, { 1047464, 2559876 }, 0 ) );
297 BOOST_CHECK_EQUAL( chain.
CPoints().size(), chain.
CShapes().size() );
303 BOOST_CHECK_EQUAL( Circle2Arcs.IsClosed(),
true );
304 BOOST_CHECK_EQUAL( Circle2Arcs.PointCount(), 16 );
305 BOOST_CHECK_EQUAL( Circle2Arcs.IsArcSegment( 15 ),
true );
306 BOOST_CHECK_EQUAL( Circle2Arcs.ShapeCount(), 2 );
307 Circle2Arcs.SetClosed(
false );
309 BOOST_CHECK_EQUAL( Circle2Arcs.IsClosed(),
false );
310 BOOST_CHECK_EQUAL( Circle2Arcs.PointCount(), 17 );
311 BOOST_CHECK_EQUAL( Circle2Arcs.IsArcSegment( 15 ),
true );
312 BOOST_CHECK_EQUAL( Circle2Arcs.IsArcSegment( 16 ),
false );
348 BOOST_TEST_CONTEXT( c.m_ctx_name )
352 BOOST_CHECK_EQUAL( slc_case.
IsClosed(), c.m_closed );
353 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
354 BOOST_CHECK_EQUAL( slc_case.
PointCount(), c.m_point_count );
357 BOOST_CHECK_EQUAL( slc_case.
IsClosed(), !c.m_closed );
358 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_expected_shape_count );
359 BOOST_CHECK_EQUAL( slc_case.
PointCount(), c.m_expected_point_count );
362 BOOST_CHECK_EQUAL( slc_case.
IsClosed(), c.m_closed );
363 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
364 BOOST_CHECK_EQUAL( slc_case.
PointCount(), c.m_point_count );
375 chain.
Append( { 100, 100 } );
376 chain.
Append( { 100, 100 }, true );
377 chain.
Append( { 200, 100 } );
384 BOOST_CHECK_EQUAL( chain.
CPoints().size(), chain.
CShapes().size() );
395 chain.
Append( { 114772424, 90949410 } );
396 chain.
Append( { 114767360, 90947240 } );
397 chain.
Append( { 114772429, 90947228 } );
405 BOOST_CHECK_EQUAL( chain.
CPoints().size(), chain.
CShapes().size() );
443 chain.
Append( { 130000, 147320 } );
444 chain.
Append( { 125730, 147320 } );
445 chain.
Append( { 125730, 150630 } );
446 chain.
Append( { 128800, 153700 } );
447 chain.
Append( { 150300, 153700 } );
448 chain.
Append( { 151500, 152500 } );
449 chain.
Append( { 151500, 148900 } );
450 chain.
Append( { 149920, 147320 } );
451 chain.
Append( { 140000, 147320 } );
552 BOOST_TEST_CONTEXT( c.m_ctx_name )
555 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
556 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_arc_count );
559 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_expected_shape_count );
560 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_expected_arc_count );
571 BOOST_TEST_CONTEXT( c.m_ctx_name )
575 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
576 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_arc_count );
579 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
580 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_arc_count );
583 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_expected_shape_count );
584 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_expected_arc_count );
592 BOOST_CHECK_EQUAL( Circle1Arc.ShapeCount(), 1 );
593 BOOST_CHECK_EQUAL( Circle2Arcs.ShapeCount(), 2 );
594 BOOST_CHECK_EQUAL( ArcsCoincident.ShapeCount(), 2 );
595 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.ShapeCount(), 3 );
596 BOOST_CHECK_EQUAL( DuplicateArcs.ShapeCount(), 4 );
597 BOOST_CHECK_EQUAL( ArcAndPoint.ShapeCount(), 2 );
598 BOOST_CHECK_EQUAL( ArcsAndSegMixed.ShapeCount(), 4 );
599 BOOST_CHECK_EQUAL( SegAndArcCoincident.ShapeCount(), 2 );
600 BOOST_CHECK_EQUAL( EmptyChain.ShapeCount(), 0 );
601 BOOST_CHECK_EQUAL( OnePoint.ShapeCount(), 0 );
602 BOOST_CHECK_EQUAL( TwoPoints.ShapeCount(), 1 );
603 BOOST_CHECK_EQUAL( ThreePoints.ShapeCount(), 2 );
609 BOOST_CHECK_EQUAL( Circle1Arc.NextShape( 0 ), -1 );
611 BOOST_CHECK_EQUAL( Circle2Arcs.NextShape( 0 ), 8 );
612 BOOST_CHECK_EQUAL( Circle2Arcs.NextShape( 8 ), -1 );
614 BOOST_CHECK_EQUAL( ArcsCoincident.NextShape( 0 ), 8 );
615 BOOST_CHECK_EQUAL( ArcsCoincident.NextShape( 8 ), -1 );
617 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.NextShape( 0 ), 8 );
618 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.NextShape( 8 ), 13 );
619 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.NextShape( 13 ), -1 );
621 BOOST_CHECK_EQUAL( ArcsIndependent.NextShape( 0 ), 8 );
622 BOOST_CHECK_EQUAL( ArcsIndependent.NextShape( 8 ), 9 );
623 BOOST_CHECK_EQUAL( ArcsIndependent.NextShape( 9 ), -1 );
625 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 0 ), 8 );
626 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 8 ), 13 );
627 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 13 ), 14 );
628 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 14 ), -1 );
630 BOOST_CHECK_EQUAL( ArcAndPoint.NextShape( 0 ), 8 );
631 BOOST_CHECK_EQUAL( ArcAndPoint.NextShape( 8 ), -1 );
633 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 0 ), 8 );
634 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 8 ), 9 );
635 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 9 ), 10 );
636 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 10 ), -1 );
637 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 20 ), -1 );
638 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( -50 ), -1 );
640 BOOST_CHECK_EQUAL( SegAndArcCoincident.NextShape( 0 ), 1 );
641 BOOST_CHECK_EQUAL( SegAndArcCoincident.NextShape( 1 ), -1 );
643 BOOST_CHECK_EQUAL( EmptyChain.NextShape( 0 ), -1 );
644 BOOST_CHECK_EQUAL( EmptyChain.NextShape( 1 ), -1 );
645 BOOST_CHECK_EQUAL( EmptyChain.NextShape( 2 ), -1 );
646 BOOST_CHECK_EQUAL( EmptyChain.NextShape( -2 ), -1 );
648 BOOST_CHECK_EQUAL( OnePoint.NextShape( 0 ), -1 );
649 BOOST_CHECK_EQUAL( OnePoint.NextShape( -1 ), -1 );
650 BOOST_CHECK_EQUAL( OnePoint.NextShape( 1 ), -1 );
651 BOOST_CHECK_EQUAL( OnePoint.NextShape( 2 ), -1 );
652 BOOST_CHECK_EQUAL( OnePoint.NextShape( -2 ), -1 );
654 BOOST_CHECK_EQUAL( TwoPoints.NextShape( 0 ), -1 );
655 BOOST_CHECK_EQUAL( TwoPoints.NextShape( 1 ), -1 );
656 BOOST_CHECK_EQUAL( TwoPoints.NextShape( -1 ), -1 );
658 BOOST_CHECK_EQUAL( ThreePoints.NextShape( 0 ), 1 );
659 BOOST_CHECK_EQUAL( ThreePoints.NextShape( 1 ), -1 );
660 BOOST_CHECK_EQUAL( ThreePoints.NextShape( 2 ), -1 );
661 BOOST_CHECK_EQUAL( ThreePoints.NextShape( -1 ), -1 );
668 BOOST_TEST_CONTEXT(
"Case 1: Arc mid point nearly collinear" )
672 chain.
Append( arc, 5000 );
674 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
681 BOOST_TEST_CONTEXT(
"Case 2: Arc = Large Circle" )
685 chain.
Append( arc, 5000 );
687 BOOST_CHECK_EQUAL( chain.
ArcCount(), 1 );
694 BOOST_TEST_CONTEXT(
"Case 3: Arc = Small Circle (approximate to point)" )
698 chain.
Append( arc, 5000 );
700 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
705 BOOST_TEST_CONTEXT(
"Case 3: Small Arc (approximate to segment)" )
709 chain.
Append( arc, 5000 );
711 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
717 BOOST_TEST_CONTEXT(
"Case 4: Arc = null arc (all points coincident)" )
721 chain.
Append( arc, 5000 );
723 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
728 BOOST_TEST_CONTEXT(
"Case 5: Arc = infinite radius (all points very close)" )
732 chain.
Append( arc, 5000 );
734 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
740 BOOST_TEST_CONTEXT(
"Case 6: Arc = large radius (all points very close)" )
744 chain.
Append( arc, 5000 );
746 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
770 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 0 ),
false );
771 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 0 ),
false );
772 BOOST_CHECK_EQUAL( chain.
IsArcStart( 0 ),
true );
775 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 6 ),
true );
776 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 6 ),
true );
777 BOOST_CHECK_EQUAL( chain.
IsArcStart( 6 ),
true );
781 BOOST_CHECK_EQUAL( chain.
IsSharedPt( endIndex ),
false );
782 BOOST_CHECK_EQUAL( chain.
IsArcEnd( endIndex ),
true );
783 BOOST_CHECK_EQUAL( chain.
IsArcStart( endIndex ),
false );
787 BOOST_CHECK_EQUAL( chain.
IsPtOnArc( i ),
true );
796 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 0 ),
true );
797 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 0 ),
true );
798 BOOST_CHECK_EQUAL( chain.
IsArcStart( 0 ),
true );
801 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 6 ),
true );
802 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 6 ),
true );
803 BOOST_CHECK_EQUAL( chain.
IsArcStart( 6 ),
true );
807 BOOST_CHECK_EQUAL( chain.
IsSharedPt( endIndex ),
false );
808 BOOST_CHECK_EQUAL( chain.
IsArcEnd( endIndex ),
false );
809 BOOST_CHECK_EQUAL( chain.
IsArcStart( endIndex ),
false );
821 BOOST_CHECK_EQUAL( chain.PointCount(), 2 );
824 BOOST_CHECK_EQUAL( chain.PointCount(), 9 );
826 chain.Append( seg2.
A );
827 chain.Append( seg2.
B );
828 BOOST_CHECK_EQUAL( chain.PointCount(), 11 );
831 BOOST_TEST_CONTEXT(
"Case 1: Point not in the chain" )
834 BOOST_CHECK_EQUAL( chainCopy.
Split(
VECTOR2I( 400000, 0 ) ), -1 );
835 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() );
836 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
839 BOOST_TEST_CONTEXT(
"Case 2: Point close to start of a segment" )
843 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 1 );
845 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 1 ), splitPoint );
846 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() + 1 );
847 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
850 BOOST_TEST_CONTEXT(
"Case 3: Point exactly on the segment" )
854 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 1 );
856 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 1 ), splitPoint );
857 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() );
858 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
861 BOOST_TEST_CONTEXT(
"Case 4: Point at start of arc" )
865 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 2 );
867 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 2 ), splitPoint );
868 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() );
869 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
872 BOOST_TEST_CONTEXT(
"Case 5: Point close to start of arc" )
876 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 3 );
878 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 3 ), splitPoint );
879 BOOST_CHECK_EQUAL( chainCopy.
IsSharedPt( 3 ),
true );
880 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() + 1 );
881 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() + 1 );
896 BOOST_CHECK_EQUAL( chain.PointCount(), 3 );
898 chain.Append( firstArc );
899 BOOST_CHECK_EQUAL( chain.PointCount(), 10 );
901 chain.Append( targetSegment.
A );
902 chain.Append( targetSegment.
B );
903 BOOST_CHECK_EQUAL( chain.PointCount(), 12 );
905 chain.Append( secondArc );
906 BOOST_CHECK_EQUAL( chain.PointCount(), 20 );
912 BOOST_TEST_CONTEXT(
"Case 1: Start at arc endpoint, finish middle of arc" )
917 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
923 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP0(), expectedSliceArc0.
GetP0() );
927 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 10 );
928 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ), firstArc.
GetP1() );
929 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 1 ), targetSegment.
A );
930 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 2 ), targetSegment.
B );
931 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 3 ), expectedSliceArc0.
GetP0() );
932 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 3 ),
true );
934 for(
int i = 4; i <= 8; i++ )
935 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
937 for(
int i = 3; i <= 7; i++ )
938 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
940 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 9 ),
true );
941 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 9 ), expectedSliceArc0.
GetP1() );
947 BOOST_TEST_CONTEXT(
"Case 2: Start at middle of an arc, finish at arc startpoint" )
952 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
958 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP1(),
959 expectedSliceArc0.
GetP1() );
963 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 8 );
964 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
965 expectedSliceArc0.
GetP0() );
966 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
968 for(
int i = 1; i <= 4; i++ )
969 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
971 for(
int i = 0; i <= 3; i++ )
972 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
974 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 4 ),
true );
975 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 4 ),
976 expectedSliceArc0.
GetP1() );
978 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 5 ), targetSegment.
A );
979 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 6 ), targetSegment.
B );
980 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 7 ), secondArc.
GetP0() );
986 BOOST_TEST_CONTEXT(
"Case 3: Full arc, nothing else" )
991 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
995 BOOST_CHECK_EQUAL( firstArc.
GetP1(), sliceArc0.
GetP1() );
997 BOOST_CHECK_EQUAL( firstArc.
GetP1(), sliceArc0.
GetP1() );
999 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 7 );
1000 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ), sliceArc0.
GetP0() );
1001 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1003 for(
int i = 1; i <= 6; i++ )
1004 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1006 for(
int i = 0; i <= 5; i++ )
1007 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1009 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 6 ),
true );
1010 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 6 ), sliceArc0.
GetP1() );
1016 BOOST_TEST_CONTEXT(
"Case 4: Full arc, and straight segments to next arc start" )
1021 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1025 BOOST_CHECK_EQUAL( firstArc.
GetP1(), sliceArc0.
GetP1() );
1027 BOOST_CHECK_EQUAL( firstArc.
GetP1(), sliceArc0.
GetP1() );
1029 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 10 );
1030 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ), sliceArc0.
GetP0() );
1031 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1033 for(
int i = 1; i <= 6; i++ )
1034 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1036 for(
int i = 0; i <= 5; i++ )
1037 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1039 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 6 ),
true );
1040 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 6 ), sliceArc0.
GetP1() );
1042 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 7 ), targetSegment.
A );
1043 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 8 ), targetSegment.
B );
1044 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 9 ), secondArc.
GetP0() );
1047 BOOST_TEST_CONTEXT(
"Case 5: Chain ends in arc and point" )
1054 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( -1 ),
VECTOR2I( 400000, 400000 ) );
1057 BOOST_TEST_CONTEXT(
"Case 6: Start to end, chain with one point" )
1062 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 1 );
1063 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
VECTOR2I( 233450000, 228360000 ) );
1064 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( -1 ),
VECTOR2I( 233450000, 228360000 ) );
1067 BOOST_TEST_CONTEXT(
"Case 7: Start to end, chain with two points" )
1072 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 2 );
1073 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
VECTOR2I( 233450000, 228360000 ) );
1074 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 1 ),
VECTOR2I( 263450000, 258360000 ) );
1075 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( -1 ),
VECTOR2I( 263450000, 258360000 ) );
1078 BOOST_TEST_CONTEXT(
"Case 8: Full 2nd arc, nothing else" )
1083 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1087 BOOST_CHECK_EQUAL( secondArc.
GetP1(), sliceArc0.
GetP1() );
1089 BOOST_CHECK_EQUAL( secondArc.
GetP1(), sliceArc0.
GetP1() );
1091 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 8 );
1092 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ), sliceArc0.
GetP0() );
1093 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1095 for(
int i = 1; i <= 7; i++ )
1096 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1098 for(
int i = 0; i <= 6; i++ )
1099 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1101 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 7 ),
true );
1102 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 7 ), sliceArc0.
GetP1() );
1105 BOOST_TEST_CONTEXT(
"Case 9: Start at middle of a 2nd arc, finish at end" )
1110 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1117 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP1(),
1118 expectedSliceArc0.
GetP1() );
1122 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 4 );
1123 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
1124 expectedSliceArc0.
GetP0() );
1125 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1127 for(
int i = 1; i <= 3; i++ )
1128 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1130 for(
int i = 0; i <= 2; i++ )
1131 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1133 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 3 ),
true );
1134 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 3 ),
1135 expectedSliceArc0.
GetP1() );
1138 BOOST_TEST_CONTEXT(
"Case 10: New chain, start at arc middle, finish at end" )
1141 chain10.
Append( firstArc );
1146 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1153 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP1(),
1154 expectedSliceArc0.
GetP1() );
1158 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 4 );
1159 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
1160 expectedSliceArc0.
GetP0() );
1161 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1163 for(
int i = 1; i <= 3; i++ )
1164 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1166 for(
int i = 0; i <= 2; i++ )
1167 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1169 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 3 ),
true );
1170 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 3 ),
1171 expectedSliceArc0.
GetP1() );
1185 BOOST_CHECK_EQUAL( chain.PointCount(), 2 );
1187 chain.Append( arc );
1188 BOOST_CHECK_EQUAL( chain.PointCount(), 9 );
1190 chain.Append( seg2.
A );
1191 chain.Append( seg2.
B );
1192 BOOST_CHECK_EQUAL( chain.PointCount(), 11 );
1195 VECTOR2I ptOnArcCloseToStart( 297553, 31697 );
1196 VECTOR2I ptOnArcCloseToEnd( 139709, 82983 );
1198 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToStart,
true ), ptOnArcCloseToStart );
1199 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToStart,
false ), arc.
GetP0() );
1201 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToEnd,
true ), ptOnArcCloseToEnd );
1202 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToEnd,
false ), arc.
GetP1() );
1209 BOOST_TEST_INFO(
"8949 crash" );
1211 std::vector<VECTOR2I> linePts = {
1212 { 206000000, 140110000 }, { 192325020, 140110000 }, { 192325020, 113348216 },
1213 { 192251784, 113274980 }, { 175548216, 113274980 }, { 175474980, 113348216 },
1214 { 175474980, 136694980 }, { 160774511, 121994511 }, { 160774511, 121693501 },
1215 { 160086499, 121005489 }, { 159785489, 121005489 }, { 159594511, 120814511 },
1216 { 160086499, 120814511 }, { 160774511, 120126499 }, { 160774511, 119153501 },
1217 { 160086499, 118465489 }, { 159113501, 118465489 }, { 158425489, 119153501 },
1218 { 158425489, 119645489 }, { 157325020, 118545020 }, { 157325020, 101925020 },
1219 { 208674980, 101925020 }, { 208674980, 145474980 }, { 192325020, 145474980 },
1220 { 192325020, 140110000 }
1225 BOOST_CHECK_EQUAL( baseChain.
PointCount(), linePts.size() );
1228 BOOST_CHECK_EQUAL( replaceChain.PointCount(), 1 );
1230 baseChain.
Replace( 1, 23, replaceChain );
1232 BOOST_CHECK_EQUAL( baseChain.
PointCount(), linePts.size() - ( 23 - 1 ) );
1241BOOST_AUTO_TEST_SUITE_END()
const VECTOR2I & GetArcMid() const
SHAPE_ARC & ConstructFromStartEndCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aClockwise=false, double aWidth=0)
Constructs this arc from the given start, end and center.
const VECTOR2I & GetP1() const
bool Collide(const SEG &aSeg, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the segment aSeg than aClearance,...
static double DefaultAccuracyForPCB()
const VECTOR2I & GetP0() const
const VECTOR2I & GetCenter() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
bool IsPtOnArc(size_t aPtIndex) const
const SHAPE_ARC & Arc(size_t aArc) const
bool IsClosed() const override
virtual const VECTOR2I GetPoint(int aIndex) const override
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.
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.
void Simplify(int aMaxError=0)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
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.
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.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const std::vector< std::pair< ssize_t, ssize_t > > & CShapes() const
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
void RemoveShape(int aPointIndex)
Remove the shape at the given index from the line chain.
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.
const std::vector< VECTOR2I > & CPoints() const
static constexpr EDA_ANGLE ANGLE_180
bool IsOutlineValid(const SHAPE_LINE_CHAIN &aChain)
Verify that a SHAPE_LINE_CHAIN has been assembled correctly by ensuring that the arc start and end po...
Numerical test predicates.
int m_expected_point_count
int m_expected_shape_count
int m_expected_shape_count
NOTE: Collision of SHAPE_LINE_CHAIN with arcs is tested in test_shape_arc.cpp.
SHAPE_LINE_CHAIN EmptyChain
SHAPE_LINE_CHAIN Circle1Arc
SHAPE_LINE_CHAIN ArcsCoincident
SHAPE_ARC Arc1
start coincident with Arc0a end
SHAPE_ARC Arc2
Independent arc.
SHAPE_ARC Arc3
Arc with angle >180.
SHAPE_ARC Arc0a
First half of a circle.
SHAPE_LINE_CHAIN DuplicateArcs
SHAPE_LINE_CHAIN Circle2Arcs
SHAPE_LINE_CHAIN ArcsCoincidentClosed
SHAPE_LINE_CHAIN TwoPoints
SHAPE_LINE_CHAIN SegAndArcCoincident
SHAPE_LINE_CHAIN ArcsIndependent
SHAPE_ARC ArcCircle
Full Circle arc.
SHAPE_LINE_CHAIN ThreePoints
SHAPE_LINE_CHAIN ArcAndPoint
SHAPE_LINE_CHAIN ArcsAndSegMixed
SHAPE_LINE_CHAIN OnePoint
SHAPE_ARC Arc0b
Second half of a circle.
BOOST_CHECK(box.ClosestPointTo(VECTOR2D(0, 0))==VECTOR2D(1, 2))
Test suite for KiCad math code.
static const std::vector< CLOSE_TOGGLE_SHAPE_CASE > close_toggle_shape_cases
BOOST_AUTO_TEST_CASE(ClipperConstructorCase1)
static const std::vector< REMOVE_SHAPE_CASE > remove_shape_cases
VECTOR2< int32_t > VECTOR2I