From 339cf3f2e240e60376b72f5ab8eb53cfe49433fb Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Tue, 30 Apr 2024 16:09:50 -0700 Subject: [PATCH] Fix simplify routine for last segment The last segment of a track could be removed when the iterator does not correctly loop. Keeping the ll within bounds and checking for equivalency instead of comparison works for last point --- libs/kimath/src/geometry/shape_line_chain.cpp | 2 +- .../kimath/geometry/test_shape_line_chain.cpp | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libs/kimath/src/geometry/shape_line_chain.cpp b/libs/kimath/src/geometry/shape_line_chain.cpp index 34055cfe72..f196e04c8c 100644 --- a/libs/kimath/src/geometry/shape_line_chain.cpp +++ b/libs/kimath/src/geometry/shape_line_chain.cpp @@ -2418,7 +2418,7 @@ void SHAPE_LINE_CHAIN::Simplify( int aMaxError ) { bool too_far = false; - for( size_t ll = ii + 1; ll < kk; ++ll ) + for( size_t ll = ( ii + 1 ) % m_points.size(); ll != kk; ++ll ) { if( !TestSegmentHitFast( m_points[ll], m_points[ii], m_points[kk], aMaxError ) ) { diff --git a/qa/tests/libs/kimath/geometry/test_shape_line_chain.cpp b/qa/tests/libs/kimath/geometry/test_shape_line_chain.cpp index 6eb353c269..0957bbc49d 100644 --- a/qa/tests/libs/kimath/geometry/test_shape_line_chain.cpp +++ b/qa/tests/libs/kimath/geometry/test_shape_line_chain.cpp @@ -387,6 +387,27 @@ BOOST_AUTO_TEST_CASE( SimplifyDuplicatePoint ) } +// Test that duplicate point gets removed when we call simplify +BOOST_AUTO_TEST_CASE( SimplifyKeepEndPoint ) +{ + SHAPE_LINE_CHAIN chain; + + chain.Append( { 114772424, 90949410 } ); + chain.Append( { 114767360, 90947240 } ); + chain.Append( { 114772429, 90947228 } ); + chain.SetClosed( true ); + + BOOST_CHECK( GEOM_TEST::IsOutlineValid( chain ) ); + BOOST_CHECK_EQUAL( chain.PointCount(), 3 ); + + chain.Simplify(); + + BOOST_CHECK_EQUAL( chain.CPoints().size(), chain.CShapes().size() ); + BOOST_CHECK_EQUAL( chain.PointCount(), 3 ); + BOOST_CHECK( GEOM_TEST::IsOutlineValid( chain ) ); +} + + struct REMOVE_SHAPE_CASE { std::string m_ctx_name;