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 );
372 SHAPE_LINE_CHAIN outline1( { { 1316455, 913576 }, { 1316455, 901129 }, { 1321102, 901129 },
373 { 1322152, 901191 }, { 1323055, 901365 }, { 1323830, 901639 },
374 { 1324543, 902036 }, { 1325121, 902521 }, { 1325581, 903100 },
375 { 1325914, 903759 }, { 1326120, 904516 }, { 1326193, 905390 },
376 { 1326121, 906253 }, { 1325915, 907005 }, { 1325581, 907667 },
377 { 1325121, 908248 }, { 1324543, 908735 }, { 1323830, 909132 },
378 { 1323055, 909406 }, { 1322153, 909579 }, { 1321102, 909641 },
379 { 1317174, 909641 }, { 1317757, 909027 }, { 1317757, 913576 } } );
380 SHAPE_LINE_CHAIN outline2( { { 1297076, 916244 }, { 1284629, 916244 }, { 1284629, 911597 },
381 { 1284691, 910547 }, { 1284865, 909644 }, { 1285139, 908869 },
382 { 1285536, 908156 }, { 1286021, 907578 }, { 1286600, 907118 },
383 { 1287259, 906785 }, { 1288016, 906579 }, { 1288890, 906506 },
384 { 1289753, 906578 }, { 1290505, 906784 }, { 1291167, 907118 },
385 { 1291748, 907578 }, { 1292235, 908156 }, { 1292632, 908869 },
386 { 1292906, 909644 }, { 1293079, 910546 }, { 1293141, 911597 },
387 { 1293141, 915525 }, { 1292527, 914942 }, { 1297076, 914942 } } );
393 outline1.SetClosed(
true );
394 outline2.SetClosed(
true );
396 BOOST_CHECK( outline1.PointInside( point1, 0,
false ) );
397 BOOST_CHECK( outline2.PointInside( point2, 0,
false ) );
405 chain.
Append( { 100, 100 } );
406 chain.
Append( { 100, 100 }, true );
407 chain.
Append( { 200, 100 } );
414 BOOST_CHECK_EQUAL( chain.
CPoints().size(), chain.
CShapes().size() );
425 chain.
Append( { 114772424, 90949410 } );
426 chain.
Append( { 114767360, 90947240 } );
427 chain.
Append( { 114772429, 90947228 } );
435 BOOST_CHECK_EQUAL( chain.
CPoints().size(), chain.
CShapes().size() );
473 chain.
Append( { 130000, 147320 } );
474 chain.
Append( { 125730, 147320 } );
475 chain.
Append( { 125730, 150630 } );
476 chain.
Append( { 128800, 153700 } );
477 chain.
Append( { 150300, 153700 } );
478 chain.
Append( { 151500, 152500 } );
479 chain.
Append( { 151500, 148900 } );
480 chain.
Append( { 149920, 147320 } );
481 chain.
Append( { 140000, 147320 } );
582 BOOST_TEST_CONTEXT( c.m_ctx_name )
585 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
586 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_arc_count );
589 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_expected_shape_count );
590 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_expected_arc_count );
601 BOOST_TEST_CONTEXT( c.m_ctx_name )
605 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
606 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_arc_count );
609 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_shape_count );
610 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_arc_count );
613 BOOST_CHECK_EQUAL( slc_case.
ShapeCount(), c.m_expected_shape_count );
614 BOOST_CHECK_EQUAL( slc_case.
ArcCount(), c.m_expected_arc_count );
622 BOOST_CHECK_EQUAL( Circle1Arc.ShapeCount(), 1 );
623 BOOST_CHECK_EQUAL( Circle2Arcs.ShapeCount(), 2 );
624 BOOST_CHECK_EQUAL( ArcsCoincident.ShapeCount(), 2 );
625 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.ShapeCount(), 3 );
626 BOOST_CHECK_EQUAL( DuplicateArcs.ShapeCount(), 4 );
627 BOOST_CHECK_EQUAL( ArcAndPoint.ShapeCount(), 2 );
628 BOOST_CHECK_EQUAL( ArcsAndSegMixed.ShapeCount(), 4 );
629 BOOST_CHECK_EQUAL( SegAndArcCoincident.ShapeCount(), 2 );
630 BOOST_CHECK_EQUAL( EmptyChain.ShapeCount(), 0 );
631 BOOST_CHECK_EQUAL( OnePoint.ShapeCount(), 0 );
632 BOOST_CHECK_EQUAL( TwoPoints.ShapeCount(), 1 );
633 BOOST_CHECK_EQUAL( ThreePoints.ShapeCount(), 2 );
639 BOOST_CHECK_EQUAL( Circle1Arc.NextShape( 0 ), -1 );
641 BOOST_CHECK_EQUAL( Circle2Arcs.NextShape( 0 ), 8 );
642 BOOST_CHECK_EQUAL( Circle2Arcs.NextShape( 8 ), -1 );
644 BOOST_CHECK_EQUAL( ArcsCoincident.NextShape( 0 ), 8 );
645 BOOST_CHECK_EQUAL( ArcsCoincident.NextShape( 8 ), -1 );
647 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.NextShape( 0 ), 8 );
648 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.NextShape( 8 ), 13 );
649 BOOST_CHECK_EQUAL( ArcsCoincidentClosed.NextShape( 13 ), -1 );
651 BOOST_CHECK_EQUAL( ArcsIndependent.NextShape( 0 ), 8 );
652 BOOST_CHECK_EQUAL( ArcsIndependent.NextShape( 8 ), 9 );
653 BOOST_CHECK_EQUAL( ArcsIndependent.NextShape( 9 ), -1 );
655 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 0 ), 8 );
656 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 8 ), 13 );
657 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 13 ), 14 );
658 BOOST_CHECK_EQUAL( DuplicateArcs.NextShape( 14 ), -1 );
660 BOOST_CHECK_EQUAL( ArcAndPoint.NextShape( 0 ), 8 );
661 BOOST_CHECK_EQUAL( ArcAndPoint.NextShape( 8 ), -1 );
663 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 0 ), 8 );
664 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 8 ), 9 );
665 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 9 ), 10 );
666 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 10 ), -1 );
667 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( 20 ), -1 );
668 BOOST_CHECK_EQUAL( ArcsAndSegMixed.NextShape( -50 ), -1 );
670 BOOST_CHECK_EQUAL( SegAndArcCoincident.NextShape( 0 ), 1 );
671 BOOST_CHECK_EQUAL( SegAndArcCoincident.NextShape( 1 ), -1 );
673 BOOST_CHECK_EQUAL( EmptyChain.NextShape( 0 ), -1 );
674 BOOST_CHECK_EQUAL( EmptyChain.NextShape( 1 ), -1 );
675 BOOST_CHECK_EQUAL( EmptyChain.NextShape( 2 ), -1 );
676 BOOST_CHECK_EQUAL( EmptyChain.NextShape( -2 ), -1 );
678 BOOST_CHECK_EQUAL( OnePoint.NextShape( 0 ), -1 );
679 BOOST_CHECK_EQUAL( OnePoint.NextShape( -1 ), -1 );
680 BOOST_CHECK_EQUAL( OnePoint.NextShape( 1 ), -1 );
681 BOOST_CHECK_EQUAL( OnePoint.NextShape( 2 ), -1 );
682 BOOST_CHECK_EQUAL( OnePoint.NextShape( -2 ), -1 );
684 BOOST_CHECK_EQUAL( TwoPoints.NextShape( 0 ), -1 );
685 BOOST_CHECK_EQUAL( TwoPoints.NextShape( 1 ), -1 );
686 BOOST_CHECK_EQUAL( TwoPoints.NextShape( -1 ), -1 );
688 BOOST_CHECK_EQUAL( ThreePoints.NextShape( 0 ), 1 );
689 BOOST_CHECK_EQUAL( ThreePoints.NextShape( 1 ), -1 );
690 BOOST_CHECK_EQUAL( ThreePoints.NextShape( 2 ), -1 );
691 BOOST_CHECK_EQUAL( ThreePoints.NextShape( -1 ), -1 );
698 BOOST_TEST_CONTEXT(
"Case 1: Arc mid point nearly collinear" )
702 chain.
Append( arc, 5000 );
704 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
711 BOOST_TEST_CONTEXT(
"Case 2: Arc = Large Circle" )
715 chain.
Append( arc, 5000 );
717 BOOST_CHECK_EQUAL( chain.
ArcCount(), 1 );
724 BOOST_TEST_CONTEXT(
"Case 3: Arc = Small Circle (approximate to point)" )
728 chain.
Append( arc, 5000 );
730 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
735 BOOST_TEST_CONTEXT(
"Case 3: Small Arc (approximate to segment)" )
739 chain.
Append( arc, 5000 );
741 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
747 BOOST_TEST_CONTEXT(
"Case 4: Arc = null arc (all points coincident)" )
751 chain.
Append( arc, 5000 );
753 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
758 BOOST_TEST_CONTEXT(
"Case 5: Arc = infinite radius (all points very close)" )
762 chain.
Append( arc, 5000 );
764 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
770 BOOST_TEST_CONTEXT(
"Case 6: Arc = large radius (all points very close)" )
774 chain.
Append( arc, 5000 );
776 BOOST_CHECK_EQUAL( chain.
ArcCount(), 0 );
800 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 0 ),
false );
801 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 0 ),
false );
802 BOOST_CHECK_EQUAL( chain.
IsArcStart( 0 ),
true );
805 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 6 ),
true );
806 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 6 ),
true );
807 BOOST_CHECK_EQUAL( chain.
IsArcStart( 6 ),
true );
811 BOOST_CHECK_EQUAL( chain.
IsSharedPt( endIndex ),
false );
812 BOOST_CHECK_EQUAL( chain.
IsArcEnd( endIndex ),
true );
813 BOOST_CHECK_EQUAL( chain.
IsArcStart( endIndex ),
false );
817 BOOST_CHECK_EQUAL( chain.
IsPtOnArc( i ),
true );
826 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 0 ),
true );
827 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 0 ),
true );
828 BOOST_CHECK_EQUAL( chain.
IsArcStart( 0 ),
true );
831 BOOST_CHECK_EQUAL( chain.
IsSharedPt( 6 ),
true );
832 BOOST_CHECK_EQUAL( chain.
IsArcEnd( 6 ),
true );
833 BOOST_CHECK_EQUAL( chain.
IsArcStart( 6 ),
true );
837 BOOST_CHECK_EQUAL( chain.
IsSharedPt( endIndex ),
false );
838 BOOST_CHECK_EQUAL( chain.
IsArcEnd( endIndex ),
false );
839 BOOST_CHECK_EQUAL( chain.
IsArcStart( endIndex ),
false );
851 BOOST_CHECK_EQUAL( chain.PointCount(), 2 );
854 BOOST_CHECK_EQUAL( chain.PointCount(), 9 );
856 chain.Append( seg2.
A );
857 chain.Append( seg2.
B );
858 BOOST_CHECK_EQUAL( chain.PointCount(), 11 );
861 BOOST_TEST_CONTEXT(
"Case 1: Point not in the chain" )
864 BOOST_CHECK_EQUAL( chainCopy.
Split(
VECTOR2I( 400000, 0 ) ), -1 );
865 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() );
866 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
869 BOOST_TEST_CONTEXT(
"Case 2: Point close to start of a segment" )
873 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 1 );
875 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 1 ), splitPoint );
876 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() + 1 );
877 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
880 BOOST_TEST_CONTEXT(
"Case 3: Point exactly on the segment" )
884 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 1 );
886 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 1 ), splitPoint );
887 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() );
888 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
891 BOOST_TEST_CONTEXT(
"Case 4: Point at start of arc" )
895 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 2 );
897 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 2 ), splitPoint );
898 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() );
899 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() );
902 BOOST_TEST_CONTEXT(
"Case 5: Point close to start of arc" )
906 BOOST_CHECK_EQUAL( chainCopy.
Split( splitPoint ), 3 );
908 BOOST_CHECK_EQUAL( chainCopy.
GetPoint( 3 ), splitPoint );
909 BOOST_CHECK_EQUAL( chainCopy.
IsSharedPt( 3 ),
true );
910 BOOST_CHECK_EQUAL( chainCopy.
PointCount(), chain.PointCount() + 1 );
911 BOOST_CHECK_EQUAL( chainCopy.
ArcCount(), chain.ArcCount() + 1 );
926 BOOST_CHECK_EQUAL( chain.PointCount(), 3 );
928 chain.Append( firstArc );
929 BOOST_CHECK_EQUAL( chain.PointCount(), 10 );
931 chain.Append( targetSegment.
A );
932 chain.Append( targetSegment.
B );
933 BOOST_CHECK_EQUAL( chain.PointCount(), 12 );
935 chain.Append( secondArc );
936 BOOST_CHECK_EQUAL( chain.PointCount(), 20 );
942 BOOST_TEST_CONTEXT(
"Case 1: Start at arc endpoint, finish middle of arc" )
947 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
953 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP0(), expectedSliceArc0.
GetP0() );
955 BOOST_CHECK( sliceResult.
Arc( 0 ).
Collide( expectedSliceArc0.
GetP1(), tol ) );
957 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 10 );
958 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ), firstArc.
GetP1() );
959 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 1 ), targetSegment.
A );
960 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 2 ), targetSegment.
B );
961 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 3 ), expectedSliceArc0.
GetP0() );
962 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 3 ),
true );
964 for(
int i = 4; i <= 8; i++ )
965 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
967 for(
int i = 3; i <= 7; i++ )
968 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
970 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 9 ),
true );
971 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 9 ), expectedSliceArc0.
GetP1() );
977 BOOST_TEST_CONTEXT(
"Case 2: Start at middle of an arc, finish at arc startpoint" )
982 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
988 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP1(),
989 expectedSliceArc0.
GetP1() );
991 BOOST_CHECK( sliceResult.
Arc( 0 ).
Collide( expectedSliceArc0.
GetP0(), tol ) );
993 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 8 );
994 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
995 expectedSliceArc0.
GetP0() );
996 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
998 for(
int i = 1; i <= 4; i++ )
999 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1001 for(
int i = 0; i <= 3; i++ )
1002 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1004 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 4 ),
true );
1005 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 4 ),
1006 expectedSliceArc0.
GetP1() );
1008 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 5 ), targetSegment.
A );
1009 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 6 ), targetSegment.
B );
1010 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 7 ), secondArc.
GetP0() );
1016 BOOST_TEST_CONTEXT(
"Case 3: Full arc, nothing else" )
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(), 7 );
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() );
1046 BOOST_TEST_CONTEXT(
"Case 4: Full arc, and straight segments to next arc start" )
1051 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1055 BOOST_CHECK_EQUAL( firstArc.
GetP1(), sliceArc0.
GetP1() );
1057 BOOST_CHECK_EQUAL( firstArc.
GetP1(), sliceArc0.
GetP1() );
1059 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 10 );
1060 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ), sliceArc0.
GetP0() );
1061 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1063 for(
int i = 1; i <= 6; i++ )
1064 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1066 for(
int i = 0; i <= 5; i++ )
1067 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1069 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 6 ),
true );
1070 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 6 ), sliceArc0.
GetP1() );
1072 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 7 ), targetSegment.
A );
1073 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 8 ), targetSegment.
B );
1074 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 9 ), secondArc.
GetP0() );
1077 BOOST_TEST_CONTEXT(
"Case 5: Chain ends in arc and point" )
1084 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( -1 ),
VECTOR2I( 400000, 400000 ) );
1087 BOOST_TEST_CONTEXT(
"Case 6: Start to end, chain with one point" )
1092 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 1 );
1093 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
VECTOR2I( 233450000, 228360000 ) );
1094 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( -1 ),
VECTOR2I( 233450000, 228360000 ) );
1097 BOOST_TEST_CONTEXT(
"Case 7: Start to end, chain with two points" )
1102 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 2 );
1103 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
VECTOR2I( 233450000, 228360000 ) );
1104 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 1 ),
VECTOR2I( 263450000, 258360000 ) );
1105 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( -1 ),
VECTOR2I( 263450000, 258360000 ) );
1108 BOOST_TEST_CONTEXT(
"Case 8: Full 2nd arc, nothing else" )
1113 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1117 BOOST_CHECK_EQUAL( secondArc.
GetP1(), sliceArc0.
GetP1() );
1119 BOOST_CHECK_EQUAL( secondArc.
GetP1(), sliceArc0.
GetP1() );
1121 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 8 );
1122 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ), sliceArc0.
GetP0() );
1123 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1125 for(
int i = 1; i <= 7; i++ )
1126 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1128 for(
int i = 0; i <= 6; i++ )
1129 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1131 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 7 ),
true );
1132 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 7 ), sliceArc0.
GetP1() );
1135 BOOST_TEST_CONTEXT(
"Case 9: Start at middle of a 2nd arc, finish at end" )
1140 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1147 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP1(),
1148 expectedSliceArc0.
GetP1() );
1150 BOOST_CHECK( sliceResult.
Arc( 0 ).
Collide( expectedSliceArc0.
GetP0(), tol ) );
1152 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 4 );
1153 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
1154 expectedSliceArc0.
GetP0() );
1155 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1157 for(
int i = 1; i <= 3; i++ )
1158 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1160 for(
int i = 0; i <= 2; i++ )
1161 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1163 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 3 ),
true );
1164 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 3 ),
1165 expectedSliceArc0.
GetP1() );
1168 BOOST_TEST_CONTEXT(
"Case 10: New chain, start at arc middle, finish at end" )
1171 chain10.
Append( firstArc );
1176 BOOST_CHECK_EQUAL( sliceResult.
ArcCount(), 1 );
1183 BOOST_CHECK_EQUAL( sliceResult.
Arc( 0 ).
GetP1(),
1184 expectedSliceArc0.
GetP1() );
1186 BOOST_CHECK( sliceResult.
Arc( 0 ).
Collide( expectedSliceArc0.
GetP0(), tol ) );
1188 BOOST_CHECK_EQUAL( sliceResult.
PointCount(), 4 );
1189 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 0 ),
1190 expectedSliceArc0.
GetP0() );
1191 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( 0 ),
true );
1193 for(
int i = 1; i <= 3; i++ )
1194 BOOST_CHECK_EQUAL( sliceResult.
IsArcStart( i ),
false );
1196 for(
int i = 0; i <= 2; i++ )
1197 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( i ),
false );
1199 BOOST_CHECK_EQUAL( sliceResult.
IsArcEnd( 3 ),
true );
1200 BOOST_CHECK_EQUAL( sliceResult.
GetPoint( 3 ),
1201 expectedSliceArc0.
GetP1() );
1215 BOOST_CHECK_EQUAL( chain.PointCount(), 2 );
1217 chain.Append( arc );
1218 BOOST_CHECK_EQUAL( chain.PointCount(), 9 );
1220 chain.Append( seg2.
A );
1221 chain.Append( seg2.
B );
1222 BOOST_CHECK_EQUAL( chain.PointCount(), 11 );
1225 VECTOR2I ptOnArcCloseToStart( 297553, 31697 );
1226 VECTOR2I ptOnArcCloseToEnd( 139709, 82983 );
1228 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToStart,
true ), ptOnArcCloseToStart );
1229 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToStart,
false ), arc.
GetP0() );
1231 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToEnd,
true ), ptOnArcCloseToEnd );
1232 BOOST_CHECK_EQUAL( chain.NearestPoint( ptOnArcCloseToEnd,
false ), arc.
GetP1() );
1239 BOOST_TEST_INFO(
"8949 crash" );
1241 std::vector<VECTOR2I> linePts = {
1242 { 206000000, 140110000 }, { 192325020, 140110000 }, { 192325020, 113348216 },
1243 { 192251784, 113274980 }, { 175548216, 113274980 }, { 175474980, 113348216 },
1244 { 175474980, 136694980 }, { 160774511, 121994511 }, { 160774511, 121693501 },
1245 { 160086499, 121005489 }, { 159785489, 121005489 }, { 159594511, 120814511 },
1246 { 160086499, 120814511 }, { 160774511, 120126499 }, { 160774511, 119153501 },
1247 { 160086499, 118465489 }, { 159113501, 118465489 }, { 158425489, 119153501 },
1248 { 158425489, 119645489 }, { 157325020, 118545020 }, { 157325020, 101925020 },
1249 { 208674980, 101925020 }, { 208674980, 145474980 }, { 192325020, 145474980 },
1250 { 192325020, 140110000 }
1255 BOOST_CHECK_EQUAL( baseChain.
PointCount(), linePts.size() );
1258 BOOST_CHECK_EQUAL( replaceChain.PointCount(), 1 );
1260 baseChain.
Replace( 1, 23, replaceChain );
1262 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