diff --git a/geometry/distance.hpp b/geometry/distance.hpp index 96c9c0d6d3..3f1219f6ff 100644 --- a/geometry/distance.hpp +++ b/geometry/distance.hpp @@ -39,6 +39,8 @@ public: } } + double GetLength() const { return m_D2; } + protected: template static double SquareLength(VectorT const & v) { @@ -87,23 +89,7 @@ public: template class ProjectionToSection : public impl::CalculatedSection { public: - struct Result - { - m2::PointD m_pr; - double m_dist; - - /// 0 - closest to P0; - /// 1 - closest to P1; - /// 2 - in the middle; - int m_type; - - Result(m2::PointD const & pr, double dist, int type) - : m_pr(pr), m_dist(dist), m_type(type) - { - } - }; - - Result operator() (PointT const & Y) const + m2::PointD operator() (PointT const & Y) const { m2::PointD const YmP0 = Y - this->m_P0; double const t = DotProduct(this->m_D, YmP0); @@ -111,15 +97,15 @@ public: if (t <= 0) { // Y is closest to P0. - return Result(this->m_P0, this->Length(YmP0), 0); + return this->m_P0; } if (t >= this->m_D2) { // Y is closest to P1. - return Result(this->m_P1, this->Length(Y - this->m_P1), 1); + return this->m_P1; } - return Result(this->m_D*t + this->m_P0, fabs(this->Distance(YmP0)), 2); + return this->m_D*t + this->m_P0; } }; diff --git a/geometry/geometry_tests/distance_test.cpp b/geometry/geometry_tests/distance_test.cpp index 461af60639..26d1a79f20 100644 --- a/geometry/geometry_tests/distance_test.cpp +++ b/geometry/geometry_tests/distance_test.cpp @@ -71,8 +71,6 @@ UNIT_TEST(PointProjectionTests_Smoke) for (size_t i = 0; i < ARRAY_SIZE(arr); ++i) { p.SetBounds(arr[i][1], arr[i][2]); - m2::ProjectionToSection

::Result const res = p(arr[i][0]); - TEST(m2::AlmostEqual(res.m_pr, arr[i][3]), (i)); - TEST_ALMOST_EQUAL(res.m_dist, res.m_pr.Length(arr[i][0]), ()); + TEST(m2::AlmostEqual(p(arr[i][0]), arr[i][3]), (i)); } } diff --git a/geometry/point2d.hpp b/geometry/point2d.hpp index c164e07d45..6a1e6828f3 100644 --- a/geometry/point2d.hpp +++ b/geometry/point2d.hpp @@ -278,6 +278,17 @@ namespace m2 } } + template + int GetOrientation(PointT const & p1, PointT const & p2, PointT const & pt) + { + double const sa = CrossProduct(p1 - pt, p2 - pt); + if (sa > 0.0) + return 1; + if (sa < 0.0) + return -1; + return 0; + } + template string DebugPrint(m2::Point const & p) { ostringstream out; @@ -286,9 +297,10 @@ namespace m2 return out.str(); } - template bool AlmostEqual(m2::Point const & a, m2::Point const & b) + template + bool AlmostEqual(m2::Point const & a, m2::Point const & b, unsigned int maxULPs = 256) { - return my::AlmostEqual(a.x, b.x) && my::AlmostEqual(a.y, b.y); + return my::AlmostEqual(a.x, b.x, maxULPs) && my::AlmostEqual(a.y, b.y, maxULPs); } template @@ -322,3 +334,14 @@ namespace m2 typedef Point PointI; typedef Point PointI64; } + +namespace my +{ + +template +bool AlmostEqual(m2::Point const & p1, m2::Point const & p2, unsigned int maxULPs = 256) +{ + return m2::AlmostEqual(p1, p2, maxULPs); +} + +}