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 Clipper2Lib::Path64 pathClipper2 = {
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 } }
150 std::vector<CLIPPER_Z_VALUE> z_values = {
151 { { -1, -1 }, 0 }, { { -1, -1 }, 0 }, { { -1, -1 }, 0 }, { { -1, -1 }, 0 },
152 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
153 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
154 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
155 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
156 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
157 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
158 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
159 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
160 { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 }, { { 0, -1 }, 0 },
164 std::vector<SHAPE_ARC> arcs = {
165 SHAPE_ARC( { 127171000, 123786000 }, { 126231718, 120077003 }, { 124598846, 123537154 }, 0 )
172 BOOST_CHECK_EQUAL( clipper2chain.
PointCount(), 37 );
174 BOOST_CHECK_EQUAL( clipper2chain.
ArcCount(), 1 );
176 BOOST_CHECK_EQUAL( clipper2chain.
ShapeCount(), 2 );
178 BOOST_CHECK_EQUAL( clipper2chain.
IsClosed(),
true );
196 BOOST_CHECK_EQUAL( base_chain.CShapes().size(), base_chain.CPoints().size() );
197 BOOST_CHECK_EQUAL( arc_insert1.CShapes().size(), arc_insert1.CPoints().size() );
198 BOOST_CHECK_EQUAL( arc_insert2.
CShapes().size(), arc_insert2.
CPoints().size() );
206 BOOST_CHECK_EQUAL( base_chain.CShapes().size(), base_chain.CPoints().size() );
208 base_chain.Replace( 0, 2, chain_insert );
210 BOOST_CHECK_EQUAL( base_chain.CShapes().size(), base_chain.CPoints().size() );
228 BOOST_CHECK_EQUAL( base_chain.PointCount(), 11 );
230 base_chain.Insert( 9,
VECTOR2I( 250000, 0 ) );
232 BOOST_CHECK_EQUAL( base_chain.PointCount(), 12 );
233 BOOST_CHECK_EQUAL( base_chain.ArcCount(), 2 );
235 base_chain.Replace( 5, 6, chain_insert );
237 BOOST_CHECK_EQUAL( base_chain.PointCount(), 13 );
238 BOOST_CHECK_EQUAL( base_chain.ArcCount(), 3 );
240 base_chain.Replace( 4, 6,
VECTOR2I( 550000, 0 ) );
242 BOOST_CHECK_EQUAL( base_chain.PointCount(), 11 );
243 BOOST_CHECK_EQUAL( base_chain.ArcCount(), 3 );
246 base_chain.SetClosed(
true );
247 double areaPriorToArcRemoval = base_chain.Area();
248 base_chain.ClearArcs();
251 BOOST_CHECK_EQUAL( base_chain.CPoints().size(), base_chain.CShapes().size() );
252 BOOST_CHECK_EQUAL( base_chain.PointCount(), 11 );
253 BOOST_CHECK_EQUAL( base_chain.ArcCount(), 0 );
254 BOOST_CHECK_EQUAL( base_chain.Area(), areaPriorToArcRemoval );
264 SHAPE_ARC( { -859598, 2559876 }, { -1632771, 1022403 }, { -3170244, 249230 }, 0 ) );
267 SHAPE_ARC( { -3170244, -1657832 }, { -292804, -317564 }, { 1047464, 2559876 }, 0 ) );
276 BOOST_CHECK_EQUAL( chain.
CPoints().size(), chain.
CShapes().size() );
282 BOOST_CHECK_EQUAL( Circle2Arcs.IsClosed(),
true );
283 BOOST_CHECK_EQUAL( Circle2Arcs.PointCount(), 16 );
284 BOOST_CHECK_EQUAL( Circle2Arcs.IsArcSegment( 15 ),
true );
285 BOOST_CHECK_EQUAL( Circle2Arcs.ShapeCount(), 2 );
286 Circle2Arcs.SetClosed(
false );
288 BOOST_CHECK_EQUAL( Circle2Arcs.IsClosed(),
false );
289 BOOST_CHECK_EQUAL( Circle2Arcs.PointCount(), 17 );
290 BOOST_CHECK_EQUAL( Circle2Arcs.IsArcSegment( 15 ),
true );
291 BOOST_CHECK_EQUAL( Circle2Arcs.IsArcSegment( 16 ),
false );
327 BOOST_TEST_CONTEXT( c.m_ctx_name )
331 BOOST_CHECK_EQUAL( slc_case.
IsClosed(), c.m_closed );
332 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
333 BOOST_CHECK_EQUAL( slc_case.
PointCount(), c.m_point_count );
336 BOOST_CHECK_EQUAL( slc_case.
IsClosed(), !c.m_closed );
337 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_expected_shape_count );
338 BOOST_CHECK_EQUAL( slc_case.
PointCount(), c.m_expected_point_count );
341 BOOST_CHECK_EQUAL( slc_case.
IsClosed(), c.m_closed );
342 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
343 BOOST_CHECK_EQUAL( slc_case.
PointCount(), c.m_point_count );
351 SHAPE_LINE_CHAIN outline1( { { 1316455, 913576 }, { 1316455, 901129 }, { 1321102, 901129 },
352 { 1322152, 901191 }, { 1323055, 901365 }, { 1323830, 901639 },
353 { 1324543, 902036 }, { 1325121, 902521 }, { 1325581, 903100 },
354 { 1325914, 903759 }, { 1326120, 904516 }, { 1326193, 905390 },
355 { 1326121, 906253 }, { 1325915, 907005 }, { 1325581, 907667 },
356 { 1325121, 908248 }, { 1324543, 908735 }, { 1323830, 909132 },
357 { 1323055, 909406 }, { 1322153, 909579 }, { 1321102, 909641 },
358 { 1317174, 909641 }, { 1317757, 909027 }, { 1317757, 913576 } } );
359 SHAPE_LINE_CHAIN outline2( { { 1297076, 916244 }, { 1284629, 916244 }, { 1284629, 911597 },
360 { 1284691, 910547 }, { 1284865, 909644 }, { 1285139, 908869 },
361 { 1285536, 908156 }, { 1286021, 907578 }, { 1286600, 907118 },
362 { 1287259, 906785 }, { 1288016, 906579 }, { 1288890, 906506 },
363 { 1289753, 906578 }, { 1290505, 906784 }, { 1291167, 907118 },
364 { 1291748, 907578 }, { 1292235, 908156 }, { 1292632, 908869 },
365 { 1292906, 909644 }, { 1293079, 910546 }, { 1293141, 911597 },
366 { 1293141, 915525 }, { 1292527, 914942 }, { 1297076, 914942 } } );
372 outline1.SetClosed(
true );
373 outline2.SetClosed(
true );
375 BOOST_CHECK( outline1.PointInside( point1, 0,
false ) );
376 BOOST_CHECK( outline2.PointInside( point2, 0,
false ) );
384 chain.
Append( { 100, 100 } );
385 chain.
Append( { 100, 100 }, true );
386 chain.
Append( { 200, 100 } );
393 BOOST_CHECK_EQUAL( chain.
CPoints().size(), chain.
CShapes().size() );
404 chain.
Append( { 114772424, 90949410 } );
405 chain.
Append( { 114767360, 90947240 } );
406 chain.
Append( { 114772429, 90947228 } );
414 BOOST_CHECK_EQUAL( chain.
CPoints().size(), chain.
CShapes().size() );
452 chain.
Append( { 130000, 147320 } );
453 chain.
Append( { 125730, 147320 } );
454 chain.
Append( { 125730, 150630 } );
455 chain.
Append( { 128800, 153700 } );
456 chain.
Append( { 150300, 153700 } );
457 chain.
Append( { 151500, 152500 } );
458 chain.
Append( { 151500, 148900 } );
459 chain.
Append( { 149920, 147320 } );
460 chain.
Append( { 140000, 147320 } );
561 BOOST_TEST_CONTEXT( c.m_ctx_name )
564 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
565 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_arc_count );
568 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_expected_shape_count );
569 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_expected_arc_count );
580 BOOST_TEST_CONTEXT( c.m_ctx_name )
584 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
585 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_arc_count );
588 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
589 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_arc_count );
592 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_expected_shape_count );
593 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_expected_arc_count );
601 BOOST_CHECK_EQUAL( Circle1Arc.ShapeCount(), 1 );
602 BOOST_CHECK_EQUAL( Circle2Arcs.ShapeCount(), 2 );
603 BOOST_CHECK_EQUAL( ArcsCoincident.ShapeCount(), 2 );
604 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.ShapeCount(), 3 );
605 BOOST_CHECK_EQUAL( DuplicateArcs.ShapeCount(), 4 );
606 BOOST_CHECK_EQUAL( ArcAndPoint.ShapeCount(), 2 );
607 BOOST_CHECK_EQUAL( ArcsAndSegMixed.ShapeCount(), 4 );
608 BOOST_CHECK_EQUAL( SegAndArcCoincident.ShapeCount(), 2 );
609 BOOST_CHECK_EQUAL( EmptyChain.ShapeCount(), 0 );
610 BOOST_CHECK_EQUAL( OnePoint.ShapeCount(), 0 );
611 BOOST_CHECK_EQUAL( TwoPoints.ShapeCount(), 1 );
612 BOOST_CHECK_EQUAL( ThreePoints.ShapeCount(), 2 );
618 BOOST_CHECK_EQUAL( Circle1Arc.NextShape( 0 ), -1 );
620 BOOST_CHECK_EQUAL( Circle2Arcs.NextShape( 0 ), 8 );
621 BOOST_CHECK_EQUAL( Circle2Arcs.NextShape( 8 ), -1 );
623 BOOST_CHECK_EQUAL( ArcsCoincident.NextShape( 0 ), 8 );
624 BOOST_CHECK_EQUAL( ArcsCoincident.NextShape( 8 ), -1 );
626 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.NextShape( 0 ), 8 );
627 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.NextShape( 8 ), 13 );
628 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.NextShape( 13 ), -1 );
630 BOOST_CHECK_EQUAL( ArcsIndependent.NextShape( 0 ), 8 );
631 BOOST_CHECK_EQUAL( ArcsIndependent.NextShape( 8 ), 9 );
632 BOOST_CHECK_EQUAL( ArcsIndependent.NextShape( 9 ), -1 );
634 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 0 ), 8 );
635 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 8 ), 13 );
636 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 13 ), 14 );
637 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 14 ), -1 );
639 BOOST_CHECK_EQUAL( ArcAndPoint.NextShape( 0 ), 8 );
640 BOOST_CHECK_EQUAL( ArcAndPoint.NextShape( 8 ), -1 );
642 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 0 ), 8 );
643 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 8 ), 9 );
644 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 9 ), 10 );
645 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 10 ), -1 );
646 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 20 ), -1 );
647 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( -50 ), -1 );
649 BOOST_CHECK_EQUAL( SegAndArcCoincident.NextShape( 0 ), 1 );
650 BOOST_CHECK_EQUAL( SegAndArcCoincident.NextShape( 1 ), -1 );
652 BOOST_CHECK_EQUAL( EmptyChain.NextShape( 0 ), -1 );
653 BOOST_CHECK_EQUAL( EmptyChain.NextShape( 1 ), -1 );
654 BOOST_CHECK_EQUAL( EmptyChain.NextShape( 2 ), -1 );
655 BOOST_CHECK_EQUAL( EmptyChain.NextShape( -2 ), -1 );
657 BOOST_CHECK_EQUAL( OnePoint.NextShape( 0 ), -1 );
658 BOOST_CHECK_EQUAL( OnePoint.NextShape( -1 ), -1 );
659 BOOST_CHECK_EQUAL( OnePoint.NextShape( 1 ), -1 );
660 BOOST_CHECK_EQUAL( OnePoint.NextShape( 2 ), -1 );
661 BOOST_CHECK_EQUAL( OnePoint.NextShape( -2 ), -1 );
663 BOOST_CHECK_EQUAL( TwoPoints.NextShape( 0 ), -1 );
664 BOOST_CHECK_EQUAL( TwoPoints.NextShape( 1 ), -1 );
665 BOOST_CHECK_EQUAL( TwoPoints.NextShape( -1 ), -1 );
667 BOOST_CHECK_EQUAL( ThreePoints.NextShape( 0 ), 1 );
668 BOOST_CHECK_EQUAL( ThreePoints.NextShape( 1 ), -1 );
669 BOOST_CHECK_EQUAL( ThreePoints.NextShape( 2 ), -1 );
670 BOOST_CHECK_EQUAL( ThreePoints.NextShape( -1 ), -1 );
677 BOOST_TEST_CONTEXT(
"Case 1: Arc mid point nearly collinear" )
681 chain.
Append( arc, 5000 );
683 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
690 BOOST_TEST_CONTEXT(
"Case 2: Arc = Large Circle" )
694 chain.
Append( arc, 5000 );
696 BOOST_CHECK_EQUAL( chain.
ArcCount(), 1 );
703 BOOST_TEST_CONTEXT(
"Case 3: Arc = Small Circle (approximate to point)" )
707 chain.
Append( arc, 5000 );
709 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
714 BOOST_TEST_CONTEXT(
"Case 3: Small Arc (approximate to segment)" )
718 chain.
Append( arc, 5000 );
720 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
726 BOOST_TEST_CONTEXT(
"Case 4: Arc = null arc (all points coincident)" )
730 chain.
Append( arc, 5000 );
732 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
737 BOOST_TEST_CONTEXT(
"Case 5: Arc = infinite radius (all points very close)" )
741 chain.
Append( arc, 5000 );
743 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
749 BOOST_TEST_CONTEXT(
"Case 6: Arc = large radius (all points very close)" )
753 chain.
Append( arc, 5000 );
755 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
779 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 0 ),
false );
780 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 0 ),
false );
781 BOOST_CHECK_EQUAL( chain.
IsArcStart( 0 ),
true );
784 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 6 ),
true );
785 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 6 ),
true );
786 BOOST_CHECK_EQUAL( chain.
IsArcStart( 6 ),
true );
790 BOOST_CHECK_EQUAL( chain.
IsSharedPt( endIndex ),
false );
791 BOOST_CHECK_EQUAL( chain.
IsArcEnd( endIndex ),
true );
792 BOOST_CHECK_EQUAL( chain.
IsArcStart( endIndex ),
false );
796 BOOST_CHECK_EQUAL( chain.
IsPtOnArc( i ),
true );
805 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 0 ),
true );
806 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 0 ),
true );
807 BOOST_CHECK_EQUAL( chain.
IsArcStart( 0 ),
true );
810 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 6 ),
true );
811 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 6 ),
true );
812 BOOST_CHECK_EQUAL( chain.
IsArcStart( 6 ),
true );
816 BOOST_CHECK_EQUAL( chain.
IsSharedPt( endIndex ),
false );
817 BOOST_CHECK_EQUAL( chain.
IsArcEnd( endIndex ),
false );
818 BOOST_CHECK_EQUAL( chain.
IsArcStart( endIndex ),
false );
830 BOOST_CHECK_EQUAL( chain.PointCount(), 2 );
833 BOOST_CHECK_EQUAL( chain.PointCount(), 9 );
835 chain.Append( seg2.
A );
836 chain.Append( seg2.
B );
837 BOOST_CHECK_EQUAL( chain.PointCount(), 11 );
840 BOOST_TEST_CONTEXT(
"Case 1: Point not in the chain" )
843 BOOST_CHECK_EQUAL( chainCopy.
Split(
VECTOR2I( 400000, 0 ) ), -1 );
844 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() );
845 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
848 BOOST_TEST_CONTEXT(
"Case 2: Point close to start of a segment" )
852 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 1 );
854 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 1 ), splitPoint );
855 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() + 1 );
856 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
859 BOOST_TEST_CONTEXT(
"Case 3: Point exactly on the segment" )
863 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 1 );
865 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 1 ), splitPoint );
866 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() );
867 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
870 BOOST_TEST_CONTEXT(
"Case 4: Point at start of arc" )
874 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 2 );
876 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 2 ), splitPoint );
877 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() );
878 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
881 BOOST_TEST_CONTEXT(
"Case 5: Point close to start of arc" )
885 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 3 );
887 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 3 ), splitPoint );
888 BOOST_CHECK_EQUAL( chainCopy.
IsSharedPt( 3 ),
true );
889 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() + 1 );
890 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() + 1 );
905 BOOST_CHECK_EQUAL( chain.PointCount(), 3 );
907 chain.Append( firstArc );
908 BOOST_CHECK_EQUAL( chain.PointCount(), 10 );
910 chain.Append( targetSegment.
A );
911 chain.Append( targetSegment.
B );
912 BOOST_CHECK_EQUAL( chain.PointCount(), 12 );
914 chain.Append( secondArc );
915 BOOST_CHECK_EQUAL( chain.PointCount(), 20 );
921 BOOST_TEST_CONTEXT(
"Case 1: Start at arc endpoint, finish middle of arc" )
926 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
932 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP0(), expectedSliceArc0.
GetP0() );
934 BOOST_CHECK( sliceResult.
Arc( 0 ).
Collide( expectedSliceArc0.
GetP1(), tol ) );
936 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 10 );
937 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ), firstArc.
GetP1() );
938 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 1 ), targetSegment.
A );
939 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 2 ), targetSegment.
B );
940 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 3 ), expectedSliceArc0.
GetP0() );
941 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 3 ),
true );
943 for(
int i = 4; i <= 8; i++ )
944 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
946 for(
int i = 3; i <= 7; i++ )
947 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
949 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 9 ),
true );
950 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 9 ), expectedSliceArc0.
GetP1() );
956 BOOST_TEST_CONTEXT(
"Case 2: Start at middle of an arc, finish at arc startpoint" )
961 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
967 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP1(),
968 expectedSliceArc0.
GetP1() );
970 BOOST_CHECK( sliceResult.
Arc( 0 ).
Collide( expectedSliceArc0.
GetP0(), tol ) );
972 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 8 );
973 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
974 expectedSliceArc0.
GetP0() );
975 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
977 for(
int i = 1; i <= 4; i++ )
978 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
980 for(
int i = 0; i <= 3; i++ )
981 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
983 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 4 ),
true );
984 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 4 ),
985 expectedSliceArc0.
GetP1() );
987 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 5 ), targetSegment.
A );
988 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 6 ), targetSegment.
B );
989 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 7 ), secondArc.
GetP0() );
995 BOOST_TEST_CONTEXT(
"Case 3: Full arc, nothing else" )
1000 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1004 BOOST_CHECK_EQUAL( firstArc.
GetP1(), sliceArc0.
GetP1() );
1006 BOOST_CHECK_EQUAL( firstArc.
GetP1(), sliceArc0.
GetP1() );
1008 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 7 );
1009 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ), sliceArc0.
GetP0() );
1010 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1012 for(
int i = 1; i <= 6; i++ )
1013 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1015 for(
int i = 0; i <= 5; i++ )
1016 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1018 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 6 ),
true );
1019 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 6 ), sliceArc0.
GetP1() );
1025 BOOST_TEST_CONTEXT(
"Case 4: Full arc, and straight segments to next arc start" )
1030 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1034 BOOST_CHECK_EQUAL( firstArc.
GetP1(), sliceArc0.
GetP1() );
1036 BOOST_CHECK_EQUAL( firstArc.
GetP1(), sliceArc0.
GetP1() );
1038 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 10 );
1039 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ), sliceArc0.
GetP0() );
1040 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1042 for(
int i = 1; i <= 6; i++ )
1043 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1045 for(
int i = 0; i <= 5; i++ )
1046 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1048 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 6 ),
true );
1049 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 6 ), sliceArc0.
GetP1() );
1051 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 7 ), targetSegment.
A );
1052 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 8 ), targetSegment.
B );
1053 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 9 ), secondArc.
GetP0() );
1056 BOOST_TEST_CONTEXT(
"Case 5: Chain ends in arc and point" )
1063 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( -1 ),
VECTOR2I( 400000, 400000 ) );
1066 BOOST_TEST_CONTEXT(
"Case 6: Start to end, chain with one point" )
1071 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 1 );
1072 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
VECTOR2I( 233450000, 228360000 ) );
1073 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( -1 ),
VECTOR2I( 233450000, 228360000 ) );
1076 BOOST_TEST_CONTEXT(
"Case 7: Start to end, chain with two points" )
1081 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 2 );
1082 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
VECTOR2I( 233450000, 228360000 ) );
1083 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 1 ),
VECTOR2I( 263450000, 258360000 ) );
1084 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( -1 ),
VECTOR2I( 263450000, 258360000 ) );
1087 BOOST_TEST_CONTEXT(
"Case 8: Full 2nd arc, nothing else" )
1092 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1096 BOOST_CHECK_EQUAL( secondArc.
GetP1(), sliceArc0.
GetP1() );
1098 BOOST_CHECK_EQUAL( secondArc.
GetP1(), sliceArc0.
GetP1() );
1100 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 8 );
1101 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ), sliceArc0.
GetP0() );
1102 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1104 for(
int i = 1; i <= 7; i++ )
1105 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1107 for(
int i = 0; i <= 6; i++ )
1108 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1110 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 7 ),
true );
1111 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 7 ), sliceArc0.
GetP1() );
1114 BOOST_TEST_CONTEXT(
"Case 9: Start at middle of a 2nd arc, finish at end" )
1119 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1126 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP1(),
1127 expectedSliceArc0.
GetP1() );
1129 BOOST_CHECK( sliceResult.
Arc( 0 ).
Collide( expectedSliceArc0.
GetP0(), tol ) );
1131 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 4 );
1132 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
1133 expectedSliceArc0.
GetP0() );
1134 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1136 for(
int i = 1; i <= 3; i++ )
1137 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1139 for(
int i = 0; i <= 2; i++ )
1140 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1142 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 3 ),
true );
1143 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 3 ),
1144 expectedSliceArc0.
GetP1() );
1147 BOOST_TEST_CONTEXT(
"Case 10: New chain, start at arc middle, finish at end" )
1150 chain10.
Append( firstArc );
1155 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1162 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP1(),
1163 expectedSliceArc0.
GetP1() );
1165 BOOST_CHECK( sliceResult.
Arc( 0 ).
Collide( expectedSliceArc0.
GetP0(), tol ) );
1167 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 4 );
1168 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
1169 expectedSliceArc0.
GetP0() );
1170 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1172 for(
int i = 1; i <= 3; i++ )
1173 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1175 for(
int i = 0; i <= 2; i++ )
1176 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1178 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 3 ),
true );
1179 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 3 ),
1180 expectedSliceArc0.
GetP1() );
1194 BOOST_CHECK_EQUAL( chain.PointCount(), 2 );
1196 chain.Append( arc );
1197 BOOST_CHECK_EQUAL( chain.PointCount(), 9 );
1199 chain.Append( seg2.
A );
1200 chain.Append( seg2.
B );
1201 BOOST_CHECK_EQUAL( chain.PointCount(), 11 );
1204 VECTOR2I ptOnArcCloseToStart( 297553, 31697 );
1205 VECTOR2I ptOnArcCloseToEnd( 139709, 82983 );
1207 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToStart,
true ), ptOnArcCloseToStart );
1208 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToStart,
false ), arc.
GetP0() );
1210 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToEnd,
true ), ptOnArcCloseToEnd );
1211 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToEnd,
false ), arc.
GetP1() );
1218 BOOST_TEST_INFO(
"8949 crash" );
1220 std::vector<VECTOR2I> linePts = {
1221 { 206000000, 140110000 }, { 192325020, 140110000 }, { 192325020, 113348216 },
1222 { 192251784, 113274980 }, { 175548216, 113274980 }, { 175474980, 113348216 },
1223 { 175474980, 136694980 }, { 160774511, 121994511 }, { 160774511, 121693501 },
1224 { 160086499, 121005489 }, { 159785489, 121005489 }, { 159594511, 120814511 },
1225 { 160086499, 120814511 }, { 160774511, 120126499 }, { 160774511, 119153501 },
1226 { 160086499, 118465489 }, { 159113501, 118465489 }, { 158425489, 119153501 },
1227 { 158425489, 119645489 }, { 157325020, 118545020 }, { 157325020, 101925020 },
1228 { 208674980, 101925020 }, { 208674980, 145474980 }, { 192325020, 145474980 },
1229 { 192325020, 140110000 }
1234 BOOST_CHECK_EQUAL( baseChain.
PointCount(), linePts.size() );
1237 BOOST_CHECK_EQUAL( replaceChain.PointCount(), 1 );
1239 baseChain.
Replace( 1, 23, replaceChain );
1241 BOOST_CHECK_EQUAL( baseChain.
PointCount(), linePts.size() - ( 23 - 1 ) );
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_AUTO_TEST_SUITE_END()
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