diff --git a/geometry/clipping.cpp b/geometry/clipping.cpp index f400511da7..db0de607cd 100644 --- a/geometry/clipping.cpp +++ b/geometry/clipping.cpp @@ -168,20 +168,25 @@ vector ClipSplineByRect(m2::RectD const & rect, m2::SharedSpli p2 = path[i + 1]; if (m2::Intersect(rect, p1, p2, code1, code2)) { - if ((p1 - p2).IsAlmostZero()) - continue; - if (s.IsNull()) s.Reset(new m2::Spline(path.size() - i)); s->AddPoint(p1); + s->AddPoint(p2); + if (code2 != 0 || i + 2 == path.size()) { - s->AddPoint(p2); - result.push_back(s); + if (s->GetSize() > 1) + result.push_back(s); s.Reset(nullptr); } } + else if (!s.IsNull() && !s->IsEmpty()) + { + if (s->GetSize() > 1) + result.push_back(s); + s.Reset(nullptr); + } } return result; } diff --git a/geometry/geometry_tests/clipping_test.cpp b/geometry/geometry_tests/clipping_test.cpp index 55592732ff..3aa200705d 100644 --- a/geometry/geometry_tests/clipping_test.cpp +++ b/geometry/geometry_tests/clipping_test.cpp @@ -260,5 +260,18 @@ UNIT_TEST(Clipping_ClipSplineByRect) vector expectedResult5 = ConstructSplineList({ { m2::PointD(-1.0, 0.0), m2::PointD(0.0, 0.0), m2::PointD(0.5, 0.5), m2::PointD(1.0, 0.66666666) } }); TEST(CompareSplineLists(result5, expectedResult5), ()); + + // Intersection. Several segments. + m2::SharedSpline spline6; + spline6.Reset(new m2::Spline(5)); + spline6->AddPoint(m2::PointD(-1.0, 0.0)); + spline6->AddPoint(m2::PointD(-0.5, 1.0)); + spline6->AddPoint(m2::PointD(-0.5, 1.000000001)); + spline6->AddPoint(m2::PointD(0.0, 1.5)); + spline6->AddPoint(m2::PointD(0.0, 0.0)); + vector result6 = m2::ClipSplineByRect(r, spline6); + vector expectedResult6 = ConstructSplineList({ { m2::PointD(-1.0, 0.0), m2::PointD(-0.5, 1.0) }, + { m2::PointD(0.0, 1.0), m2::PointD(0.0, 0.0) } }); + TEST(CompareSplineLists(result6, expectedResult6), ()); }