#include "testing/testing.hpp" #include "geometry/algorithm.hpp" #include "std/vector.hpp" using m2::PointD; using m2::RectD; using m2::CalculatePolyLineCenter; using m2::CalculatePointOnSurface; using m2::CalculateBoundingBox; namespace { PointD GetPolyLineCenter(vector const & points) { return m2::ApplyCalculator(points, m2::CalculatePolyLineCenter()); } RectD GetBoundingBox(vector const & points) { return m2::ApplyCalculator(points, m2::CalculateBoundingBox()); } PointD GetPointOnSurface(vector const & points) { ASSERT(!points.empty() && points.size() % 3 == 0, ("points.size() =", points.size())); auto const boundingBox = GetBoundingBox(points); return m2::ApplyCalculator(points, m2::CalculatePointOnSurface(boundingBox)); } bool PointsAlmostEqual(PointD const & p1, PointD const & p2) { return p1.EqualDxDy(p2, 1e-7); } } // namespace UNIT_TEST(CalculatePolyLineCenter) { { vector const points { {0, 0}, {1, 1}, {2, 2} }; TEST_EQUAL(GetPolyLineCenter(points), PointD(1, 1), ()); } { vector const points { {0, 2}, {1, 1}, {2, 2} }; TEST_EQUAL(GetPolyLineCenter(points), PointD(1, 1), ()); } { vector const points { {1, 1}, {2, 2}, {4, 4}, }; TEST_EQUAL(GetPolyLineCenter(points), PointD(2.5, 2.5), ()); } { vector const points { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} }; // Also logs a warning message. TEST_EQUAL(GetPolyLineCenter(points), PointD(0, 0), ()); } { vector const points { {0, 0}, {0, 0}, {0, 0}, {0, 0.000001}, {0, 0.000001}, {0, 0.000001}, {0, 0.000001} }; // Also logs a warning message. TEST(GetPolyLineCenter(points).EqualDxDy(PointD(0, .0000005), 1e-7), ()); } } UNIT_TEST(CalculateCenter) { { vector const points { {2, 2} }; TEST_EQUAL(GetBoundingBox(points), RectD({2, 2}, {2, 2}), ()); } { vector const points { {0, 0}, {1, 1}, {2, 2} }; TEST_EQUAL(GetBoundingBox(points), RectD({0, 0}, {2, 2}), ()); } { vector const points { {0, 2}, {1, 1}, {2, 2}, {1, 2}, {2, 2}, {2, 0} }; TEST_EQUAL(GetBoundingBox(points), RectD({0, 0}, {2, 2}), ()); } } UNIT_TEST(CalculatePointOnSurface) { { vector const points { {0, 0}, {1, 1}, {2, 2} }; TEST_EQUAL(GetPointOnSurface(points), PointD(1, 1), ()); } { vector const points { {0, 2}, {1, 1}, {2, 2}, {1, 2}, {2, 2}, {2, 0} }; TEST_EQUAL(GetPointOnSurface(points), PointD(1, 1), ()); } { vector const points { {0, 0}, {1, 1}, {2, 0}, {1, 1}, {2, 0}, {3, 1}, // Center of this triangle is used as a result. {2, 0}, {3, 1}, {4, 0}, {4, 0}, {3, 1}, {4, 2}, {3, 1}, {4, 2}, {3, 3}, // Or this. {4, 2}, {3, 3}, {4, 4}, {3, 3}, {4, 4}, {2, 4}, {3, 3}, {2, 4}, {1, 3}, // Or this. {1, 3}, {2, 4}, {0, 4}, {0, 4}, {1, 3}, {0, 2}, {1, 3}, {0, 2}, {1, 1}, // Or this {0, 2}, {1, 1}, {0, 0}, }; auto const result = GetPointOnSurface(points); TEST(PointsAlmostEqual(result, {10.0 / 3.0, 2}) || PointsAlmostEqual(result, {2, 2.0 / 3.0}) || PointsAlmostEqual(result, {2, 10.0 / 3.0}) || PointsAlmostEqual(result, {2.0 / 3.0, 2}), ("result = ", result)); } }