Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Pimenov <m@maps.me>2018-07-23 19:29:00 +0300
committerVlad Mihaylenko <vxmihaylenko@gmail.com>2018-07-25 18:49:59 +0300
commit845af4ae26f41e86d2db9399420c19ec04b43d05 (patch)
tree6b7c4d696579d9f5b9d304dd7ed7246767244925 /geometry
parent4e146ec1ed8f8aed0d07ab6f0fe49d067b4c9901 (diff)
[geometry] Coding style fixes.
Diffstat (limited to 'geometry')
-rw-r--r--geometry/algorithm.cpp5
-rw-r--r--geometry/angles.cpp10
-rw-r--r--geometry/angles.hpp212
-rw-r--r--geometry/any_rect2d.hpp395
-rw-r--r--geometry/avg_vector.hpp171
-rw-r--r--geometry/clipping.cpp60
-rw-r--r--geometry/clipping.hpp25
-rw-r--r--geometry/covering.hpp26
-rw-r--r--geometry/covering_utils.hpp29
-rw-r--r--geometry/distance.hpp116
-rw-r--r--geometry/distance_on_sphere.cpp17
-rw-r--r--geometry/distance_on_sphere.hpp9
-rw-r--r--geometry/geometry_tests/point_test.cpp23
-rw-r--r--geometry/geometry_tests/polygon_test.cpp147
-rw-r--r--geometry/geometry_tests/tree_test.cpp93
-rw-r--r--geometry/latlon.cpp9
-rw-r--r--geometry/latlon.hpp13
-rw-r--r--geometry/line2d.hpp8
-rw-r--r--geometry/mercator.cpp19
-rw-r--r--geometry/mercator.hpp73
-rw-r--r--geometry/packer.cpp268
-rw-r--r--geometry/packer.hpp138
-rw-r--r--geometry/point2d.hpp514
-rw-r--r--geometry/polyline2d.hpp41
-rw-r--r--geometry/rect2d.hpp626
-rw-r--r--geometry/region2d.hpp580
-rw-r--r--geometry/robust_orientation.cpp96
-rw-r--r--geometry/robust_orientation.hpp203
-rw-r--r--geometry/screenbase.cpp166
-rw-r--r--geometry/screenbase.hpp132
-rw-r--r--geometry/segment2d.cpp11
-rw-r--r--geometry/tree4d.hpp390
32 files changed, 2197 insertions, 2428 deletions
diff --git a/geometry/algorithm.cpp b/geometry/algorithm.cpp
index c8c34ce000..751476f7d5 100644
--- a/geometry/algorithm.cpp
+++ b/geometry/algorithm.cpp
@@ -3,9 +3,12 @@
#include "base/logging.hpp"
+using namespace std;
+
namespace m2
{
-// CalculatePolyLineCenter -----------------------------------------------------------------------------
+// CalculatePolyLineCenter
+// -----------------------------------------------------------------------------
void CalculatePolyLineCenter::operator()(m2::PointD const & pt)
{
diff --git a/geometry/angles.cpp b/geometry/angles.cpp
index 7abf02c77a..c911abf0b3 100644
--- a/geometry/angles.cpp
+++ b/geometry/angles.cpp
@@ -1,16 +1,14 @@
#include "geometry/angles.hpp"
-
namespace ang
{
-
double AngleIn2PI(double ang)
{
double const period = 2.0 * math::pi;
ang = fmod(ang, period);
if (ang < 0.0)
ang += period;
-
+
if (my::AlmostEqualULPs(period, ang))
return 0.0;
@@ -29,7 +27,7 @@ double GetShortestDistance(double rad1, double rad2)
if (res < 0.0)
res = period + res;
else
- res = - period + res;
+ res = -period + res;
}
return res;
}
@@ -44,9 +42,7 @@ double GetMiddleAngle(double a1, double a2)
ang -= math::pi;
else
ang += math::pi;
-
}
return ang;
}
-
-}
+} // namespace ang
diff --git a/geometry/angles.hpp b/geometry/angles.hpp
index 0371fe0dbc..ce16c60b78 100644
--- a/geometry/angles.hpp
+++ b/geometry/angles.hpp
@@ -4,130 +4,116 @@
#include "base/matrix.hpp"
-#include "std/cmath.hpp"
-#include "std/string.hpp"
-
+#include <cmath>
+#include <string>
namespace ang
{
- template <typename T>
- class Angle
- {
- T m_val;
- T m_sin;
- T m_cos;
-
- public:
- Angle() : m_val(0), m_sin(0), m_cos(1) {}
- Angle(T const & val) : m_val(val), m_sin(::sin(val)), m_cos(::cos(val)) {}
- Angle(T const & sin, T const & cos) : m_val(::atan2(sin, cos)), m_sin(sin), m_cos(cos) {}
-
- T const & val() const
- {
- return m_val;
- }
-
- T const & sin() const
- {
- return m_sin;
- }
-
- T const & cos() const
- {
- return m_cos;
- }
-
- Angle<T> const & operator*=(math::Matrix<T, 3, 3> const & m)
- {
- m2::Point<T> pt0(0, 0);
- m2::Point<T> pt1(m_cos, m_sin);
-
- pt1 *= m;
- pt0 *= m;
-
- m_val = atan2(pt1.y - pt0.y, pt1.x - pt0.x);
- m_sin = ::sin(m_val);
- m_cos = ::cos(m_val);
-
- return *this;
- }
-
- friend string DebugPrint(Angle<T> const & ang)
- {
- return DebugPrint(ang.m_val);
- }
- };
-
- typedef Angle<double> AngleD;
- typedef Angle<float> AngleF;
-
- template <typename T>
- Angle<T> const operator*(Angle<T> const & a, math::Matrix<T, 3, 3> const & m)
- {
- Angle<T> ret(a);
- ret *= m;
- return ret;
- }
+template <typename T>
+class Angle
+{
+public:
+ Angle() : m_val(0), m_sin(0), m_cos(1) {}
+ Angle(T const & val) : m_val(val), m_sin(::sin(val)), m_cos(::cos(val)) {}
+ Angle(T const & sin, T const & cos) : m_val(::atan2(sin, cos)), m_sin(sin), m_cos(cos) {}
- /// Returns an angle of vector [p1, p2] from x-axis directed to y-axis.
- /// Angle is in range [-pi, pi].
- template <typename T>
- inline T AngleTo(m2::Point<T> const & p1, m2::Point<T> const & p2)
- {
- return atan2(p2.y - p1.y, p2.x - p1.x);
- }
+ T const & val() const { return m_val; }
+
+ T const & sin() const { return m_sin; }
- /// Returns an angle from vector [p, p1] to vector [p, p2]. A counterclockwise rotation.
- /// Angle is in range [0, 2 * pi]
- template <typename T>
- inline T TwoVectorsAngle(m2::Point<T> const & p, m2::Point<T> const & p1, m2::Point<T> const & p2)
+ T const & cos() const { return m_cos; }
+
+ Angle<T> const & operator*=(math::Matrix<T, 3, 3> const & m)
{
- T a = ang::AngleTo(p, p2) - ang::AngleTo(p, p1);
- while (a < 0)
- a += math::twicePi;
- return a;
+ m2::Point<T> pt0(0, 0);
+ m2::Point<T> pt1(m_cos, m_sin);
+
+ pt1 *= m;
+ pt0 *= m;
+
+ m_val = atan2(pt1.y - pt0.y, pt1.x - pt0.x);
+ m_sin = ::sin(m_val);
+ m_cos = ::cos(m_val);
+
+ return *this;
}
- double AngleIn2PI(double ang);
+ friend std::string DebugPrint(Angle<T> const & ang) { return DebugPrint(ang.m_val); }
+
+private:
+ T m_val;
+ T m_sin;
+ T m_cos;
+};
+
+using AngleD = Angle<double>;
+using AngleF = Angle<float>;
+
+template <typename T>
+Angle<T> const operator*(Angle<T> const & a, math::Matrix<T, 3, 3> const & m)
+{
+ Angle<T> ret(a);
+ ret *= m;
+ return ret;
+}
+
+/// Returns an angle of vector [p1, p2] from x-axis directed to y-axis.
+/// Angle is in range [-pi, pi].
+template <typename T>
+T AngleTo(m2::Point<T> const & p1, m2::Point<T> const & p2)
+{
+ return atan2(p2.y - p1.y, p2.x - p1.x);
+}
+
+/// Returns an angle from vector [p, p1] to vector [p, p2]. A counterclockwise rotation.
+/// Angle is in range [0, 2 * pi]
+template <typename T>
+T TwoVectorsAngle(m2::Point<T> const & p, m2::Point<T> const & p1, m2::Point<T> const & p2)
+{
+ T a = ang::AngleTo(p, p2) - ang::AngleTo(p, p1);
+ while (a < 0)
+ a += math::twicePi;
+ return a;
+}
+
+double AngleIn2PI(double ang);
- /// @return Oriented angle (<= PI) from rad1 to rad2.
- /// >0 - clockwise, <0 - counterclockwise
- double GetShortestDistance(double rad1, double rad2);
+/// @return Oriented angle (<= PI) from rad1 to rad2.
+/// >0 - clockwise, <0 - counterclockwise
+double GetShortestDistance(double rad1, double rad2);
- double GetMiddleAngle(double a1, double a2);
+double GetMiddleAngle(double a1, double a2);
- /// @return If north is zero - azimuth between geographic north and [p1, p2] vector is returned.
- /// If north is not zero - it is treated as azimuth of some custom direction(eg magnetic north or some other direction),
- /// and azimuth between that direction and [p1, p2] is returned.
- /// Azimuth is in range [0, 2 * pi]
- template <typename T>
- inline T Azimuth(m2::Point<T> const & p1, m2::Point<T> const & p2, T north = 0)
+/// @return If north is zero - azimuth between geographic north and [p1, p2] vector is returned.
+/// If north is not zero - it is treated as azimuth of some custom direction(eg magnetic north or
+/// some other direction), and azimuth between that direction and [p1, p2] is returned. Azimuth is
+/// in range [0, 2 * pi]
+template <typename T>
+T Azimuth(m2::Point<T> const & p1, m2::Point<T> const & p2, T north = 0)
+{
+ T azimuth = math::pi2 - (AngleTo(p1, p2) + north);
+ if (azimuth < 0)
+ azimuth += math::twicePi;
+ return azimuth;
+}
+
+/// Average angle calcker. Can't find any suitable solution, so decided to do like this:
+/// Avg(i) = Avg(Avg(i-1), Ai);
+class AverageCalc
+{
+public:
+ AverageCalc() : m_ang(0.0), m_isEmpty(true) {}
+
+ void Add(double a)
{
- T azimuth = math::pi2 - (AngleTo(p1, p2) + north);
- if (azimuth < 0)
- azimuth += math::twicePi;
- return azimuth;
+ m_ang = (m_isEmpty ? a : GetMiddleAngle(m_ang, a));
+ m_isEmpty = false;
}
- /// Average angle calcker. Can't find any suitable solution, so decided to do like this:
- /// Avg(i) = Avg(Avg(i-1), Ai);
- class AverageCalc
- {
- double m_ang;
- bool m_isEmpty;
-
- public:
- AverageCalc() : m_ang(0.0), m_isEmpty(true) {}
-
- void Add(double a)
- {
- m_ang = (m_isEmpty ? a : GetMiddleAngle(m_ang, a));
- m_isEmpty = false;
- }
-
- double GetAverage() const
- {
- return m_ang;
- }
- };
-}
+ double GetAverage() const { return m_ang; }
+
+private:
+ double m_ang;
+ bool m_isEmpty;
+};
+} // namespace ang
diff --git a/geometry/any_rect2d.hpp b/geometry/any_rect2d.hpp
index b538f5f99e..0a507c719f 100644
--- a/geometry/any_rect2d.hpp
+++ b/geometry/any_rect2d.hpp
@@ -1,279 +1,242 @@
#pragma once
+#include "geometry/angles.hpp"
#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"
#include "geometry/rect_intersect.hpp"
-#include "geometry/angles.hpp"
#include "base/math.hpp"
+#include <string>
namespace m2
{
- /// axis aligned rect
- template <typename T>
- class AnyRect
- {
- ang::Angle<T> m_angle;
-
- Point<T> m_zero;
- Rect<T> m_rect;
-
- static Point<T> const Convert(Point<T> const & p,
- Point<T> const & fromI, Point<T> const & fromJ,
- Point<T> const & toI, Point<T> const & toJ)
- {
- Point<T> res;
-
- res.x = p.x * DotProduct(fromI, toI) + p.y * DotProduct(fromJ, toI);
- res.y = p.x * DotProduct(fromI, toJ) + p.y * DotProduct(fromJ, toJ);
-
- return res;
- }
-
- public:
- AnyRect() : m_zero(0, 0), m_rect() {}
+/// axis aligned rect
+template <typename T>
+class AnyRect
+{
+public:
+ AnyRect() : m_zero(0, 0), m_rect() {}
- /// creating from regular rect
- explicit AnyRect(Rect<T> const & r)
+ /// creating from regular rect
+ explicit AnyRect(Rect<T> const & r)
+ {
+ if (r.IsValid())
{
- if (r.IsValid())
- {
- m_zero = Point<T>(r.minX(), r.minY());
- m_rect = Rect<T>(0, 0, r.SizeX(), r.SizeY());
- }
- else
- {
- m_zero = Point<T>(0, 0);
- m_rect = r;
- }
+ m_zero = Point<T>(r.minX(), r.minY());
+ m_rect = Rect<T>(0, 0, r.SizeX(), r.SizeY());
}
-
- AnyRect(Point<T> const & zero, ang::Angle<T> const & angle, Rect<T> const & r)
- : m_angle(angle), m_rect(r)
+ else
{
- m_zero = Convert(zero, Point<T>(1, 0), Point<T>(0, 1), i(), j());
+ m_zero = Point<T>(0, 0);
+ m_rect = r;
}
+ }
- Point<T> const & LocalZero() const
- {
- return m_zero;
- }
+ AnyRect(Point<T> const & zero, ang::Angle<T> const & angle, Rect<T> const & r)
+ : m_angle(angle), m_rect(r)
+ {
+ m_zero = Convert(zero, Point<T>(1, 0), Point<T>(0, 1), i(), j());
+ }
- Point<T> const GlobalZero() const
- {
- return Convert(m_zero, i(), j(), m2::Point<T>(1, 0), m2::Point<T>(0, 1));
- }
+ Point<T> const & LocalZero() const { return m_zero; }
- Point<T> const i() const
- {
- return Point<T>(m_angle.cos(), m_angle.sin());
- }
+ Point<T> const GlobalZero() const
+ {
+ return Convert(m_zero, i(), j(), m2::Point<T>(1, 0), m2::Point<T>(0, 1));
+ }
- Point<T> const j() const
- {
- return Point<T>(-m_angle.sin(), m_angle.cos());
- }
+ Point<T> const i() const { return Point<T>(m_angle.cos(), m_angle.sin()); }
- void SetAngle(ang::Angle<T> const & a)
- {
- m2::Point<T> glbZero = GlobalZero();
+ Point<T> const j() const { return Point<T>(-m_angle.sin(), m_angle.cos()); }
- m_angle = a;
- m_zero = Convert(glbZero, Point<T>(1, 0), Point<T>(0, 1), i(), j());
- }
+ void SetAngle(ang::Angle<T> const & a)
+ {
+ m2::Point<T> glbZero = GlobalZero();
- ang::Angle<T> const & Angle() const
- {
- return m_angle;
- }
+ m_angle = a;
+ m_zero = Convert(glbZero, Point<T>(1, 0), Point<T>(0, 1), i(), j());
+ }
- Point<T> const GlobalCenter() const
- {
- return ConvertFrom(m_rect.Center());
- }
+ ang::Angle<T> const & Angle() const { return m_angle; }
- Point<T> const LocalCenter() const
- {
- return m_rect.Center();
- }
+ Point<T> const GlobalCenter() const { return ConvertFrom(m_rect.Center()); }
- T GetMaxSize() const { return max(m_rect.SizeX(), m_rect.SizeY()); }
+ Point<T> const LocalCenter() const { return m_rect.Center(); }
- bool EqualDxDy(AnyRect<T> const & r, T eps) const
- {
- m2::Point<T> arr1[4];
- GetGlobalPoints(arr1);
- sort(arr1, arr1 + 4);
+ T GetMaxSize() const { return max(m_rect.SizeX(), m_rect.SizeY()); }
- m2::Point<T> arr2[4];
- r.GetGlobalPoints(arr2);
- sort(arr2, arr2 + 4);
+ bool EqualDxDy(AnyRect<T> const & r, T eps) const
+ {
+ m2::Point<T> arr1[4];
+ GetGlobalPoints(arr1);
+ sort(arr1, arr1 + 4);
- for (size_t i = 0; i < 4; ++i)
- if (!arr1[i].EqualDxDy(arr2[i], eps))
- return false;
+ m2::Point<T> arr2[4];
+ r.GetGlobalPoints(arr2);
+ sort(arr2, arr2 + 4);
- return true;
- }
+ for (size_t i = 0; i < 4; ++i)
+ if (!arr1[i].EqualDxDy(arr2[i], eps))
+ return false;
- bool IsPointInside(Point<T> const & pt) const
- {
- return m_rect.IsPointInside(ConvertTo(pt));
- }
+ return true;
+ }
- bool IsRectInside(AnyRect<T> const & r) const
- {
- m2::Point<T> pts[4];
- r.GetGlobalPoints(pts);
- ConvertTo(pts, 4);
- return m_rect.IsPointInside(pts[0])
- && m_rect.IsPointInside(pts[1])
- && m_rect.IsPointInside(pts[2])
- && m_rect.IsPointInside(pts[3]);
- }
+ bool IsPointInside(Point<T> const & pt) const { return m_rect.IsPointInside(ConvertTo(pt)); }
- bool IsIntersect(AnyRect<T> const & r) const
- {
- m2::Point<T> pts[4];
- if (r.GetLocalRect() == Rect<T>())
- return false;
- r.GetGlobalPoints(pts);
- ConvertTo(pts, 4);
+ bool IsRectInside(AnyRect<T> const & r) const
+ {
+ m2::Point<T> pts[4];
+ r.GetGlobalPoints(pts);
+ ConvertTo(pts, 4);
+ return m_rect.IsPointInside(pts[0]) && m_rect.IsPointInside(pts[1]) &&
+ m_rect.IsPointInside(pts[2]) && m_rect.IsPointInside(pts[3]);
+ }
- m2::Rect<T> r1(pts[0], pts[0]);
- r1.Add(pts[1]);
- r1.Add(pts[2]);
- r1.Add(pts[3]);
+ bool IsIntersect(AnyRect<T> const & r) const
+ {
+ m2::Point<T> pts[4];
+ if (r.GetLocalRect() == Rect<T>())
+ return false;
+ r.GetGlobalPoints(pts);
+ ConvertTo(pts, 4);
- if (!GetLocalRect().IsIntersect(r1))
- return false;
+ m2::Rect<T> r1(pts[0], pts[0]);
+ r1.Add(pts[1]);
+ r1.Add(pts[2]);
+ r1.Add(pts[3]);
- if (r.IsRectInside(*this))
- return true;
+ if (!GetLocalRect().IsIntersect(r1))
+ return false;
- if (IsRectInside(r))
- return true;
+ if (r.IsRectInside(*this))
+ return true;
- return Intersect(GetLocalRect(), pts[0], pts[1])
- || Intersect(GetLocalRect(), pts[1], pts[2])
- || Intersect(GetLocalRect(), pts[2], pts[3])
- || Intersect(GetLocalRect(), pts[3], pts[0]);
- }
+ if (IsRectInside(r))
+ return true;
- /// Convert into coordinate system of this AnyRect
- Point<T> const ConvertTo(Point<T> const & p) const
- {
- m2::Point<T> i1(1, 0);
- m2::Point<T> j1(0, 1);
- return Convert(p - Convert(m_zero, i(), j(), i1, j1), i1, j1, i(), j());
- }
+ return Intersect(GetLocalRect(), pts[0], pts[1]) || Intersect(GetLocalRect(), pts[1], pts[2]) ||
+ Intersect(GetLocalRect(), pts[2], pts[3]) || Intersect(GetLocalRect(), pts[3], pts[0]);
+ }
- void ConvertTo(Point<T> * pts, size_t count) const
- {
- for (size_t i = 0; i < count; ++i)
- pts[i] = ConvertTo(pts[i]);
- }
+ /// Convert into coordinate system of this AnyRect
+ Point<T> const ConvertTo(Point<T> const & p) const
+ {
+ m2::Point<T> i1(1, 0);
+ m2::Point<T> j1(0, 1);
+ return Convert(p - Convert(m_zero, i(), j(), i1, j1), i1, j1, i(), j());
+ }
- /// Convert into global coordinates from the local coordinates of this AnyRect
- Point<T> const ConvertFrom(Point<T> const & p) const
- {
- return Convert(p + m_zero, i(), j(), m2::Point<T>(1, 0), m2::Point<T>(0, 1));
- }
+ void ConvertTo(Point<T> * pts, size_t count) const
+ {
+ for (size_t i = 0; i < count; ++i)
+ pts[i] = ConvertTo(pts[i]);
+ }
- void ConvertFrom(Point<T> * pts, size_t count) const
- {
- for (size_t i = 0; i < count; ++i)
- pts[i] = ConvertFrom(pts[i]);
- }
+ /// Convert into global coordinates from the local coordinates of this AnyRect
+ Point<T> const ConvertFrom(Point<T> const & p) const
+ {
+ return Convert(p + m_zero, i(), j(), m2::Point<T>(1, 0), m2::Point<T>(0, 1));
+ }
- Rect<T> const & GetLocalRect() const
- {
- return m_rect;
- }
+ void ConvertFrom(Point<T> * pts, size_t count) const
+ {
+ for (size_t i = 0; i < count; ++i)
+ pts[i] = ConvertFrom(pts[i]);
+ }
- Rect<T> const GetGlobalRect() const
- {
- Point<T> pts[4];
- GetGlobalPoints(pts);
+ Rect<T> const & GetLocalRect() const { return m_rect; }
- Rect<T> res(pts[0], pts[1]);
- res.Add(pts[2]);
- res.Add(pts[3]);
+ Rect<T> const GetGlobalRect() const
+ {
+ Point<T> pts[4];
+ GetGlobalPoints(pts);
- return res;
- }
+ Rect<T> res(pts[0], pts[1]);
+ res.Add(pts[2]);
+ res.Add(pts[3]);
- void GetGlobalPoints(Point<T> * pts) const
- {
- pts[0] = Point<T>(ConvertFrom(Point<T>(m_rect.minX(), m_rect.minY())));
- pts[1] = Point<T>(ConvertFrom(Point<T>(m_rect.minX(), m_rect.maxY())));
- pts[2] = Point<T>(ConvertFrom(Point<T>(m_rect.maxX(), m_rect.maxY())));
- pts[3] = Point<T>(ConvertFrom(Point<T>(m_rect.maxX(), m_rect.minY())));
- }
+ return res;
+ }
- template <typename U>
- void Inflate(U const & dx, U const & dy)
- {
- m_rect.Inflate(dx, dy);
- }
+ void GetGlobalPoints(Point<T> * pts) const
+ {
+ pts[0] = Point<T>(ConvertFrom(Point<T>(m_rect.minX(), m_rect.minY())));
+ pts[1] = Point<T>(ConvertFrom(Point<T>(m_rect.minX(), m_rect.maxY())));
+ pts[2] = Point<T>(ConvertFrom(Point<T>(m_rect.maxX(), m_rect.maxY())));
+ pts[3] = Point<T>(ConvertFrom(Point<T>(m_rect.maxX(), m_rect.minY())));
+ }
- void Add(AnyRect<T> const & r)
- {
- Point<T> pts[4];
- r.GetGlobalPoints(pts);
- ConvertTo(pts, 4);
- m_rect.Add(pts[0]);
- m_rect.Add(pts[1]);
- m_rect.Add(pts[2]);
- m_rect.Add(pts[3]);
- }
+ template <typename U>
+ void Inflate(U const & dx, U const & dy)
+ {
+ m_rect.Inflate(dx, dy);
+ }
- void Offset(Point<T> const & p)
- {
- m_zero = ConvertTo(ConvertFrom(m_zero) + p);
- }
+ void Add(AnyRect<T> const & r)
+ {
+ Point<T> pts[4];
+ r.GetGlobalPoints(pts);
+ ConvertTo(pts, 4);
+ m_rect.Add(pts[0]);
+ m_rect.Add(pts[1]);
+ m_rect.Add(pts[2]);
+ m_rect.Add(pts[3]);
+ }
- Point<T> const Center() const
- {
- return ConvertFrom(m_rect.Center());
- }
+ void Offset(Point<T> const & p) { m_zero = ConvertTo(ConvertFrom(m_zero) + p); }
- void SetSizesToIncludePoint(Point<T> const & p)
- {
- m_rect.SetSizesToIncludePoint(ConvertTo(p));
- }
+ Point<T> const Center() const { return ConvertFrom(m_rect.Center()); }
- friend string DebugPrint(m2::AnyRect<T> const & r)
- {
- return "{ Zero = " + DebugPrint(r.m_zero) +
- ", Rect = " + DebugPrint(r.m_rect) +
- ", Ang = " + DebugPrint(r.m_angle) + " }";
- }
- };
+ void SetSizesToIncludePoint(Point<T> const & p) { m_rect.SetSizesToIncludePoint(ConvertTo(p)); }
- template <typename T>
- AnyRect<T> const Offset(AnyRect<T> const & r, Point<T> const & pt)
+ friend std::string DebugPrint(m2::AnyRect<T> const & r)
{
- AnyRect<T> res(r);
- res.Offset(pt);
- return res;
+ return "{ Zero = " + DebugPrint(r.m_zero) + ", Rect = " + DebugPrint(r.m_rect) +
+ ", Ang = " + DebugPrint(r.m_angle) + " }";
}
- template <typename T, typename U>
- AnyRect<T> const Inflate(AnyRect<T> const & r, U const & dx, U const & dy)
+private:
+ static Point<T> const Convert(Point<T> const & p, Point<T> const & fromI, Point<T> const & fromJ,
+ Point<T> const & toI, Point<T> const & toJ)
{
- AnyRect<T> res = r;
- res.Inflate(dx, dy);
+ Point<T> res;
+
+ res.x = p.x * DotProduct(fromI, toI) + p.y * DotProduct(fromJ, toI);
+ res.y = p.x * DotProduct(fromI, toJ) + p.y * DotProduct(fromJ, toJ);
+
return res;
}
- template <typename T, typename U>
- AnyRect<T> const Inflate(AnyRect<T> const & r, Point<U> const & pt)
- {
- return Inflate(r, pt.x, pt.y);
- }
+ ang::Angle<T> m_angle;
+
+ Point<T> m_zero;
+ Rect<T> m_rect;
+};
+
+using AnyRectD = AnyRect<double>;
+using AnyRectF = AnyRect<float>;
- typedef AnyRect<double> AnyRectD;
- typedef AnyRect<float> AnyRectF;
+template <typename T>
+AnyRect<T> const Offset(AnyRect<T> const & r, Point<T> const & pt)
+{
+ AnyRect<T> res(r);
+ res.Offset(pt);
+ return res;
+}
+
+template <typename T, typename U>
+AnyRect<T> const Inflate(AnyRect<T> const & r, U const & dx, U const & dy)
+{
+ AnyRect<T> res = r;
+ res.Inflate(dx, dy);
+ return res;
+}
+
+template <typename T, typename U>
+AnyRect<T> const Inflate(AnyRect<T> const & r, Point<U> const & pt)
+{
+ return Inflate(r, pt.x, pt.y);
}
+} // namespace m2
diff --git a/geometry/avg_vector.hpp b/geometry/avg_vector.hpp
index 2841f47509..06eefbaa0e 100644
--- a/geometry/avg_vector.hpp
+++ b/geometry/avg_vector.hpp
@@ -1,7 +1,7 @@
#pragma once
-#include "base/math.hpp"
#include "base/assert.hpp"
+#include "base/math.hpp"
#include <array>
#include <cmath>
@@ -12,105 +12,104 @@
namespace math
{
- template <class T, size_t Dim> class AvgVector
- {
- typedef std::deque<std::array<T, Dim>> ContT;
- typedef typename ContT::value_type ValueT;
+template <class T, size_t Dim>
+class AvgVector
+{
+ typedef std::deque<std::array<T, Dim>> ContT;
+ typedef typename ContT::value_type ValueT;
- ContT m_vectors;
- size_t m_count;
+ ContT m_vectors;
+ size_t m_count;
- static T Distance(ValueT const & a1, ValueT const & a2)
- {
- T res = 0;
- for (size_t i = 0; i < Dim; ++i)
- res += std::pow(a1[i] - a2[i], 2);
+ static T Distance(ValueT const & a1, ValueT const & a2)
+ {
+ T res = 0;
+ for (size_t i = 0; i < Dim; ++i)
+ res += std::pow(a1[i] - a2[i], 2);
- return sqrt(res);
- }
+ return sqrt(res);
+ }
- static void Average(ValueT const & a1, ValueT const & a2, T * res)
- {
- for (size_t i = 0; i < Dim; ++i)
- res[i] = (a1[i] + a2[i]) / 2.0;
- }
+ static void Average(ValueT const & a1, ValueT const & a2, T * res)
+ {
+ for (size_t i = 0; i < Dim; ++i)
+ res[i] = (a1[i] + a2[i]) / 2.0;
+ }
- void CalcAverage(T * res) const
- {
- T minD = std::numeric_limits<T>::max();
- size_t I = 0, J = 1;
+ void CalcAverage(T * res) const
+ {
+ T minD = std::numeric_limits<T>::max();
+ size_t I = 0, J = 1;
- size_t const count = m_vectors.size();
- ASSERT_GREATER ( count, 1, () );
- for (size_t i = 0; i < count - 1; ++i)
- for (size_t j = i+1; j < count; ++j)
+ size_t const count = m_vectors.size();
+ ASSERT_GREATER(count, 1, ());
+ for (size_t i = 0; i < count - 1; ++i)
+ for (size_t j = i + 1; j < count; ++j)
+ {
+ T const d = Distance(m_vectors[i], m_vectors[j]);
+ if (d < minD)
{
- T const d = Distance(m_vectors[i], m_vectors[j]);
- if (d < minD)
- {
- I = i;
- J = j;
- minD = d;
- }
+ I = i;
+ J = j;
+ minD = d;
}
+ }
- Average(m_vectors[I], m_vectors[J], res);
- }
-
- public:
- AvgVector(size_t count = 1) : m_count(count)
- {
- static_assert(std::is_floating_point<T>::value, "");
- }
-
- void SetCount(size_t count) { m_count = count; }
+ Average(m_vectors[I], m_vectors[J], res);
+ }
- /// @param[in] Next measurement.
- /// @param[out] Average value.
- void Next(T * arr)
- {
- if (m_vectors.size() == m_count)
- m_vectors.pop_front();
+public:
+ AvgVector(size_t count = 1) : m_count(count)
+ {
+ static_assert(std::is_floating_point<T>::value, "");
+ }
- m_vectors.push_back(ValueT());
- std::memcpy(m_vectors.back().data(), arr, Dim * sizeof(T));
+ void SetCount(size_t count) { m_count = count; }
- if (m_vectors.size() > 1)
- CalcAverage(arr);
- }
- };
-
- // Compass smoothing parameters
- // We're using technique described in
- // http://windowsteamblog.com/windows_phone/b/wpdev/archive/2010/09/08/using-the-accelerometer-on-windows-phone-7.aspx
- // In short it's a combination of low-pass filter to smooth the
- // small orientation changes and a threshold filter to get big changes fast.
- // k in the following formula: O(n) = O(n-1) + k * (I - O(n - 1));
- // smoothed heading angle. doesn't always correspond to the m_headingAngle
- // as we change the heading angle only if the delta between
- // smoothedHeadingRad and new heading value is bigger than smoothingThreshold.
- template <class T, size_t Dim> class LowPassVector
+ /// @param[in] Next measurement.
+ /// @param[out] Average value.
+ void Next(T * arr)
{
- typedef std::array<T, Dim> ArrayT;
- ArrayT m_val;
- T m_factor;
+ if (m_vectors.size() == m_count)
+ m_vectors.pop_front();
+
+ m_vectors.push_back(ValueT());
+ std::memcpy(m_vectors.back().data(), arr, Dim * sizeof(T));
+
+ if (m_vectors.size() > 1)
+ CalcAverage(arr);
+ }
+};
+
+// Compass smoothing parameters
+// We're using technique described in
+// http://windowsteamblog.com/windows_phone/b/wpdev/archive/2010/09/08/using-the-accelerometer-on-windows-phone-7.aspx
+// In short it's a combination of low-pass filter to smooth the
+// small orientation changes and a threshold filter to get big changes fast.
+// k in the following formula: O(n) = O(n-1) + k * (I - O(n - 1));
+// smoothed heading angle. doesn't always correspond to the m_headingAngle
+// as we change the heading angle only if the delta between
+// smoothedHeadingRad and new heading value is bigger than smoothingThreshold.
+template <class T, size_t Dim>
+class LowPassVector
+{
+ typedef std::array<T, Dim> ArrayT;
+ ArrayT m_val;
+ T m_factor;
- public:
- LowPassVector() : m_factor(0.15)
- {
- m_val.fill(T());
- }
- void SetFactor(T t) { m_factor = t; }
+public:
+ LowPassVector() : m_factor(0.15) { m_val.fill(T()); }
+ void SetFactor(T t) { m_factor = t; }
- /// @param[in] Next measurement.
- /// @param[out] Average value.
- void Next(T * arr)
+ /// @param[in] Next measurement.
+ /// @param[out] Average value.
+ void Next(T * arr)
+ {
+ for (size_t i = 0; i < Dim; ++i)
{
- for (size_t i = 0; i < Dim; ++i)
- {
- m_val[i] = m_val[i] + m_factor * (arr[i] - m_val[i]);
- arr[i] = m_val[i];
- }
+ m_val[i] = m_val[i] + m_factor * (arr[i] - m_val[i]);
+ arr[i] = m_val[i];
}
- };
-}
+ }
+};
+} // namespace math
diff --git a/geometry/clipping.cpp b/geometry/clipping.cpp
index db0de607cd..c08083589a 100644
--- a/geometry/clipping.cpp
+++ b/geometry/clipping.cpp
@@ -1,12 +1,14 @@
-#include "clipping.hpp"
-#include "rect_intersect.hpp"
+#include "geometry/clipping.hpp"
-#include "std/vector.hpp"
+#include "geometry/rect_intersect.hpp"
+
+#include <algorithm>
+
+using namespace std;
namespace m2
{
-
-using AddPoligonPoint = function<void(m2::PointD const &)>;
+using AddPolygonPoint = function<void(m2::PointD const &)>;
int GetRectSideIndex(int code)
{
@@ -19,9 +21,9 @@ int GetRectSideIndex(int code)
return 3;
}
-void InsertCorners(vector<m2::PointD> const & corners,
- m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3,
- AddPoligonPoint const & addPoligonPoint, int code1, int code2)
+void InsertCorners(vector<m2::PointD> const & corners, m2::PointD const & p1, m2::PointD const & p2,
+ m2::PointD const & p3, AddPolygonPoint const & addPolygonPoint, int code1,
+ int code2)
{
int cornerInd = GetRectSideIndex(code1);
int endCornerInd = GetRectSideIndex(code2);
@@ -35,15 +37,15 @@ void InsertCorners(vector<m2::PointD> const & corners,
while (cornerInd != endCornerInd)
{
- addPoligonPoint(corners[cornerInd]);
+ addPolygonPoint(corners[cornerInd]);
cornerInd = (cornerInd + 1) % 4;
}
}
bool IntersectEdge(m2::RectD const & rect, vector<m2::PointD> const & corners,
m2::PointD const & pp1, m2::PointD const & pp2, m2::PointD const & pp3,
- AddPoligonPoint const & addPoligonPoint,
- int prevClipCode, int nextClipCode, int & firstClipCode, int & lastClipCode)
+ AddPolygonPoint const & addPolygonPoint, int prevClipCode, int nextClipCode,
+ int & firstClipCode, int & lastClipCode)
{
m2::PointD p1 = pp1;
m2::PointD p2 = pp2;
@@ -51,27 +53,26 @@ bool IntersectEdge(m2::RectD const & rect, vector<m2::PointD> const & corners,
if (m2::Intersect(rect, p1, p2, firstClipCode, lastClipCode))
{
if (firstClipCode != 0 && prevClipCode != 0 && ((firstClipCode & prevClipCode) == 0))
- InsertCorners(corners, pp1, pp2, pp3, addPoligonPoint, prevClipCode, firstClipCode);
+ InsertCorners(corners, pp1, pp2, pp3, addPolygonPoint, prevClipCode, firstClipCode);
- addPoligonPoint(p1);
- addPoligonPoint(p2);
+ addPolygonPoint(p1);
+ addPolygonPoint(p2);
if (lastClipCode != 0 && nextClipCode != 0 && ((lastClipCode & nextClipCode) == 0) &&
firstClipCode != lastClipCode && prevClipCode != nextClipCode)
- InsertCorners(corners, pp1, pp2, pp3, addPoligonPoint, lastClipCode, nextClipCode);
+ InsertCorners(corners, pp1, pp2, pp3, addPolygonPoint, lastClipCode, nextClipCode);
return true;
}
else if (prevClipCode != 0 && nextClipCode != 0)
{
- InsertCorners(corners, pp1, pp2, pp3, addPoligonPoint, prevClipCode, nextClipCode);
+ InsertCorners(corners, pp1, pp2, pp3, addPolygonPoint, prevClipCode, nextClipCode);
}
return false;
}
-void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1,
- m2::PointD const & p2, m2::PointD const & p3,
- ClipTriangleByRectResultIt const & resultIterator)
+void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1, m2::PointD const & p2,
+ m2::PointD const & p3, ClipTriangleByRectResultIt const & resultIterator)
{
if (resultIterator == nullptr)
return;
@@ -84,25 +85,25 @@ void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1,
const double kEps = 1e-8;
vector<m2::PointD> poligon;
- auto const addPoligonPoint = [&poligon, kEps](m2::PointD const & pt)
- {
+ auto const addPolygonPoint = [&poligon, kEps](m2::PointD const & pt) {
if (poligon.empty() || !poligon.back().EqualDxDy(pt, kEps))
poligon.push_back(pt);
};
- vector<m2::PointD> const corners = { rect.LeftTop(), rect.RightTop(), rect.RightBottom(), rect.LeftBottom() };
+ vector<m2::PointD> const corners = {rect.LeftTop(), rect.RightTop(), rect.RightBottom(),
+ rect.LeftBottom()};
int firstClipCode[3];
int lastClipCode[3];
bool intersected[3];
- intersected[0] = IntersectEdge(rect, corners, p1, p2, p3, addPoligonPoint,
- 0, 0, firstClipCode[0], lastClipCode[0]);
+ intersected[0] = IntersectEdge(rect, corners, p1, p2, p3, addPolygonPoint, 0, 0, firstClipCode[0],
+ lastClipCode[0]);
- intersected[1] = IntersectEdge(rect, corners, p2, p3, p1, addPoligonPoint,
- lastClipCode[0], 0, firstClipCode[1], lastClipCode[1]);
+ intersected[1] = IntersectEdge(rect, corners, p2, p3, p1, addPolygonPoint, lastClipCode[0], 0,
+ firstClipCode[1], lastClipCode[1]);
- intersected[2] = IntersectEdge(rect, corners, p3, p1, p2, addPoligonPoint,
+ intersected[2] = IntersectEdge(rect, corners, p3, p1, p2, addPolygonPoint,
lastClipCode[1] != 0 ? lastClipCode[1] : lastClipCode[0],
firstClipCode[0] != 0 ? firstClipCode[0] : firstClipCode[1],
firstClipCode[2], lastClipCode[2]);
@@ -119,7 +120,7 @@ void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1,
}
if (intersectCount == 1 && intersected[2])
- InsertCorners(corners, p1, p2, p3, addPoligonPoint, lastClipCode[2], firstClipCode[2]);
+ InsertCorners(corners, p1, p2, p3, addPolygonPoint, lastClipCode[2], firstClipCode[2]);
if (!poligon.empty() && poligon.back().EqualDxDy(poligon[0], kEps))
poligon.pop_back();
@@ -190,5 +191,4 @@ vector<m2::SharedSpline> ClipSplineByRect(m2::RectD const & rect, m2::SharedSpli
}
return result;
}
-
-} // namespace m2;
+} // namespace m2;
diff --git a/geometry/clipping.hpp b/geometry/clipping.hpp
index 58b7691d44..27a2e25d64 100644
--- a/geometry/clipping.hpp
+++ b/geometry/clipping.hpp
@@ -1,20 +1,21 @@
#pragma once
-#include "rect2d.hpp"
-#include "spline.hpp"
-#include "triangle2d.hpp"
+#include "geometry/point2d.hpp"
+#include "geometry/rect2d.hpp"
+#include "geometry/spline.hpp"
+#include "geometry/triangle2d.hpp"
-#include "std/function.hpp"
+#include <functional>
+#include <vector>
namespace m2
{
+using ClipTriangleByRectResultIt =
+ std::function<void(m2::PointD const &, m2::PointD const &, m2::PointD const &)>;
-using ClipTriangleByRectResultIt = function<void(m2::PointD const &, m2::PointD const &, m2::PointD const &)>;
+void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1, m2::PointD const & p2,
+ m2::PointD const & p3, ClipTriangleByRectResultIt const & resultIterator);
-void ClipTriangleByRect(m2::RectD const & rect, m2::PointD const & p1,
- m2::PointD const & p2, m2::PointD const & p3,
- ClipTriangleByRectResultIt const & resultIterator);
-
-vector<m2::SharedSpline> ClipSplineByRect(m2::RectD const & rect, m2::SharedSpline const & spline);
-
-} // namespace m2
+std::vector<m2::SharedSpline> ClipSplineByRect(m2::RectD const & rect,
+ m2::SharedSpline const & spline);
+} // namespace m2
diff --git a/geometry/covering.hpp b/geometry/covering.hpp
index eff30cb0ba..5ffeb9a937 100644
--- a/geometry/covering.hpp
+++ b/geometry/covering.hpp
@@ -1,11 +1,14 @@
#pragma once
+
#include "geometry/covering_utils.hpp"
#include "geometry/point2d.hpp"
+
#include "base/assert.hpp"
#include "base/base.hpp"
#include "base/logging.hpp"
#include "base/set_operations.hpp"
#include "base/stl_add.hpp"
+
#include "std/algorithm.hpp"
#include "std/array.hpp"
#include "std/functional.hpp"
@@ -17,7 +20,6 @@
namespace covering
{
-
template <class CellIdT>
class Covering
{
@@ -27,10 +29,7 @@ public:
Covering() : m_Size(0) {}
- explicit Covering(CellId cell) : m_Size(1)
- {
- m_Covering[cell.Level()].push_back(cell);
- }
+ explicit Covering(CellId cell) : m_Size(1) { m_Covering[cell.Level()].push_back(cell); }
explicit Covering(vector<CellId> const & v)
{
@@ -78,7 +77,7 @@ public:
void OutputToVector(vector<CellId> & result) const
{
for (int level = 0; level < CellId::DEPTH_LEVELS; ++level)
- result.insert(result.end(), m_Covering[level].begin(), m_Covering[level].end());
+ result.insert(result.end(), m_Covering[level].begin(), m_Covering[level].end());
}
void OutputToVector(vector<int64_t> & result, int cellDepth) const
@@ -110,13 +109,12 @@ public:
}
private:
-
void SimplifyLevel(int level)
{
map<CellId, uint32_t, LessLevelOrder> parentCellCounts;
typedef typename vector<CellId>::const_iterator ConstIteartor;
for (ConstIteartor it = m_Covering[level].begin(); it != m_Covering[level].end(); ++it)
- ++parentCellCounts[it->Parent()];
+ ++parentCellCounts[it->Parent()];
vector<CellId> parentCells, childCells;
for (ConstIteartor it = m_Covering[level].begin(); it != m_Covering[level].end(); ++it)
@@ -147,7 +145,7 @@ private:
{
explicit CompareCellsAtLevel(int level) : m_Level(level) {}
- bool operator() (CellId id1, CellId id2) const
+ bool operator()(CellId id1, CellId id2) const
{
return m_Comp(id1.AncestorAtLevel(m_Level), id2.AncestorAtLevel(m_Level));
}
@@ -229,9 +227,8 @@ private:
if (i + 3 < a.size())
{
CellId const parent = a[i].Parent();
- if (parent == a[i+1].Parent() &&
- parent == a[i+2].Parent() &&
- parent == a[i+3].Parent())
+ if (parent == a[i + 1].Parent() && parent == a[i + 2].Parent() &&
+ parent == a[i + 3].Parent())
{
parents.push_back(parent);
i += 3;
@@ -280,10 +277,7 @@ private:
CoverTriangleImpl(info, cell.Child(child));
}
-
- array<vector<CellId>, CellId::DEPTH_LEVELS> m_Covering; // Covering by level.
+ array<vector<CellId>, CellId::DEPTH_LEVELS> m_Covering; // Covering by level.
size_t m_Size;
};
-
-
}
diff --git a/geometry/covering_utils.hpp b/geometry/covering_utils.hpp
index 9ca35d7969..6ef89e377f 100644
--- a/geometry/covering_utils.hpp
+++ b/geometry/covering_utils.hpp
@@ -1,7 +1,8 @@
#pragma once
-#include "point2d.hpp"
-#include "robust_orientation.hpp"
-#include "triangle2d.hpp"
+
+#include "geometry/point2d.hpp"
+#include "geometry/robust_orientation.hpp"
+#include "geometry/triangle2d.hpp"
#include "base/assert.hpp"
#include "base/base.hpp"
@@ -13,7 +14,6 @@
namespace covering
{
-
// Result of an intersection between object and cell.
enum CellObjectIntersection
{
@@ -25,19 +25,14 @@ enum CellObjectIntersection
};
template <class CellIdT>
-inline CellObjectIntersection IntersectCellWithLine(CellIdT const cell,
- m2::PointD const & a,
- m2::PointD const & b)
+CellObjectIntersection IntersectCellWithLine(CellIdT const cell, m2::PointD const & a,
+ m2::PointD const & b)
{
std::pair<uint32_t, uint32_t> const xy = cell.XY();
uint32_t const r = cell.Radius();
- m2::PointD const cellCorners[4] =
- {
- m2::PointD(xy.first - r, xy.second - r),
- m2::PointD(xy.first - r, xy.second + r),
- m2::PointD(xy.first + r, xy.second + r),
- m2::PointD(xy.first + r, xy.second - r)
- };
+ m2::PointD const cellCorners[4] = {
+ m2::PointD(xy.first - r, xy.second - r), m2::PointD(xy.first - r, xy.second + r),
+ m2::PointD(xy.first + r, xy.second + r), m2::PointD(xy.first + r, xy.second - r)};
for (int i = 0; i < 4; ++i)
if (m2::robust::SegmentsIntersect(a, b, cellCorners[i], cellCorners[i == 0 ? 3 : i - 1]))
return CELL_OBJECT_INTERSECT;
@@ -47,8 +42,8 @@ inline CellObjectIntersection IntersectCellWithLine(CellIdT const cell,
}
template <class CellIdT>
-CellObjectIntersection IntersectCellWithTriangle(
- CellIdT const cell, m2::PointD const & a, m2::PointD const & b, m2::PointD const & c)
+CellObjectIntersection IntersectCellWithTriangle(CellIdT const cell, m2::PointD const & a,
+ m2::PointD const & b, m2::PointD const & c)
{
CellObjectIntersection const i1 = IntersectCellWithLine(cell, a, b);
if (i1 == CELL_OBJECT_INTERSECT)
@@ -117,4 +112,4 @@ void CoverObject(IntersectF const & intersect, uint64_t cellPenaltyArea, CellIdC
}
}
-} // namespace covering
+} // namespace covering
diff --git a/geometry/distance.hpp b/geometry/distance.hpp
index 8cc6da0538..219a57b824 100644
--- a/geometry/distance.hpp
+++ b/geometry/distance.hpp
@@ -1,4 +1,5 @@
#pragma once
+
#include "geometry/point2d.hpp"
#include "base/math.hpp"
@@ -8,107 +9,92 @@
namespace m2
{
-
namespace impl
{
-
-template <typename PointT> class CalculatedSection
+template <typename Point>
+class CalculatedSection
{
-private:
- static_assert(std::numeric_limits<typename PointT::value_type>::is_signed,
- "We do not support unsigned points!!!");
-
public:
- void SetBounds(PointT const & p0, PointT const & p1)
+ void SetBounds(Point const & p0, Point const & p1)
{
- m_P0 = p0;
- m_P1 = p1;
- m_D = m_P1 - m_P0;
- m_D2 = Length(m_D);
+ m_p0 = p0;
+ m_p1 = p1;
+ m_d = m_p1 - m_p0;
+ m_length = sqrt(SquaredLength(m_d));
- if (my::AlmostEqualULPs(m_D2, 0.0))
+ if (my::AlmostEqualULPs(m_length, 0.0))
{
- // make zero vector - then all DotProduct will be equal to zero
- m_D = m2::PointD::Zero();
+ // Make zero vector and all DotProduct will be equal to zero.
+ m_d = m2::PointD::Zero();
}
else
{
- // normalize vector
- m_D = m_D / m_D2;
+ // Normalize vector.
+ m_d = m_d / m_length;
}
}
- inline double GetLength() const { return m_D2; }
- inline PointT const & P0() const { return m_P0; }
- inline PointT const & P1() const { return m_P1; }
+ double GetLength() const { return m_length; }
+ Point const & P0() const { return m_p0; }
+ Point const & P1() const { return m_p1; }
protected:
- template <class VectorT> static double SquaredLength(VectorT const & v)
+ template <typename Vector>
+ static double SquaredLength(Vector const & v)
{
return DotProduct(v, v);
}
- template <class VectorT> static double Length(VectorT const & v)
- {
- return sqrt(SquaredLength(v));
- }
- double Distance(PointD const & v) const
- {
- return CrossProduct(v, m_D);
- }
- PointT m_P0, m_P1;
- m2::PointD m_D;
- double m_D2;
-};
+ double Distance(PointD const & v) const { return CrossProduct(v, m_d); }
+
+ Point m_p0;
+ Point m_p1;
+ m2::PointD m_d;
+ double m_length;
+private:
+ static_assert(std::numeric_limits<typename Point::value_type>::is_signed,
+ "Unsigned points are not supported");
+};
} // namespace impl
-template <typename PointT> class DistanceToLineSquare : public impl::CalculatedSection<PointT>
+template <typename Point>
+class DistanceToLineSquare : public impl::CalculatedSection<Point>
{
public:
- double operator() (PointT const & Y) const
+ double operator()(Point const & p) const
{
- PointT const diff = Y - this->m_P0;
- m2::PointD const YmP0(diff);
- double const t = DotProduct(this->m_D, YmP0);
+ Point const diff = p - this->m_p0;
+ m2::PointD const diffD(diff);
+ double const t = DotProduct(this->m_d, diffD);
if (t <= 0)
- {
- // Y is closest to P0.
- return this->SquaredLength(YmP0);
- }
- if (t >= this->m_D2)
- {
- // Y is closest to P1.
- return this->SquaredLength(Y - this->m_P1);
- }
+ return this->SquaredLength(diffD);
+
+ if (t >= this->m_length)
+ return this->SquaredLength(p - this->m_p1);
- // Closest point is interior to segment.
- return std::pow(this->Distance(YmP0), 2);
+ // Closest point is between |m_p0| and |m_p1|.
+ return std::pow(this->Distance(diffD), 2.0);
}
};
-template <typename PointT> class ProjectionToSection : public impl::CalculatedSection<PointT>
+template <typename Point>
+class ProjectionToSection : public impl::CalculatedSection<Point>
{
public:
- m2::PointD operator() (PointT const & Y) const
+ m2::PointD operator()(Point const & p) const
{
- m2::PointD const YmP0 = Y - this->m_P0;
- double const t = DotProduct(this->m_D, YmP0);
+ m2::PointD const diffD = p - this->m_p0;
+ double const t = DotProduct(this->m_d, diffD);
if (t <= 0)
- {
- // Y is closest to P0.
- return this->m_P0;
- }
- if (t >= this->m_D2)
- {
- // Y is closest to P1.
- return this->m_P1;
- }
+ return this->m_p0;
+
+ if (t >= this->m_length)
+ return this->m_p1;
- return this->m_D*t + this->m_P0;
+ return this->m_p0 + this->m_d * t;
}
};
-
-}
+} // namespace m2
diff --git a/geometry/distance_on_sphere.cpp b/geometry/distance_on_sphere.cpp
index 3365b9a69d..7aadd2b876 100644
--- a/geometry/distance_on_sphere.cpp
+++ b/geometry/distance_on_sphere.cpp
@@ -1,8 +1,14 @@
#include "geometry/distance_on_sphere.hpp"
+
#include "base/math.hpp"
-#include "std/algorithm.hpp"
-double ms::DistanceOnSphere(double lat1Deg, double lon1Deg, double lat2Deg, double lon2Deg)
+#include <algorithm>
+
+using namespace std;
+
+namespace ms
+{
+double DistanceOnSphere(double lat1Deg, double lon1Deg, double lat2Deg, double lon2Deg)
{
double const lat1 = my::DegToRad(lat1Deg);
double const lat2 = my::DegToRad(lat2Deg);
@@ -12,9 +18,12 @@ double ms::DistanceOnSphere(double lat1Deg, double lon1Deg, double lat2Deg, doub
return 2.0 * atan2(sqrt(y), sqrt(max(0.0, 1.0 - y)));
}
-double ms::AreaOnSphere(ms::LatLon const & ll1, ms::LatLon const & ll2, ms::LatLon const & ll3)
+double AreaOnSphere(ms::LatLon const & ll1, ms::LatLon const & ll2, ms::LatLon const & ll3)
{
// Todo: proper area on sphere (not needed for now)
double const avgLat = my::DegToRad((ll1.lat + ll2.lat + ll3.lat) / 3);
- return cos(avgLat) * 0.5 * fabs((ll2.lon - ll1.lon)*(ll3.lat - ll1.lat) - (ll3.lon - ll1.lon)*(ll2.lat - ll1.lat));
+ return cos(avgLat) * 0.5 *
+ fabs((ll2.lon - ll1.lon) * (ll3.lat - ll1.lat) -
+ (ll3.lon - ll1.lon) * (ll2.lat - ll1.lat));
}
+} // namespace ms
diff --git a/geometry/distance_on_sphere.hpp b/geometry/distance_on_sphere.hpp
index efba329e3d..e8c6181e2f 100644
--- a/geometry/distance_on_sphere.hpp
+++ b/geometry/distance_on_sphere.hpp
@@ -1,11 +1,12 @@
#pragma once
-#include "base/base.hpp"
+
#include "geometry/latlon.hpp"
+#include "base/base.hpp"
+
// namespace ms - "math on sphere", similar to the namespaces m2 and mn.
namespace ms
{
-
// Earth radius in meters.
inline double EarthRadiusMeters() { return 6378000; }
// Length of one degree square at the equator in meters.
@@ -32,7 +33,7 @@ inline double DistanceOnEarth(LatLon const & ll1, LatLon const & ll2)
inline double AreaOnEarth(LatLon const & ll1, LatLon const & ll2, LatLon const & ll3)
{
- return OneDegreeEquatorLengthMeters() * OneDegreeEquatorLengthMeters() * AreaOnSphere(ll1, ll2, ll3);
+ return OneDegreeEquatorLengthMeters() * OneDegreeEquatorLengthMeters() *
+ AreaOnSphere(ll1, ll2, ll3);
}
-
} // namespace ms
diff --git a/geometry/geometry_tests/point_test.cpp b/geometry/geometry_tests/point_test.cpp
index 0c15ef621b..3152f923a9 100644
--- a/geometry/geometry_tests/point_test.cpp
+++ b/geometry/geometry_tests/point_test.cpp
@@ -4,6 +4,9 @@
#include "geometry/point2d.hpp"
#include "geometry/triangle2d.hpp"
+#include <array>
+
+using namespace std;
UNIT_TEST(Point_Rotate)
{
@@ -78,9 +81,19 @@ UNIT_TEST(GetArrowPoints)
UNIT_TEST(PointAtSegment)
{
- TEST(m2::AlmostEqualULPs(m2::PointAtSegment(m2::PointF(0, 0), m2::PointF(1, 0), 0.5f), m2::PointF(0.5f, 0.f)), ());
- TEST(m2::AlmostEqualULPs(m2::PointAtSegment(m2::PointF(0, 0), m2::PointF(0, 1), 0.3f), m2::PointF(0.f, 0.3f)), ());
- TEST(m2::AlmostEqualULPs(m2::PointAtSegment(m2::PointD(0., 0.), m2::PointD(30., 40.), 5.), m2::PointD(3., 4.)), ());
- TEST(m2::AlmostEqualULPs(m2::PointAtSegment(m2::PointF(-3, -4), m2::PointF(-30, -40), 5.f), m2::PointF(-6.f, -8.f)), ());
- TEST(m2::AlmostEqualULPs(m2::PointAtSegment(m2::PointD(14., -48.), m2::PointD(70., -240.), 25.), m2::PointD(21., -72.)), ());
+ TEST(m2::AlmostEqualULPs(m2::PointAtSegment(m2::PointF(0, 0), m2::PointF(1, 0), 0.5f),
+ m2::PointF(0.5f, 0.f)),
+ ());
+ TEST(m2::AlmostEqualULPs(m2::PointAtSegment(m2::PointF(0, 0), m2::PointF(0, 1), 0.3f),
+ m2::PointF(0.f, 0.3f)),
+ ());
+ TEST(m2::AlmostEqualULPs(m2::PointAtSegment(m2::PointD(0., 0.), m2::PointD(30., 40.), 5.),
+ m2::PointD(3., 4.)),
+ ());
+ TEST(m2::AlmostEqualULPs(m2::PointAtSegment(m2::PointF(-3, -4), m2::PointF(-30, -40), 5.f),
+ m2::PointF(-6.f, -8.f)),
+ ());
+ TEST(m2::AlmostEqualULPs(m2::PointAtSegment(m2::PointD(14., -48.), m2::PointD(70., -240.), 25.),
+ m2::PointD(21., -72.)),
+ ());
}
diff --git a/geometry/geometry_tests/polygon_test.cpp b/geometry/geometry_tests/polygon_test.cpp
index 3ebb69a686..0dfa606382 100644
--- a/geometry/geometry_tests/polygon_test.cpp
+++ b/geometry/geometry_tests/polygon_test.cpp
@@ -6,47 +6,51 @@
#include "base/macros.hpp"
-#include "std/algorithm.hpp"
+#include <algorithm>
+using namespace std;
-namespace { typedef m2::PointD P; }
+namespace
+{
+using P = m2::PointD;
+} // namespace
using namespace m2::robust;
UNIT_TEST(IsSegmentInCone)
{
- TEST(IsSegmentInCone(P(0,0), P( 0, 3), P(-1,-1), P(1,-1)), ());
- TEST(IsSegmentInCone(P(0,0), P( 2, 3), P(-1,-1), P(1,-1)), ());
- TEST(IsSegmentInCone(P(0,0), P(-3, 3), P(-1,-1), P(1,-1)), ());
- TEST(IsSegmentInCone(P(0,0), P(-3, 0), P(-1,-1), P(1,-1)), ());
- TEST(IsSegmentInCone(P(0,0), P( 3, 0), P(-1,-1), P(1,-1)), ());
- TEST(!IsSegmentInCone(P(0,0), P( 0,-1), P(-1,-1), P(1,-1)), ());
- TEST(!IsSegmentInCone(P(0,0), P( 1,-3), P(-1,-1), P(1,-1)), ());
- TEST(!IsSegmentInCone(P(0,0), P(-1,-3), P(-1,-1), P(1,-1)), ());
-
- TEST(IsSegmentInCone(P(0,0), P( 0, 3), P(-1,1), P(1,1)), ());
- TEST(IsSegmentInCone(P(0,0), P( 2, 3), P(-1,1), P(1,1)), ());
- TEST(!IsSegmentInCone(P(0,0), P(-3, 3), P(-1,1), P(1,1)), ());
- TEST(!IsSegmentInCone(P(0,0), P(-3, 0), P(-1,1), P(1,1)), ());
- TEST(!IsSegmentInCone(P(0,0), P( 3, 0), P(-1,1), P(1,1)), ());
- TEST(!IsSegmentInCone(P(0,0), P( 0,-1), P(-1,1), P(1,1)), ());
- TEST(!IsSegmentInCone(P(0,0), P( 1,-3), P(-1,1), P(1,1)), ());
- TEST(!IsSegmentInCone(P(0,0), P(-1,-3), P(-1,1), P(1,1)), ());
+ TEST(IsSegmentInCone(P(0, 0), P(0, 3), P(-1, -1), P(1, -1)), ());
+ TEST(IsSegmentInCone(P(0, 0), P(2, 3), P(-1, -1), P(1, -1)), ());
+ TEST(IsSegmentInCone(P(0, 0), P(-3, 3), P(-1, -1), P(1, -1)), ());
+ TEST(IsSegmentInCone(P(0, 0), P(-3, 0), P(-1, -1), P(1, -1)), ());
+ TEST(IsSegmentInCone(P(0, 0), P(3, 0), P(-1, -1), P(1, -1)), ());
+ TEST(!IsSegmentInCone(P(0, 0), P(0, -1), P(-1, -1), P(1, -1)), ());
+ TEST(!IsSegmentInCone(P(0, 0), P(1, -3), P(-1, -1), P(1, -1)), ());
+ TEST(!IsSegmentInCone(P(0, 0), P(-1, -3), P(-1, -1), P(1, -1)), ());
+
+ TEST(IsSegmentInCone(P(0, 0), P(0, 3), P(-1, 1), P(1, 1)), ());
+ TEST(IsSegmentInCone(P(0, 0), P(2, 3), P(-1, 1), P(1, 1)), ());
+ TEST(!IsSegmentInCone(P(0, 0), P(-3, 3), P(-1, 1), P(1, 1)), ());
+ TEST(!IsSegmentInCone(P(0, 0), P(-3, 0), P(-1, 1), P(1, 1)), ());
+ TEST(!IsSegmentInCone(P(0, 0), P(3, 0), P(-1, 1), P(1, 1)), ());
+ TEST(!IsSegmentInCone(P(0, 0), P(0, -1), P(-1, 1), P(1, 1)), ());
+ TEST(!IsSegmentInCone(P(0, 0), P(1, -3), P(-1, 1), P(1, 1)), ());
+ TEST(!IsSegmentInCone(P(0, 0), P(-1, -3), P(-1, 1), P(1, 1)), ());
}
namespace
{
- template <typename IterT>
- void TestDiagonalVisible(IterT beg, IterT end, IterT i0, IterT i1, bool res)
- {
- TEST_EQUAL ( IsDiagonalVisible(beg, end, i0, i1), res, () );
- TEST_EQUAL ( IsDiagonalVisible(beg, end, i1, i0), res, () );
- }
+template <typename IterT>
+void TestDiagonalVisible(IterT beg, IterT end, IterT i0, IterT i1, bool res)
+{
+ TEST_EQUAL(IsDiagonalVisible(beg, end, i0, i1), res, ());
+ TEST_EQUAL(IsDiagonalVisible(beg, end, i1, i0), res, ());
+}
}
UNIT_TEST(IsDiagonalVisible)
{
- P poly [] = { P(0, 0), P(3, 0), P(3, 2), P(2, 2), P(2, 1), P(0, 1) };
+ P poly[] = {P(0, 0), P(3, 0), P(3, 2), P(2, 2), P(2, 1), P(0, 1)};
P const * b = poly;
P const * e = poly + ARRAY_SIZE(poly);
@@ -63,59 +67,53 @@ UNIT_TEST(IsDiagonalVisible)
namespace
{
- void TestFindStrip(P const * beg, size_t n)
- {
- size_t const i = FindSingleStrip(n, IsDiagonalVisibleFunctor<P const *>(beg, beg + n));
- TEST_LESS ( i, n, () );
+void TestFindStrip(P const * beg, size_t n)
+{
+ size_t const i = FindSingleStrip(n, IsDiagonalVisibleFunctor<P const *>(beg, beg + n));
+ TEST_LESS(i, n, ());
- vector<size_t> test;
- MakeSingleStripFromIndex(i, n, MakeBackInsertFunctor(test));
+ vector<size_t> test;
+ MakeSingleStripFromIndex(i, n, MakeBackInsertFunctor(test));
- sort(test.begin(), test.end());
- unique(test.begin(), test.end());
+ sort(test.begin(), test.end());
+ unique(test.begin(), test.end());
- TEST_EQUAL ( test.size(), n, () );
- }
+ TEST_EQUAL(test.size(), n, ());
+}
- void TestFindStripMulti(P const * beg, size_t n)
- {
- for (size_t i = 3; i <= n; ++i)
- TestFindStrip(beg, i);
- }
+void TestFindStripMulti(P const * beg, size_t n)
+{
+ for (size_t i = 3; i <= n; ++i)
+ TestFindStrip(beg, i);
+}
}
UNIT_TEST(FindSingleStrip)
{
{
- P poly[] = { P(0, 0), P(3, 0), P(3, 2), P(2, 2), P(2, 1), P(0, 1) };
+ P poly[] = {P(0, 0), P(3, 0), P(3, 2), P(2, 2), P(2, 1), P(0, 1)};
TestFindStripMulti(poly, ARRAY_SIZE(poly));
}
{
- P poly[] = { P(0, 0), P(2, 0), P(2, -1), P(3, -1), P(3, 2), P(2, 2), P(2, 1), P(0, 1) };
+ P poly[] = {P(0, 0), P(2, 0), P(2, -1), P(3, -1), P(3, 2), P(2, 2), P(2, 1), P(0, 1)};
size_t const n = ARRAY_SIZE(poly);
- TEST_EQUAL ( FindSingleStrip(n, IsDiagonalVisibleFunctor<P const *>(poly, poly + n)), n, () );
+ TEST_EQUAL(FindSingleStrip(n, IsDiagonalVisibleFunctor<P const *>(poly, poly + n)), n, ());
}
{
// Minsk, Bobryiskaya str., 7
- P poly[] = {
- P(53.8926922, 27.5460021),
- P(53.8926539, 27.5461821),
- P(53.8926164, 27.5461591),
- P(53.8925455, 27.5464921),
- P(53.8925817, 27.5465143),
- P(53.8925441, 27.5466909),
- P(53.8923762, 27.5465881),
- P(53.8925229, 27.5458984)
- };
+ P poly[] = {P(53.8926922, 27.5460021), P(53.8926539, 27.5461821), P(53.8926164, 27.5461591),
+ P(53.8925455, 27.5464921), P(53.8925817, 27.5465143), P(53.8925441, 27.5466909),
+ P(53.8923762, 27.5465881), P(53.8925229, 27.5458984)};
TestFindStrip(poly, ARRAY_SIZE(poly));
}
}
namespace
{
-template <typename IterT> void TestPolygonCCW(IterT beg, IterT end)
+template <typename IterT>
+void TestPolygonCCW(IterT beg, IterT end)
{
TEST_EQUAL(m2::robust::CheckPolygonSelfIntersections(beg, end), false, ());
@@ -124,7 +122,8 @@ template <typename IterT> void TestPolygonCCW(IterT beg, IterT end)
TEST(!IsPolygonCCW(ReverseIterT(end), ReverseIterT(beg)), ());
}
-template <typename IterT> void TestPolygonOrReverseCCW(IterT beg, IterT end)
+template <typename IterT>
+void TestPolygonOrReverseCCW(IterT beg, IterT end)
{
TEST_EQUAL(m2::robust::CheckPolygonSelfIntersections(beg, end), false, ());
@@ -137,24 +136,24 @@ template <typename IterT> void TestPolygonOrReverseCCW(IterT beg, IterT end)
UNIT_TEST(IsPolygonCCW_Smoke)
{
- P arr1[] = { P(1, 1), P(2, 0), P(3, 2) };
+ P arr1[] = {P(1, 1), P(2, 0), P(3, 2)};
TestPolygonCCW(arr1, arr1 + ARRAY_SIZE(arr1));
- P arr2[] = { P(0, 0), P(1, 0), P(0, 1) };
+ P arr2[] = {P(0, 0), P(1, 0), P(0, 1)};
TestPolygonCCW(arr2, arr2 + ARRAY_SIZE(arr2));
- P arr3[] = { P(0, 1), P(1, 1), P(1, 0), P(2, 0), P(2, 1), P(1, 1), P(1, 2), P(0, 2) };
+ P arr3[] = {P(0, 1), P(1, 1), P(1, 0), P(2, 0), P(2, 1), P(1, 1), P(1, 2), P(0, 2)};
TestPolygonCCW(arr3, arr3 + ARRAY_SIZE(arr3));
}
UNIT_TEST(IsPolygonCCW_DataSet)
{
- P arr[] = { P(27.3018836975098, 61.7740631103516), P(27.2981071472168, 61.7816162109375),
- P(27.2962188720703, 61.7831611633301), P(27.293815612793, 61.7814445495605),
- P(27.2926139831543, 61.783332824707), P(27.2919273376465, 61.787109375),
- P(27.2948455810547, 61.7865943908691), P(27.2958755493164, 61.7883110046387),
- P(27.3001670837402, 61.779899597168), P(27.3036003112793, 61.7771530151367),
- P(27.3015403747559, 61.7747497558594) };
+ P arr[] = {P(27.3018836975098, 61.7740631103516), P(27.2981071472168, 61.7816162109375),
+ P(27.2962188720703, 61.7831611633301), P(27.293815612793, 61.7814445495605),
+ P(27.2926139831543, 61.783332824707), P(27.2919273376465, 61.787109375),
+ P(27.2948455810547, 61.7865943908691), P(27.2958755493164, 61.7883110046387),
+ P(27.3001670837402, 61.779899597168), P(27.3036003112793, 61.7771530151367),
+ P(27.3015403747559, 61.7747497558594)};
TestPolygonOrReverseCCW(arr, arr + ARRAY_SIZE(arr));
}
@@ -162,16 +161,16 @@ UNIT_TEST(IsPolygonCCW_DataSet)
UNIT_TEST(PolygonArea_Smoke)
{
{
- P arr[] = { P (-1, 0), P(0, 1), P(1, -1) };
+ P arr[] = {P(-1, 0), P(0, 1), P(1, -1)};
TEST_ALMOST_EQUAL_ULPS(m2::GetTriangleArea(arr[0], arr[1], arr[2]),
GetPolygonArea(arr, arr + ARRAY_SIZE(arr)), ());
}
{
- P arr[] = { P (-5, -7), P(-3.5, 10), P(7.2, 5), P(14, -6.4) };
- TEST_ALMOST_EQUAL_ULPS(m2::GetTriangleArea(arr[0], arr[1], arr[2]) +
- m2::GetTriangleArea(arr[2], arr[3], arr[0]),
- GetPolygonArea(arr, arr + ARRAY_SIZE(arr)), ());
+ P arr[] = {P(-5, -7), P(-3.5, 10), P(7.2, 5), P(14, -6.4)};
+ TEST_ALMOST_EQUAL_ULPS(
+ m2::GetTriangleArea(arr[0], arr[1], arr[2]) + m2::GetTriangleArea(arr[2], arr[3], arr[0]),
+ GetPolygonArea(arr, arr + ARRAY_SIZE(arr)), ());
}
}
@@ -205,10 +204,10 @@ UNIT_TEST(IsPolygonCCW_DataSet3)
/*
UNIT_TEST(IsPolygonCCW_DataSet4)
{
- P arr[] = { P(37.368060441099174795, 67.293103344080122952), P(37.368017525754879671, 67.292797572252140981),
- P(37.367990703664702323, 67.292969568905391498), P(37.368060441099174795, 67.293103344080122952),
- P(37.368017525754879671, 67.292797572252140981), P(37.368097992025411713, 67.292830094036474975),
- P(37.368216009222180674, 67.292969568905391498) };
+ P arr[] = { P(37.368060441099174795, 67.293103344080122952),
+P(37.368017525754879671, 67.292797572252140981), P(37.367990703664702323, 67.292969568905391498),
+P(37.368060441099174795, 67.293103344080122952), P(37.368017525754879671, 67.292797572252140981),
+P(37.368097992025411713, 67.292830094036474975), P(37.368216009222180674, 67.292969568905391498) };
TestPolygonOrReverseCCW(arr, arr + ARRAY_SIZE(arr));
}
*/
diff --git a/geometry/geometry_tests/tree_test.cpp b/geometry/geometry_tests/tree_test.cpp
index 31b4844ba5..1495663049 100644
--- a/geometry/geometry_tests/tree_test.cpp
+++ b/geometry/geometry_tests/tree_test.cpp
@@ -2,27 +2,39 @@
#include "geometry/tree4d.hpp"
+#include <functional>
+
+using namespace std;
namespace
{
- typedef m2::RectD R;
+using R = m2::RectD;
+
+struct traits_t
+{
+ m2::RectD LimitRect(m2::RectD const & r) const { return r; }
+};
+
+using Tree = m4::Tree<R, traits_t>;
- struct traits_t { m2::RectD LimitRect(m2::RectD const & r) const { return r; }};
- typedef m4::Tree<R, traits_t> TTree;
+template <typename T>
+bool RTrue(T const &, T const &)
+{
+ return true;
+}
- template <class T> bool RTrue(T const &, T const &) { return true; }
- template <class T> bool RFalse(T const &, T const &) { return false; }
+template <typename T>
+bool RFalse(T const &, T const &)
+{
+ return false;
}
+} // namespace
UNIT_TEST(Tree4D_Smoke)
{
- TTree theTree;
+ Tree theTree;
- R arr[] = {
- R(0, 0, 1, 1),
- R(1, 1, 2, 2),
- R(2, 2, 3, 3)
- };
+ R arr[] = {R(0, 0, 1, 1), R(1, 1, 2, 2), R(2, 2, 3, 3)};
for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
theTree.ReplaceAllInRect(arr[i], &RTrue<R>);
@@ -52,31 +64,23 @@ UNIT_TEST(Tree4D_Smoke)
UNIT_TEST(Tree4D_ReplaceAllInRect)
{
- TTree theTree;
-
- R arr[] = {
- R(8, 13, 554, 32), R(555, 13, 700, 32),
- R(8, 33, 554, 52), R(555, 33, 700, 52),
- R(8, 54, 554, 73), R(555, 54, 700, 73),
- R(8, 76, 554, 95), R(555, 76, 700, 95)
- };
-
- R arr1[] = {
- R(3, 23, 257, 42), R(600, 23, 800, 42),
- R(3, 43, 257, 62), R(600, 43, 800, 62),
- R(3, 65, 257, 84), R(600, 65, 800, 84),
- R(3, 87, 257, 106), R(600, 87, 800, 106)
- };
+ Tree theTree;
+
+ R arr[] = {R(8, 13, 554, 32), R(555, 13, 700, 32), R(8, 33, 554, 52), R(555, 33, 700, 52),
+ R(8, 54, 554, 73), R(555, 54, 700, 73), R(8, 76, 554, 95), R(555, 76, 700, 95)};
+
+ R arr1[] = {R(3, 23, 257, 42), R(600, 23, 800, 42), R(3, 43, 257, 62), R(600, 43, 800, 62),
+ R(3, 65, 257, 84), R(600, 65, 800, 84), R(3, 87, 257, 106), R(600, 87, 800, 106)};
for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
{
size_t const count = theTree.GetSize();
theTree.ReplaceAllInRect(arr[i], &RFalse<R>);
- TEST_EQUAL ( theTree.GetSize(), count + 1, () );
+ TEST_EQUAL(theTree.GetSize(), count + 1, ());
theTree.ReplaceAllInRect(arr1[i], &RFalse<R>);
- TEST_EQUAL ( theTree.GetSize(), count + 1, () );
+ TEST_EQUAL(theTree.GetSize(), count + 1, ());
}
vector<R> test;
@@ -87,28 +91,25 @@ UNIT_TEST(Tree4D_ReplaceAllInRect)
TEST_EQUAL(test[i], arr[i], ());
}
-namespace
+namespace
{
- void CheckInRect(R const * arr, size_t count, R const & searchR, size_t expected)
- {
- TTree theTree;
+void CheckInRect(R const * arr, size_t count, R const & searchR, size_t expected)
+{
+ Tree theTree;
- for (size_t i = 0; i < count; ++i)
- theTree.Add(arr[i], arr[i]);
+ for (size_t i = 0; i < count; ++i)
+ theTree.Add(arr[i], arr[i]);
- vector<R> test;
- theTree.ForEachInRect(searchR, MakeBackInsertFunctor(test));
+ vector<R> test;
+ theTree.ForEachInRect(searchR, MakeBackInsertFunctor(test));
- TEST_EQUAL(test.size(), expected, ());
- }
+ TEST_EQUAL(test.size(), expected, ());
+}
}
UNIT_TEST(Tree4D_ForEachInRect)
{
- R arr[] =
- {
- R(0, 0, 1, 1), R(5, 5, 10, 10), R(-1, -1, 0, 0), R(-10, -10, -5, -5)
- };
+ R arr[] = {R(0, 0, 1, 1), R(5, 5, 10, 10), R(-1, -1, 0, 0), R(-10, -10, -5, -5)};
CheckInRect(arr, ARRAY_SIZE(arr), R(1, 1, 5, 5), 0);
CheckInRect(arr, ARRAY_SIZE(arr), R(-5, -5, -1, -1), 0);
CheckInRect(arr, ARRAY_SIZE(arr), R(3, 3, 3, 3), 0);
@@ -125,7 +126,6 @@ UNIT_TEST(Tree4D_ForEachInRect)
namespace
{
-
struct TestObj : public m2::RectD
{
int m_id;
@@ -137,7 +137,6 @@ struct TestObj : public m2::RectD
bool operator==(TestObj const & r) const { return m_id == r.m_id; }
};
-
}
UNIT_TEST(Tree4D_ReplaceEqual)
@@ -145,11 +144,7 @@ UNIT_TEST(Tree4D_ReplaceEqual)
typedef TestObj T;
m4::Tree<T, traits_t> theTree;
- T arr[] = {
- T(0, 0, 1, 1, 1),
- T(1, 1, 2, 2, 2),
- T(2, 2, 3, 3, 3)
- };
+ T arr[] = {T(0, 0, 1, 1, 1), T(1, 1, 2, 2, 2), T(2, 2, 3, 3, 3)};
// 1.
for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
diff --git a/geometry/latlon.cpp b/geometry/latlon.cpp
index 636a91c054..fa0521a2c3 100644
--- a/geometry/latlon.cpp
+++ b/geometry/latlon.cpp
@@ -1,6 +1,8 @@
#include "latlon.hpp"
-#include "std/sstream.hpp"
+#include <sstream>
+
+using namespace std;
namespace ms
{
@@ -18,10 +20,7 @@ string DebugPrint(LatLon const & t)
return out.str();
}
-bool LatLon::operator == (ms::LatLon const & p) const
-{
- return lat == p.lat && lon == p.lon;
-}
+bool LatLon::operator==(ms::LatLon const & p) const { return lat == p.lat && lon == p.lon; }
bool LatLon::EqualDxDy(LatLon const & p, double eps) const
{
diff --git a/geometry/latlon.hpp b/geometry/latlon.hpp
index 3204eec693..ceff8cbe31 100644
--- a/geometry/latlon.hpp
+++ b/geometry/latlon.hpp
@@ -2,11 +2,10 @@
#include "base/math.hpp"
-#include "std/string.hpp"
+#include <string>
namespace ms
{
-
/// \brief Class for representing WGS point.
class LatLon
{
@@ -24,19 +23,15 @@ public:
static LatLon Zero() { return LatLon(0., 0.); }
- bool operator == (ms::LatLon const & p) const;
+ bool operator==(ms::LatLon const & p) const;
bool EqualDxDy(LatLon const & p, double eps) const;
struct Hash
{
- size_t operator()(ms::LatLon const & p) const
- {
- return my::Hash(p.lat, p.lon);
- }
+ size_t operator()(ms::LatLon const & p) const { return my::Hash(p.lat, p.lon); }
};
};
-string DebugPrint(LatLon const & t);
-
+std::string DebugPrint(LatLon const & t);
} // namespace ms
diff --git a/geometry/line2d.hpp b/geometry/line2d.hpp
index cfce8d0858..fc7b544e1b 100644
--- a/geometry/line2d.hpp
+++ b/geometry/line2d.hpp
@@ -15,17 +15,12 @@ struct Line2D
explicit Line2D(Segment2D const & segment) : m_point(segment.m_u), m_direction(segment.Dir()) {}
- Line2D(PointD const & point, PointD const & direction)
- : m_point(point), m_direction(direction)
- {
- }
+ Line2D(PointD const & point, PointD const & direction) : m_point(point), m_direction(direction) {}
PointD m_point;
PointD m_direction;
};
-std::string DebugPrint(Line2D const & line);
-
struct LineIntersector
{
struct Result
@@ -47,6 +42,7 @@ struct LineIntersector
static Result Intersect(Line2D const & lhs, Line2D const & rhs, double eps);
};
+std::string DebugPrint(Line2D const & line);
std::string DebugPrint(LineIntersector::Result::Type type);
std::string DebugPrint(LineIntersector::Result const & result);
} // namespace m2
diff --git a/geometry/mercator.cpp b/geometry/mercator.cpp
index df93104f85..9f46e5585a 100644
--- a/geometry/mercator.cpp
+++ b/geometry/mercator.cpp
@@ -2,24 +2,28 @@
#include "geometry/distance_on_sphere.hpp"
+#include <algorithm>
+#include <cmath>
+
+using namespace std;
+
double MercatorBounds::minX = -180;
double MercatorBounds::maxX = 180;
double MercatorBounds::minY = -180;
double MercatorBounds::maxY = 180;
-m2::RectD MercatorBounds::MetresToXY(double lon, double lat,
- double lonMetresR, double latMetresR)
+m2::RectD MercatorBounds::MetresToXY(double lon, double lat, double lonMetresR, double latMetresR)
{
double const latDegreeOffset = latMetresR * degreeInMetres;
double const minLat = max(-90.0, lat - latDegreeOffset);
- double const maxLat = min( 90.0, lat + latDegreeOffset);
+ double const maxLat = min(90.0, lat + latDegreeOffset);
double const cosL = max(cos(my::DegToRad(max(fabs(minLat), fabs(maxLat)))), 0.00001);
- ASSERT_GREATER ( cosL, 0.0, () );
+ ASSERT_GREATER(cosL, 0.0, ());
double const lonDegreeOffset = lonMetresR * degreeInMetres / cosL;
double const minLon = max(-180.0, lon - lonDegreeOffset);
- double const maxLon = min( 180.0, lon + lonDegreeOffset);
+ double const maxLon = min(180.0, lon + lonDegreeOffset);
return m2::RectD(FromLatLon(minLat, minLon), FromLatLon(maxLat, maxLon));
}
@@ -33,7 +37,7 @@ m2::PointD MercatorBounds::GetSmPoint(m2::PointD const & pt, double lonMetresR,
double const newLat = min(90.0, max(-90.0, lat + latDegreeOffset));
double const cosL = max(cos(my::DegToRad(newLat)), 0.00001);
- ASSERT_GREATER ( cosL, 0.0, () );
+ ASSERT_GREATER(cosL, 0.0, ());
double const lonDegreeOffset = lonMetresR * degreeInMetres / cosL;
double const newLon = min(180.0, max(-180.0, lon + lonDegreeOffset));
@@ -46,7 +50,8 @@ double MercatorBounds::DistanceOnEarth(m2::PointD const & p1, m2::PointD const &
return ms::DistanceOnEarth(ToLatLon(p1), ToLatLon(p2));
}
-double MercatorBounds::AreaOnEarth(m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3)
+double MercatorBounds::AreaOnEarth(m2::PointD const & p1, m2::PointD const & p2,
+ m2::PointD const & p3)
{
return ms::AreaOnEarth(ToLatLon(p1), ToLatLon(p2), ToLatLon(p3));
}
diff --git a/geometry/mercator.hpp b/geometry/mercator.hpp
index acabe3123a..cee5cff05f 100644
--- a/geometry/mercator.hpp
+++ b/geometry/mercator.hpp
@@ -1,4 +1,5 @@
#pragma once
+
#include "geometry/latlon.hpp"
#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"
@@ -12,73 +13,45 @@ struct MercatorBounds
static double minY;
static double maxY;
- inline static m2::RectD FullRect() { return m2::RectD(minX, minY, maxX, maxY); }
+ static m2::RectD FullRect() { return m2::RectD(minX, minY, maxX, maxY); }
- inline static bool ValidLon(double d)
- {
- return my::between_s(-180.0, 180.0, d);
- }
- inline static bool ValidLat(double d)
- {
- return my::between_s(-90.0, 90.0, d);
- }
+ static bool ValidLon(double d) { return my::between_s(-180.0, 180.0, d); }
+ static bool ValidLat(double d) { return my::between_s(-90.0, 90.0, d); }
- inline static bool ValidX(double d)
- {
- return my::between_s(minX, maxX, d);
- }
- inline static bool ValidY(double d)
- {
- return my::between_s(minY, maxY, d);
- }
+ static bool ValidX(double d) { return my::between_s(minX, maxX, d); }
+ static bool ValidY(double d) { return my::between_s(minY, maxY, d); }
- inline static double ClampX(double d)
- {
- return my::clamp(d, minX, maxX);
- }
- inline static double ClampY(double d)
- {
- return my::clamp(d, minY, maxY);
- }
+ static double ClampX(double d) { return my::clamp(d, minX, maxX); }
+ static double ClampY(double d) { return my::clamp(d, minY, maxY); }
- inline static double YToLat(double y)
- {
- return my::RadToDeg(2.0 * atan(tanh(0.5 * my::DegToRad(y))));
- }
+ static double YToLat(double y) { return my::RadToDeg(2.0 * atan(tanh(0.5 * my::DegToRad(y)))); }
- inline static double LatToY(double lat)
+ static double LatToY(double lat)
{
double const sinx = sin(my::DegToRad(my::clamp(lat, -86.0, 86.0)));
double const res = my::RadToDeg(0.5 * log((1.0 + sinx) / (1.0 - sinx)));
return ClampY(res);
}
- inline static double XToLon(double x)
- {
- return x;
- }
+ static double XToLon(double x) { return x; }
- inline static double LonToX(double lon)
- {
- return lon;
- }
+ static double LonToX(double lon) { return lon; }
static double constexpr degreeInMetres = 360.0 / 40008245;
/// @name Get rect for center point (lon, lat) and dimensions in metres.
//@{
/// @return mercator rect.
- static m2::RectD MetresToXY(double lon, double lat,
- double lonMetresR, double latMetresR);
+ static m2::RectD MetresToXY(double lon, double lat, double lonMetresR, double latMetresR);
- inline static m2::RectD MetresToXY(double lon, double lat, double metresR)
+ static m2::RectD MetresToXY(double lon, double lat, double metresR)
{
return MetresToXY(lon, lat, metresR, metresR);
}
//@}
- inline static m2::RectD RectByCenterXYAndSizeInMeters(double centerX, double centerY,
- double sizeX, double sizeY)
+ static m2::RectD RectByCenterXYAndSizeInMeters(double centerX, double centerY, double sizeX,
+ double sizeY)
{
ASSERT_GREATER_OR_EQUAL(sizeX, 0, ());
ASSERT_GREATER_OR_EQUAL(sizeY, 0, ());
@@ -86,7 +59,7 @@ struct MercatorBounds
return MetresToXY(XToLon(centerX), YToLat(centerY), sizeX, sizeY);
}
- inline static m2::RectD RectByCenterXYAndSizeInMeters(m2::PointD const & center, double size)
+ static m2::RectD RectByCenterXYAndSizeInMeters(m2::PointD const & center, double size)
{
return RectByCenterXYAndSizeInMeters(center.x, center.y, size, size);
}
@@ -95,34 +68,34 @@ struct MercatorBounds
static double constexpr GetCellID2PointAbsEpsilon() { return 1.0E-4; }
- inline static m2::PointD FromLatLon(double lat, double lon)
+ static m2::PointD FromLatLon(double lat, double lon)
{
return m2::PointD(LonToX(lon), LatToY(lat));
}
- inline static m2::PointD FromLatLon(ms::LatLon const & point)
+ static m2::PointD FromLatLon(ms::LatLon const & point)
{
return FromLatLon(point.lat, point.lon);
}
- inline static m2::RectD RectByCenterLatLonAndSizeInMeters(double lat, double lon, double size)
+ static m2::RectD RectByCenterLatLonAndSizeInMeters(double lat, double lon, double size)
{
return RectByCenterXYAndSizeInMeters(FromLatLon(lat, lon), size);
}
- inline static ms::LatLon ToLatLon(m2::PointD const & point)
+ static ms::LatLon ToLatLon(m2::PointD const & point)
{
return {YToLat(point.y), XToLon(point.x)};
}
/// Converts lat lon rect to mercator one
- inline static m2::RectD FromLatLonRect(m2::RectD const & latLonRect)
+ static m2::RectD FromLatLonRect(m2::RectD const & latLonRect)
{
return m2::RectD(FromLatLon(latLonRect.minY(), latLonRect.minX()),
FromLatLon(latLonRect.maxY(), latLonRect.maxX()));
}
- inline static m2::RectD ToLatLonRect(m2::RectD const & mercatorRect)
+ static m2::RectD ToLatLonRect(m2::RectD const & mercatorRect)
{
return m2::RectD(YToLat(mercatorRect.minY()), XToLon(mercatorRect.minX()),
YToLat(mercatorRect.maxY()), XToLon(mercatorRect.maxX()));
diff --git a/geometry/packer.cpp b/geometry/packer.cpp
index 183af8d4e8..6b56b86966 100644
--- a/geometry/packer.cpp
+++ b/geometry/packer.cpp
@@ -3,106 +3,122 @@
#include "base/assert.hpp"
#include "base/logging.hpp"
+using namespace std;
+
namespace m2
{
- Packer::Packer()
- : m_currentX(0),
- m_currentY(0),
- m_yStep(0),
- m_width(0),
- m_height(0),
- m_currentHandle(0),
- m_maxHandle(0),
- m_invalidHandle(0x00FFFFFF)
- {}
-
- Packer::Packer(unsigned width, unsigned height, uint32_t maxHandle)
- : m_currentX(0),
- m_currentY(0),
- m_yStep(0),
- m_width(width),
- m_height(height),
- m_currentHandle(0),
- m_maxHandle(maxHandle),
- m_invalidHandle(0x00FFFFFF)
- {
- }
-
- uint32_t Packer::invalidHandle() const
- {
- return m_invalidHandle;
- }
-
- Packer::handle_t Packer::pack(unsigned width, unsigned height)
- {
- ASSERT(width <= m_width, ());
- ASSERT(height <= m_height, ());
+Packer::Packer()
+ : m_currentX(0)
+ , m_currentY(0)
+ , m_yStep(0)
+ , m_width(0)
+ , m_height(0)
+ , m_currentHandle(0)
+ , m_maxHandle(0)
+ , m_invalidHandle(0x00FFFFFF)
+{
+}
- if ((width > m_width) || (height > m_height))
- return m_invalidHandle;
+Packer::Packer(unsigned width, unsigned height, uint32_t maxHandle)
+ : m_currentX(0)
+ , m_currentY(0)
+ , m_yStep(0)
+ , m_width(width)
+ , m_height(height)
+ , m_currentHandle(0)
+ , m_maxHandle(maxHandle)
+ , m_invalidHandle(0x00FFFFFF)
+{
+}
- /// checking whether there is enough space on X axis
+uint32_t Packer::invalidHandle() const { return m_invalidHandle; }
- if (m_currentX + width > m_width)
- {
- m_currentY += m_yStep;
- m_currentX = 0;
- m_yStep = 0;
- }
+Packer::handle_t Packer::pack(unsigned width, unsigned height)
+{
+ ASSERT(width <= m_width, ());
+ ASSERT(height <= m_height, ());
- /// checking whether there is enough space on Y axis
- if (m_currentY + height > m_height)
- {
- /// texture overflow detected. all packed rects should be forgotten.
- callOverflowFns();
- reset();
- }
- /// check handleOverflow
- if (m_currentHandle == m_maxHandle)
- {
- /// handles overflow detected. all packed rects should be forgotten.
- callOverflowFns();
- reset();
- m_currentHandle = 0;
- }
+ if ((width > m_width) || (height > m_height))
+ return m_invalidHandle;
- /// can pack
- m_yStep = max(height, m_yStep);
- handle_t curHandle = m_currentHandle++;
- m_rects[curHandle] = m2::RectU(m_currentX, m_currentY, m_currentX + width, m_currentY + height);
- m_currentX += width;
+ /// checking whether there is enough space on X axis
- return curHandle;
+ if (m_currentX + width > m_width)
+ {
+ m_currentY += m_yStep;
+ m_currentX = 0;
+ m_yStep = 0;
}
- Packer::handle_t Packer::freeHandle()
+ /// checking whether there is enough space on Y axis
+ if (m_currentY + height > m_height)
{
- if (m_currentHandle == m_maxHandle)
- {
- callOverflowFns();
- reset();
- m_currentHandle = 0;
- }
-
- return m_currentHandle++;
+ /// texture overflow detected. all packed rects should be forgotten.
+ callOverflowFns();
+ reset();
+ }
+ /// check handleOverflow
+ if (m_currentHandle == m_maxHandle)
+ {
+ /// handles overflow detected. all packed rects should be forgotten.
+ callOverflowFns();
+ reset();
+ m_currentHandle = 0;
}
- bool Packer::hasRoom(unsigned width, unsigned height) const
+ /// can pack
+ m_yStep = max(height, m_yStep);
+ handle_t curHandle = m_currentHandle++;
+ m_rects[curHandle] = m2::RectU(m_currentX, m_currentY, m_currentX + width, m_currentY + height);
+ m_currentX += width;
+
+ return curHandle;
+}
+
+Packer::handle_t Packer::freeHandle()
+{
+ if (m_currentHandle == m_maxHandle)
{
- return ((m_width >= width) && (m_height - m_currentY - m_yStep >= height))
- || ((m_width - m_currentX >= width ) && (m_height - m_currentY >= height));
+ callOverflowFns();
+ reset();
+ m_currentHandle = 0;
}
- bool Packer::hasRoom(m2::PointU const * sizes, size_t cnt) const
+ return m_currentHandle++;
+}
+
+bool Packer::hasRoom(unsigned width, unsigned height) const
+{
+ return ((m_width >= width) && (m_height - m_currentY - m_yStep >= height)) ||
+ ((m_width - m_currentX >= width) && (m_height - m_currentY >= height));
+}
+
+bool Packer::hasRoom(m2::PointU const * sizes, size_t cnt) const
+{
+ unsigned currentX = m_currentX;
+ unsigned currentY = m_currentY;
+ unsigned yStep = m_yStep;
+
+ for (unsigned i = 0; i < cnt; ++i)
{
- unsigned currentX = m_currentX;
- unsigned currentY = m_currentY;
- unsigned yStep = m_yStep;
+ unsigned width = sizes[i].x;
+ unsigned height = sizes[i].y;
- for (unsigned i = 0; i < cnt; ++i)
+ if (width <= m_width - currentX)
+ {
+ if (height <= m_height - currentY)
+ {
+ yStep = max(height, yStep);
+ currentX += width;
+ }
+ else
+ return false;
+ }
+ else
{
- unsigned width = sizes[i].x;
- unsigned height = sizes[i].y;
+ currentX = 0;
+ currentY += yStep;
+ yStep = 0;
if (width <= m_width - currentX)
{
@@ -114,70 +130,48 @@ namespace m2
else
return false;
}
- else
- {
- currentX = 0;
- currentY += yStep;
- yStep = 0;
-
- if (width <= m_width - currentX)
- {
- if (height <= m_height - currentY)
- {
- yStep = max(height, yStep);
- currentX += width;
- }
- else
- return false;
- }
- }
}
-
- return true;
}
- bool Packer::isPacked(handle_t handle)
- {
- return m_rects.find(handle) != m_rects.end();
- }
+ return true;
+}
- Packer::find_result_t Packer::find(handle_t handle) const
- {
- rects_t::const_iterator it = m_rects.find(handle);
- std::pair<bool, m2::RectU> res;
- res.first = (it != m_rects.end());
- if (res.first)
- res.second = it->second;
- return res;
- }
+bool Packer::isPacked(handle_t handle) { return m_rects.find(handle) != m_rects.end(); }
- void Packer::remove(handle_t handle)
- {
- m_rects.erase(handle);
- }
+Packer::find_result_t Packer::find(handle_t handle) const
+{
+ rects_t::const_iterator it = m_rects.find(handle);
+ std::pair<bool, m2::RectU> res;
+ res.first = (it != m_rects.end());
+ if (res.first)
+ res.second = it->second;
+ return res;
+}
- void Packer::reset()
- {
- m_rects.clear();
- m_currentX = 0;
- m_currentY = 0;
- m_yStep = 0;
- m_currentHandle = 0;
- }
+void Packer::remove(handle_t handle) { m_rects.erase(handle); }
- void Packer::addOverflowFn(overflowFn fn, int priority)
- {
- m_overflowFns.push(std::pair<size_t, overflowFn>(priority, fn));
- }
+void Packer::reset()
+{
+ m_rects.clear();
+ m_currentX = 0;
+ m_currentY = 0;
+ m_yStep = 0;
+ m_currentHandle = 0;
+}
- void Packer::callOverflowFns()
+void Packer::addOverflowFn(overflowFn fn, int priority)
+{
+ m_overflowFns.push(std::pair<size_t, overflowFn>(priority, fn));
+}
+
+void Packer::callOverflowFns()
+{
+ LOG(LDEBUG, ("Texture|Handles Overflow"));
+ overflowFns handlersCopy = m_overflowFns;
+ while (!handlersCopy.empty())
{
- LOG(LDEBUG, ("Texture|Handles Overflow"));
- overflowFns handlersCopy = m_overflowFns;
- while (!handlersCopy.empty())
- {
- handlersCopy.top().second();
- handlersCopy.pop();
- }
+ handlersCopy.top().second();
+ handlersCopy.pop();
}
}
+} // namespace m2
diff --git a/geometry/packer.hpp b/geometry/packer.hpp
index 3efe051abf..4944fdd3cc 100644
--- a/geometry/packer.hpp
+++ b/geometry/packer.hpp
@@ -2,99 +2,97 @@
#include "geometry/rect2d.hpp"
-#include "std/list.hpp"
-#include "std/map.hpp"
-#include "std/function.hpp"
-#include "std/queue.hpp"
-#include "std/utility.hpp"
-#include "std/vector.hpp"
-
+#include <cstdint>
+#include <functional>
+#include <list>
+#include <map>
+#include <queue>
+#include <utility>
+#include <vector>
namespace m2
{
- template <typename pair_t>
- struct first_less
- {
- bool operator()(pair_t const & first, pair_t const & second)
- {
- return first.first < second.first;
- }
- };
-
- /// The simplest row-by-row packer.
- /// When there is no free room all the packing
- /// rect is cleared and the process is started again.
- class Packer
+template <typename pair_t>
+struct first_less
+{
+ bool operator()(pair_t const & first, pair_t const & second)
{
- public:
-
- typedef function<void()> overflowFn;
-
- typedef priority_queue<pair<size_t, overflowFn>, vector<pair<size_t, overflowFn> >, first_less<pair<size_t, overflowFn> > > overflowFns;
-
- typedef uint32_t handle_t;
- typedef std::pair<bool, m2::RectU> find_result_t;
+ return first.first < second.first;
+ }
+};
+
+/// The simplest row-by-row packer.
+/// When there is no free room all the packing
+/// rect is cleared and the process is started again.
+class Packer
+{
+public:
+ using overflowFn = std::function<void()>;
- private:
+ using overflowFns =
+ std::priority_queue<std::pair<size_t, overflowFn>, std::vector<std::pair<size_t, overflowFn>>,
+ first_less<std::pair<size_t, overflowFn>>>;
- unsigned m_currentX;
- unsigned m_currentY;
- unsigned m_yStep;
+ using handle_t = uint32_t;
+ using find_result_t = std::pair<bool, m2::RectU>;
- unsigned m_width;
- unsigned m_height;
+ Packer();
- overflowFns m_overflowFns;
+ /// create a packer on a rectangular area of (0, 0, width, height) dimensions
+ Packer(unsigned width, unsigned height, uint32_t maxHandle = 0xFFFF - 1);
- handle_t m_currentHandle;
+ /// reset the state of the packer
+ void reset();
- typedef map<handle_t, m2::RectU> rects_t;
+ /// add overflow handler.
+ /// @param priority handlers with higher priority value are called first.
+ void addOverflowFn(overflowFn fn, int priority);
- rects_t m_rects;
+ /// pack the rect with dimensions width X height on a free area.
+ /// when there is no free area - find it somehow(depending on a packer implementation,
+ /// the simplest one will just clear the whole rect and start the packing process again).
+ handle_t pack(unsigned width, unsigned height);
- void callOverflowFns();
+ /// return free handle
+ handle_t freeHandle();
- uint32_t m_maxHandle;
- uint32_t m_invalidHandle;
+ /// Does we have room to pack another rectangle?
+ bool hasRoom(unsigned width, unsigned height) const;
- public:
+ /// Does we have room to pack a sequence of rectangles?
+ bool hasRoom(m2::PointU const * sizes, size_t cnt) const;
- Packer();
+ /// is the handle present on the texture.
+ bool isPacked(handle_t handle);
- /// create a packer on a rectangular area of (0, 0, width, height) dimensions
- Packer(unsigned width, unsigned height, uint32_t maxHandle = 0xFFFF - 1);
+ /// find the packed area by the handle.
+ find_result_t find(handle_t handle) const;
- /// reset the state of the packer
- void reset();
+ /// remove the handle from the list of active handles.
+ void remove(handle_t handle);
- /// add overflow handler.
- /// @param priority handlers with higher priority value are called first.
- void addOverflowFn(overflowFn fn, int priority);
+ /// get an invalid handle
+ uint32_t invalidHandle() const;
- /// pack the rect with dimensions width X height on a free area.
- /// when there is no free area - find it somehow(depending on a packer implementation,
- /// the simplest one will just clear the whole rect and start the packing process again).
- handle_t pack(unsigned width, unsigned height);
+private:
+ using rects_t = std::map<handle_t, m2::RectU>;
- /// return free handle
- handle_t freeHandle();
+ void callOverflowFns();
- /// Does we have room to pack another rectangle?
- bool hasRoom(unsigned width, unsigned height) const;
+ unsigned m_currentX;
+ unsigned m_currentY;
+ unsigned m_yStep;
- /// Does we have room to pack a sequence of rectangles?
- bool hasRoom(m2::PointU const * sizes, size_t cnt) const;
+ unsigned m_width;
+ unsigned m_height;
- /// is the handle present on the texture.
- bool isPacked(handle_t handle);
+ overflowFns m_overflowFns;
- /// find the packed area by the handle.
- find_result_t find(handle_t handle) const;
+ handle_t m_currentHandle;
- /// remove the handle from the list of active handles.
- void remove(handle_t handle);
+ rects_t m_rects;
- /// get an invalid handle
- uint32_t invalidHandle() const;
- };
-}
+ uint32_t m_maxHandle;
+ uint32_t m_invalidHandle;
+};
+} // namespace m2
diff --git a/geometry/point2d.hpp b/geometry/point2d.hpp
index 7afec7c336..3b46e05150 100644
--- a/geometry/point2d.hpp
+++ b/geometry/point2d.hpp
@@ -5,331 +5,295 @@
#include "base/math.hpp"
#include "base/matrix.hpp"
-#include "std/array.hpp"
-#include "std/cmath.hpp"
-#include "std/functional.hpp"
-#include "std/sstream.hpp"
-#include "std/typeinfo.hpp"
-
+#include <array>
+#include <cmath>
+#include <functional>
+#include <sstream>
+#include <typeinfo>
namespace m2
{
- template <typename T>
- class Point
- {
- public:
- using value_type = T;
-
- T x, y;
-
- Point() : x(T()), y(T()) {}
-
- Point(T x_, T y_) : x(x_), y(y_) {}
-
- template <typename U>
- explicit Point(Point<U> const & u) : x(u.x), y(u.y) {}
-
- static Point<T> Zero() { return Point<T>(0, 0); }
-
- bool EqualDxDy(Point<T> const & p, T eps) const
- {
- return ((fabs(x - p.x) < eps) && (fabs(y - p.y) < eps));
- }
-
- T SquaredLength(Point<T> const & p) const { return pow(x - p.x, 2) + pow(y - p.y, 2); }
-
- T SquaredLength() const { return x * x + y * y; }
-
- double Length(Point<T> const & p) const
- {
- return sqrt(SquaredLength(p));
- }
-
- bool IsAlmostZero() const
- {
- return AlmostEqualULPs(*this, Point<T>(0,0));
- }
-
- Point<T> Move(T len, T ang) const
- {
- return Point<T>(x + len * cos(ang), y + len * sin(ang));
- }
-
- Point<T> Move(T len, T angSin, T angCos) const
- {
- return m2::Point<T>(x + len * angCos, y + len * angSin);
- }
-
- Point<T> const & operator-=(Point<T> const & a)
- {
- x -= a.x;
- y -= a.y;
- return *this;
- }
-
- Point<T> const & operator+=(Point<T> const & a)
- {
- x += a.x;
- y += a.y;
- return *this;
- }
-
- template <typename U>
- Point<T> const & operator*=(U const & k)
- {
- x = static_cast<T>(x * k);
- y = static_cast<T>(y * k);
- return *this;
- }
-
- template <typename U>
- Point<T> const & operator=(Point<U> const & a)
- {
- x = static_cast<T>(a.x);
- y = static_cast<T>(a.y);
- return *this;
- }
-
- bool operator==(m2::Point<T> const & p) const
- {
- return x == p.x && y == p.y;
- }
-
- bool operator!=(m2::Point<T> const & p) const
- {
- return !(*this == p);
- }
-
- m2::Point<T> operator+(m2::Point<T> const & pt) const
- {
- return m2::Point<T>(x + pt.x, y + pt.y);
- }
-
- m2::Point<T> operator-(m2::Point<T> const & pt) const
- {
- return m2::Point<T>(x - pt.x, y - pt.y);
- }
-
- m2::Point<T> operator-() const
- {
- return m2::Point<T>(-x, -y);
- }
-
- m2::Point<T> operator*(T scale) const
- {
- return m2::Point<T>(x * scale, y * scale);
- }
-
- m2::Point<T> const operator*(math::Matrix<T, 3, 3> const & m) const
- {
- m2::Point<T> res;
- res.x = x * m(0, 0) + y * m(1, 0) + m(2, 0);
- res.y = x * m(0, 1) + y * m(1, 1) + m(2, 1);
- return res;
- }
-
- m2::Point<T> operator/(T scale) const
- {
- return m2::Point<T>(x / scale, y / scale);
- }
-
- m2::Point<T> mid(m2::Point<T> const & p) const
- {
- return m2::Point<T>((x + p.x) * 0.5, (y + p.y) * 0.5);
- }
-
- /// @name VectorOperationsOnPoint
- double Length() const
- {
- return sqrt(SquaredLength());
- }
-
- Point<T> Normalize() const
- {
- ASSERT(!IsAlmostZero(), ());
- double const module = this->Length();
- return Point<T>(x / module, y / module);
- }
-
- std::pair<Point<T>, Point<T> > Normals(T prolongationFactor = 1) const
- {
- T const prolongatedX = prolongationFactor * x;
- T const prolongatedY = prolongationFactor * y;
- return std::pair<Point<T>, Point<T> >(Point<T>(static_cast<T>(-prolongatedY), static_cast<T>(prolongatedX)),
- Point<T>(static_cast<T>(prolongatedY), static_cast<T>(-prolongatedX)));
- }
-
- m2::Point<T> const & operator *= (math::Matrix<T, 3, 3> const & m)
- {
- T tempX = x;
- x = tempX * m(0, 0) + y * m(1, 0) + m(2, 0);
- y = tempX * m(0, 1) + y * m(1, 1) + m(2, 1);
- return *this;
- }
-
- void Rotate(double angle)
- {
- T cosAngle = cos(angle);
- T sinAngle = sin(angle);
- T oldX = x;
- x = cosAngle * oldX - sinAngle * y;
- y = sinAngle * oldX + cosAngle * y;
- }
-
- // Returns vector rotated 90 degrees counterclockwise.
- Point Ort() const { return Point(-y, x); }
-
- void Transform(m2::Point<T> const & org,
- m2::Point<T> const & dx, m2::Point<T> const & dy)
- {
- T oldX = x;
- x = org.x + oldX * dx.x + y * dy.x;
- y = org.y + oldX * dx.y + y * dy.y;
- }
-
- struct Hash
- {
- size_t operator()(m2::Point<T> const & p) const
- {
- return my::Hash(p.x, p.y);
- }
- };
- };
+template <typename T>
+class Point
+{
+public:
+ using value_type = T;
+
+ T x, y;
- template <typename T>
- inline Point<T> const operator- (Point<T> const & a, Point<T> const & b)
+ Point() : x(T()), y(T()) {}
+
+ Point(T x_, T y_) : x(x_), y(y_) {}
+
+ template <typename U>
+ explicit Point(Point<U> const & u) : x(u.x), y(u.y)
{
- return Point<T>(a.x - b.x, a.y - b.y);
}
- template <typename T>
- inline Point<T> const operator+ (Point<T> const & a, Point<T> const & b)
+ static Point<T> Zero() { return Point<T>(0, 0); }
+
+ bool EqualDxDy(Point<T> const & p, T eps) const
{
- return Point<T>(a.x + b.x, a.y + b.y);
+ return ((fabs(x - p.x) < eps) && (fabs(y - p.y) < eps));
}
- // Dot product of a and b, equals to |a|*|b|*cos(angle_between_a_and_b).
- template <typename T>
- T const DotProduct(Point<T> const & a, Point<T> const & b)
+ T SquaredLength(Point<T> const & p) const { return pow(x - p.x, 2.0) + pow(y - p.y, 2.0); }
+
+ T SquaredLength() const { return x * x + y * y; }
+
+ double Length(Point<T> const & p) const { return sqrt(SquaredLength(p)); }
+
+ bool IsAlmostZero() const { return AlmostEqualULPs(*this, Point<T>(0, 0)); }
+
+ Point<T> Move(T len, T ang) const { return Point<T>(x + len * cos(ang), y + len * sin(ang)); }
+
+ Point<T> Move(T len, T angSin, T angCos) const
{
- return a.x * b.x + a.y * b.y;
+ return m2::Point<T>(x + len * angCos, y + len * angSin);
}
- // Value of cross product of a and b, equals to |a|*|b|*sin(angle_between_a_and_b).
- template <typename T>
- T const CrossProduct(Point<T> const & a, Point<T> const & b)
+ Point<T> const & operator-=(Point<T> const & a)
{
- return a.x * b.y - a.y * b.x;
+ x -= a.x;
+ y -= a.y;
+ return *this;
}
- template <typename T>
- Point<T> const Rotate(Point<T> const & pt, T a)
+ Point<T> const & operator+=(Point<T> const & a)
{
- Point<T> res(pt);
- res.Rotate(a);
- return res;
+ x += a.x;
+ y += a.y;
+ return *this;
}
- template <typename T, typename U>
- Point<T> const Shift(Point<T> const & pt, U const & dx, U const & dy)
+ template <typename U>
+ Point<T> const & operator*=(U const & k)
{
- return Point<T>(pt.x + dx, pt.y + dy);
+ x = static_cast<T>(x * k);
+ y = static_cast<T>(y * k);
+ return *this;
}
- template <typename T, typename U>
- Point<T> const Shift(Point<T> const & pt, Point<U> const & offset)
+ template <typename U>
+ Point<T> const & operator=(Point<U> const & a)
{
- return Shift(pt, offset.x, offset.y);
+ x = static_cast<T>(a.x);
+ y = static_cast<T>(a.y);
+ return *this;
}
- template <typename T>
- Point<T> const Floor(Point<T> const & pt)
+ bool operator==(m2::Point<T> const & p) const { return x == p.x && y == p.y; }
+
+ bool operator!=(m2::Point<T> const & p) const { return !(*this == p); }
+
+ m2::Point<T> operator+(m2::Point<T> const & pt) const { return m2::Point<T>(x + pt.x, y + pt.y); }
+
+ m2::Point<T> operator-(m2::Point<T> const & pt) const { return m2::Point<T>(x - pt.x, y - pt.y); }
+
+ m2::Point<T> operator-() const { return m2::Point<T>(-x, -y); }
+
+ m2::Point<T> operator*(T scale) const { return m2::Point<T>(x * scale, y * scale); }
+
+ m2::Point<T> const operator*(math::Matrix<T, 3, 3> const & m) const
{
- Point<T> res;
- res.x = floor(pt.x);
- res.y = floor(pt.y);
+ m2::Point<T> res;
+ res.x = x * m(0, 0) + y * m(1, 0) + m(2, 0);
+ res.y = x * m(0, 1) + y * m(1, 1) + m(2, 1);
return res;
}
- template <typename T> std::string DebugPrint(m2::Point<T> const & p)
- {
- ostringstream out;
- out.precision(20);
- out << "m2::Point<" << typeid(T).name() << ">(" << p.x << ", " << p.y << ")";
- return out.str();
- }
+ m2::Point<T> operator/(T scale) const { return m2::Point<T>(x / scale, y / scale); }
- template <typename T>
- bool AlmostEqualAbs(m2::Point<T> const & a, m2::Point<T> const & b, double const eps)
+ m2::Point<T> mid(m2::Point<T> const & p) const
{
- return my::AlmostEqualAbs(a.x, b.x, eps) && my::AlmostEqualAbs(a.y, b.y, eps);
+ return m2::Point<T>((x + p.x) * 0.5, (y + p.y) * 0.5);
}
- template <typename T>
- bool AlmostEqualULPs(m2::Point<T> const & a, m2::Point<T> const & b, unsigned int maxULPs = 256)
+ /// @name VectorOperationsOnPoint
+ double Length() const { return sqrt(SquaredLength()); }
+
+ Point<T> Normalize() const
{
- return my::AlmostEqualULPs(a.x, b.x, maxULPs) && my::AlmostEqualULPs(a.y, b.y, maxULPs);
+ ASSERT(!IsAlmostZero(), ());
+ double const length = this->Length();
+ return Point<T>(x / length, y / length);
}
- /// Calculate three points of a triangle (p1, p2 and p3) which give an arrow that
- /// presents an equilateral triangle with the median
- /// starting at point b and having direction b,e.
- /// The height of the equilateral triangle is l and the base of the triangle is 2 * w
- template <typename T, typename TT, typename PointT = Point<T>>
- void GetArrowPoints(PointT const & b, PointT const & e, T w, T l, array<Point<TT>, 3> & arrPnts)
+ std::pair<Point<T>, Point<T>> Normals(T prolongationFactor = 1) const
{
- ASSERT(!m2::AlmostEqualULPs(b, e), ());
-
- PointT const beVec = e - b;
- PointT beNormalizedVec = beVec.Normalize();
- std::pair<PointT, PointT > beNormVecs = beNormalizedVec.Normals(w);
-
- arrPnts[0] = e + beNormVecs.first;
- arrPnts[1] = e + beNormalizedVec * l;
- arrPnts[2] = e + beNormVecs.second;
+ T const prolongatedX = prolongationFactor * x;
+ T const prolongatedY = prolongationFactor * y;
+ return std::pair<Point<T>, Point<T>>(
+ Point<T>(static_cast<T>(-prolongatedY), static_cast<T>(prolongatedX)),
+ Point<T>(static_cast<T>(prolongatedY), static_cast<T>(-prolongatedX)));
}
- /// Returns a point which is belonged to the segment p1, p2 with respet the indent shiftFromP1 from p1.
- /// If shiftFromP1 is more the distance between (p1, p2) it returns p2.
- /// If shiftFromP1 is less or equal zero it returns p1.
- template <typename T>
- Point<T> PointAtSegment(Point<T> const & p1, Point<T> const & p2, T shiftFromP1)
+ m2::Point<T> const & operator*=(math::Matrix<T, 3, 3> const & m)
{
- Point<T> p12 = p2 - p1;
- shiftFromP1 = my::clamp(shiftFromP1, static_cast<T>(0.0), static_cast<T>(p12.Length()));
- return p1 + p12.Normalize() * shiftFromP1;
+ T tempX = x;
+ x = tempX * m(0, 0) + y * m(1, 0) + m(2, 0);
+ y = tempX * m(0, 1) + y * m(1, 1) + m(2, 1);
+ return *this;
}
- template <class TArchive, class PointT>
- TArchive & operator >> (TArchive & ar, m2::Point<PointT> & pt)
+ void Rotate(double angle)
{
- ar >> pt.x;
- ar >> pt.y;
- return ar;
+ T cosAngle = cos(angle);
+ T sinAngle = sin(angle);
+ T oldX = x;
+ x = cosAngle * oldX - sinAngle * y;
+ y = sinAngle * oldX + cosAngle * y;
}
- template <class TArchive, class PointT>
- TArchive & operator<<(TArchive & ar, m2::Point<PointT> const & pt)
+ // Returns vector rotated 90 degrees counterclockwise.
+ Point Ort() const { return Point(-y, x); }
+
+ void Transform(m2::Point<T> const & org, m2::Point<T> const & dx, m2::Point<T> const & dy)
{
- ar << pt.x;
- ar << pt.y;
- return ar;
+ T oldX = x;
+ x = org.x + oldX * dx.x + y * dy.x;
+ y = org.y + oldX * dx.y + y * dy.y;
}
- template <typename T>
- bool operator<(Point<T> const & l, Point<T> const & r)
+ struct Hash
{
- if (l.x != r.x)
- return l.x < r.x;
- return l.y < r.y;
- }
+ size_t operator()(m2::Point<T> const & p) const { return my::Hash(p.x, p.y); }
+ };
+};
+
+using PointF = Point<float>;
+using PointD = Point<double>;
+using PointU = Point<uint32_t>;
+using PointU64 = Point<uint64_t>;
+using PointI = Point<int32_t>;
+using PointI64 = Point<int64_t>;
+
+template <typename T>
+Point<T> const operator-(Point<T> const & a, Point<T> const & b)
+{
+ return Point<T>(a.x - b.x, a.y - b.y);
+}
+
+template <typename T>
+Point<T> const operator+(Point<T> const & a, Point<T> const & b)
+{
+ return Point<T>(a.x + b.x, a.y + b.y);
+}
+
+template <typename T>
+T const DotProduct(Point<T> const & a, Point<T> const & b)
+{
+ return a.x * b.x + a.y * b.y;
+}
+
+template <typename T>
+T const CrossProduct(Point<T> const & a, Point<T> const & b)
+{
+ return a.x * b.y - a.y * b.x;
+}
+
+template <typename T>
+Point<T> const Rotate(Point<T> const & pt, T a)
+{
+ Point<T> res(pt);
+ res.Rotate(a);
+ return res;
+}
+
+template <typename T, typename U>
+Point<T> const Shift(Point<T> const & pt, U const & dx, U const & dy)
+{
+ return Point<T>(pt.x + dx, pt.y + dy);
+}
+
+template <typename T, typename U>
+Point<T> const Shift(Point<T> const & pt, Point<U> const & offset)
+{
+ return Shift(pt, offset.x, offset.y);
+}
+
+template <typename T>
+Point<T> const Floor(Point<T> const & pt)
+{
+ Point<T> res;
+ res.x = floor(pt.x);
+ res.y = floor(pt.y);
+ return res;
+}
+
+template <typename T>
+std::string DebugPrint(m2::Point<T> const & p)
+{
+ std::ostringstream out;
+ out.precision(20);
+ out << "m2::Point<" << typeid(T).name() << ">(" << p.x << ", " << p.y << ")";
+ return out.str();
+}
+
+template <typename T>
+bool AlmostEqualAbs(m2::Point<T> const & a, m2::Point<T> const & b, double const eps)
+{
+ return my::AlmostEqualAbs(a.x, b.x, eps) && my::AlmostEqualAbs(a.y, b.y, eps);
+}
- using PointF = Point<float>;
- using PointD = Point<double>;
- using PointU = Point<uint32_t>;
- using PointU64 = Point<uint64_t>;
- using PointI = Point<int32_t>;
- using PointI64 = Point<int64_t>;
+template <typename T>
+bool AlmostEqualULPs(m2::Point<T> const & a, m2::Point<T> const & b, unsigned int maxULPs = 256)
+{
+ return my::AlmostEqualULPs(a.x, b.x, maxULPs) && my::AlmostEqualULPs(a.y, b.y, maxULPs);
+}
+
+/// Calculate three points of a triangle (p1, p2 and p3) which give an arrow that
+/// presents an equilateral triangle with the median
+/// starting at point b and having direction b,e.
+/// The height of the equilateral triangle is l and the base of the triangle is 2 * w
+template <typename T, typename TT, typename PointT = Point<T>>
+void GetArrowPoints(PointT const & b, PointT const & e, T w, T l, std::array<Point<TT>, 3> & arr)
+{
+ ASSERT(!m2::AlmostEqualULPs(b, e), ());
+
+ PointT const beVec = e - b;
+ PointT beNormalizedVec = beVec.Normalize();
+ std::pair<PointT, PointT> beNormVecs = beNormalizedVec.Normals(w);
+
+ arr[0] = e + beNormVecs.first;
+ arr[1] = e + beNormalizedVec * l;
+ arr[2] = e + beNormVecs.second;
+}
+
+/// Returns a point which is belonged to the segment p1, p2 with respet the indent shiftFromP1 from
+/// p1. If shiftFromP1 is more the distance between (p1, p2) it returns p2. If shiftFromP1 is less
+/// or equal zero it returns p1.
+template <typename T>
+Point<T> PointAtSegment(Point<T> const & p1, Point<T> const & p2, T shiftFromP1)
+{
+ Point<T> p12 = p2 - p1;
+ shiftFromP1 = my::clamp(shiftFromP1, static_cast<T>(0.0), static_cast<T>(p12.Length()));
+ return p1 + p12.Normalize() * shiftFromP1;
+}
+
+template <class TArchive, class PointT>
+TArchive & operator>>(TArchive & ar, m2::Point<PointT> & pt)
+{
+ ar >> pt.x;
+ ar >> pt.y;
+ return ar;
+}
+
+template <class TArchive, class PointT>
+TArchive & operator<<(TArchive & ar, m2::Point<PointT> const & pt)
+{
+ ar << pt.x;
+ ar << pt.y;
+ return ar;
+}
+
+template <typename T>
+bool operator<(Point<T> const & l, Point<T> const & r)
+{
+ if (l.x != r.x)
+ return l.x < r.x;
+ return l.y < r.y;
+}
} // namespace m2
namespace my
diff --git a/geometry/polyline2d.hpp b/geometry/polyline2d.hpp
index 2bc82d64b5..00d9588d1f 100644
--- a/geometry/polyline2d.hpp
+++ b/geometry/polyline2d.hpp
@@ -1,37 +1,40 @@
#pragma once
+#include "geometry/distance.hpp"
#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"
-#include "geometry/distance.hpp"
#include "base/internal/message.hpp"
-#include "std/initializer_list.hpp"
-#include "std/vector.hpp"
+#include <cstddef>
+#include <initializer_list>
+#include <limits>
+#include <string>
+#include <vector>
namespace m2
{
template <typename T>
class Polyline
{
- vector<Point<T> > m_points;
+ std::vector<Point<T>> m_points;
public:
- using Container = vector<Point<T>>;
+ using Container = std::vector<Point<T>>;
using Iter = typename Container::const_iterator;
Polyline() {}
- Polyline(initializer_list<Point<T>> const & points) : m_points(points)
+ Polyline(std::initializer_list<Point<T>> const & points) : m_points(points)
{
ASSERT_GREATER(m_points.size(), 1, ());
}
- explicit Polyline(vector<Point<T>> const & points) : m_points(points)
+ explicit Polyline(std::vector<Point<T>> const & points) : m_points(points)
{
ASSERT_GREATER(m_points.size(), 1, ());
}
- explicit Polyline(vector<Point<T>> && points) : m_points(move(points))
+ explicit Polyline(std::vector<Point<T>> && points) : m_points(move(points))
{
ASSERT_GREATER(m_points.size(), 1, ());
}
@@ -47,7 +50,7 @@ public:
// @todo add cached value and lazy init
double dist = 0;
for (size_t i = 1; i < m_points.size(); ++i)
- dist += m_points[i-1].Length(m_points[i]);
+ dist += m_points[i - 1].Length(m_points[i]);
return dist;
}
@@ -61,7 +64,7 @@ public:
double CalcMinSquaredDistance(m2::Point<T> const & point) const
{
- double res = numeric_limits<double>::max();
+ double res = std::numeric_limits<double>::max();
m2::DistanceToLineSquare<m2::Point<T>> d;
Iter i = Begin();
@@ -136,31 +139,31 @@ public:
return m_points.back();
}
- vector<Point<T>> ExtractSegment(size_t segmentIndex, bool reversed) const
+ std::vector<Point<T>> ExtractSegment(size_t segmentIndex, bool reversed) const
{
if (segmentIndex + 1 >= m_points.size())
- return vector<Point<T>>();
+ return std::vector<Point<T>>();
- return reversed ? vector<Point<T>>{m_points[segmentIndex + 1], m_points[segmentIndex]} :
- vector<Point<T>>{m_points[segmentIndex], m_points[segmentIndex + 1]};
+ return reversed ? std::vector<Point<T>>{m_points[segmentIndex + 1], m_points[segmentIndex]}
+ : std::vector<Point<T>>{m_points[segmentIndex], m_points[segmentIndex + 1]};
}
- vector<Point<T>> ExtractSegment(size_t startPointIndex, size_t endPointIndex) const
+ std::vector<Point<T>> ExtractSegment(size_t startPointIndex, size_t endPointIndex) const
{
if (startPointIndex > endPointIndex || startPointIndex >= m_points.size() ||
endPointIndex >= m_points.size())
{
- return vector<Point<T>>();
+ return std::vector<Point<T>>();
}
- vector<Point<T>> result(endPointIndex - startPointIndex + 1);
+ std::vector<Point<T>> result(endPointIndex - startPointIndex + 1);
for (size_t i = startPointIndex, j = 0; i <= endPointIndex; ++i, ++j)
result[j] = m_points[i];
return result;
}
- vector<Point<T> > const & GetPoints() const { return m_points; }
- friend string DebugPrint(Polyline const & p) { return ::DebugPrint(p.m_points); }
+ std::vector<Point<T>> const & GetPoints() const { return m_points; }
+ friend std::string DebugPrint(Polyline const & p) { return ::DebugPrint(p.m_points); }
};
using PolylineD = Polyline<double>;
diff --git a/geometry/rect2d.hpp b/geometry/rect2d.hpp
index 44f3e9eafd..e980a7b880 100644
--- a/geometry/rect2d.hpp
+++ b/geometry/rect2d.hpp
@@ -5,399 +5,367 @@
#include "base/assert.hpp"
#include "base/internal/message.hpp"
-#include "std/algorithm.hpp"
-#include "std/limits.hpp"
-#include "std/string.hpp"
+#include <algorithm>
+#include <limits>
+#include <sstream>
+#include <string>
namespace m2
{
- namespace impl
- {
- template <typename T, bool has_sign> struct min_max_value;
- template <typename T> struct min_max_value<T, true>
- {
- T get_min() { return -get_max(); }
- T get_max() { return numeric_limits<T>::max(); }
- };
- template <typename T> struct min_max_value<T, false>
- {
- T get_min() { return numeric_limits<T>::min(); }
- T get_max() { return numeric_limits<T>::max(); }
- };
- }
-
-
- template <typename T>
- class Rect
- {
- template <class TArchive, class TPoint>
- friend TArchive & operator << (TArchive & ar, Rect<TPoint> const & rect);
- template <class TArchive, class TPoint>
- friend TArchive & operator >> (TArchive & ar, Rect<TPoint> & rect);
-
- enum { IsSigned = numeric_limits<T>::is_signed };
-
- T m_minX, m_minY, m_maxX, m_maxY;
+namespace impl
+{
+template <typename T, bool has_sign>
+struct min_max_value;
- public:
- typedef T value_type;
+template <typename T>
+struct min_max_value<T, true>
+{
+ T get_min() { return -get_max(); }
+ T get_max() { return std::numeric_limits<T>::max(); }
+};
- Rect() { MakeEmpty(); }
- Rect(T minX, T minY, T maxX, T maxY)
- : m_minX(minX), m_minY(minY), m_maxX(maxX), m_maxY(maxY)
- {
- ASSERT ( minX <= maxX, (minX, maxX) );
- ASSERT ( minY <= maxY, (minY, maxY) );
- }
- Rect(Point<T> const & p1, Point<T> const & p2)
- : m_minX(min(p1.x, p2.x)), m_minY(min(p1.y, p2.y)),
- m_maxX(max(p1.x, p2.x)), m_maxY(max(p1.y, p2.y))
- {
- }
+template <typename T>
+struct min_max_value<T, false>
+{
+ T get_min() { return std::numeric_limits<T>::min(); }
+ T get_max() { return std::numeric_limits<T>::max(); }
+};
+} // namespace impl
- template <typename U>
- explicit Rect(Rect<U> const & src)
- : m_minX(src.minX()), m_minY(src.minY()), m_maxX(src.maxX()), m_maxY(src.maxY())
- {
- }
+template <typename T>
+class Rect
+{
+public:
+ using value_type = T;
- static Rect GetEmptyRect() { return Rect(); }
+ Rect() { MakeEmpty(); }
- static Rect GetInfiniteRect()
- {
- Rect r;
- r.MakeInfinite();
- return r;
- }
+ Rect(T minX, T minY, T maxX, T maxY) : m_minX(minX), m_minY(minY), m_maxX(maxX), m_maxY(maxY)
+ {
+ ASSERT(minX <= maxX, ());
+ ASSERT(minY <= maxY, ());
+ }
- void MakeEmpty()
- {
- m_minX = m_minY = impl::min_max_value<T, IsSigned>().get_max();
- m_maxX = m_maxY = impl::min_max_value<T, IsSigned>().get_min();
- }
+ Rect(Point<T> const & p1, Point<T> const & p2)
+ : m_minX(std::min(p1.x, p2.x))
+ , m_minY(std::min(p1.y, p2.y))
+ , m_maxX(std::max(p1.x, p2.x))
+ , m_maxY(std::max(p1.y, p2.y))
+ {
+ }
- void MakeInfinite()
- {
- m_minX = m_minY = impl::min_max_value<T, IsSigned>().get_min();
- m_maxX = m_maxY = impl::min_max_value<T, IsSigned>().get_max();
- }
+ template <typename U>
+ explicit Rect(Rect<U> const & src)
+ : m_minX(src.minX()), m_minY(src.minY()), m_maxX(src.maxX()), m_maxY(src.maxY())
+ {
+ }
- bool IsValid() const
- {
- return (m_minX <= m_maxX && m_minY <= m_maxY);
- }
+ static Rect GetEmptyRect() { return Rect(); }
- bool IsEmptyInterior() const { return m_minX >= m_maxX || m_minY >= m_maxY; }
+ static Rect GetInfiniteRect()
+ {
+ Rect r;
+ r.MakeInfinite();
+ return r;
+ }
- void Add(m2::Point<T> const & p)
- {
- m_minX = min(p.x, m_minX);
- m_minY = min(p.y, m_minY);
- m_maxX = max(p.x, m_maxX);
- m_maxY = max(p.y, m_maxY);
- }
+ void MakeEmpty()
+ {
+ m_minX = m_minY = impl::min_max_value<T, IsSigned>().get_max();
+ m_maxX = m_maxY = impl::min_max_value<T, IsSigned>().get_min();
+ }
- void Add(m2::Rect<T> const & r)
- {
- m_minX = min(r.m_minX, m_minX);
- m_minY = min(r.m_minY, m_minY);
- m_maxX = max(r.m_maxX, m_maxX);
- m_maxY = max(r.m_maxY, m_maxY);
- }
+ void MakeInfinite()
+ {
+ m_minX = m_minY = impl::min_max_value<T, IsSigned>().get_min();
+ m_maxX = m_maxY = impl::min_max_value<T, IsSigned>().get_max();
+ }
- void Offset(m2::Point<T> const & p)
- {
- m_minX += p.x;
- m_minY += p.y;
- m_maxX += p.x;
- m_maxY += p.y;
- }
+ bool IsValid() const { return (m_minX <= m_maxX && m_minY <= m_maxY); }
- void Offset(T const & dx, T const & dy)
- {
- m_minX += dx;
- m_minY += dy;
- m_maxX += dx;
- m_maxY += dy;
- }
+ bool IsEmptyInterior() const { return m_minX >= m_maxX || m_minY >= m_maxY; }
- Point<T> LeftTop() const { return Point<T>(m_minX, m_maxY); }
- Point<T> RightTop() const { return Point<T>(m_maxX, m_maxY); }
- Point<T> RightBottom() const { return Point<T>(m_maxX, m_minY); }
- Point<T> LeftBottom() const { return Point<T>(m_minX, m_minY); }
+ void Add(m2::Point<T> const & p)
+ {
+ m_minX = std::min(p.x, m_minX);
+ m_minY = std::min(p.y, m_minY);
+ m_maxX = std::max(p.x, m_maxX);
+ m_maxY = std::max(p.y, m_maxY);
+ }
- bool IsIntersect(Rect const & r) const
- {
- return !((m_maxX < r.m_minX) || (m_minX > r.m_maxX) ||
- (m_maxY < r.m_minY) || (m_minY > r.m_maxY));
- }
+ void Add(m2::Rect<T> const & r)
+ {
+ m_minX = std::min(r.m_minX, m_minX);
+ m_minY = std::min(r.m_minY, m_minY);
+ m_maxX = std::max(r.m_maxX, m_maxX);
+ m_maxY = std::max(r.m_maxY, m_maxY);
+ }
- bool IsPointInside(Point<T> const & pt) const
- {
- return !(m_minX > pt.x || pt.x > m_maxX || m_minY > pt.y || pt.y > m_maxY);
- }
+ void Offset(m2::Point<T> const & p)
+ {
+ m_minX += p.x;
+ m_minY += p.y;
+ m_maxX += p.x;
+ m_maxY += p.y;
+ }
- bool IsRectInside(Rect<T> const & rect) const
- {
- return (IsPointInside(Point<T>(rect.minX(), rect.minY())) &&
- IsPointInside(Point<T>(rect.maxX(), rect.maxY())));
- }
+ void Offset(T const & dx, T const & dy)
+ {
+ m_minX += dx;
+ m_minY += dy;
+ m_maxX += dx;
+ m_maxY += dy;
+ }
- Point<T> Center() const { return Point<T>((m_minX + m_maxX) / 2.0, (m_minY + m_maxY) / 2.0); }
- T SizeX() const { return max(static_cast<T>(0), m_maxX - m_minX); }
- T SizeY() const { return max(static_cast<T>(0), m_maxY - m_minY); }
+ Point<T> LeftTop() const { return Point<T>(m_minX, m_maxY); }
+ Point<T> RightTop() const { return Point<T>(m_maxX, m_maxY); }
+ Point<T> RightBottom() const { return Point<T>(m_maxX, m_minY); }
+ Point<T> LeftBottom() const { return Point<T>(m_minX, m_minY); }
- void DivideByGreaterSize(Rect & r1, Rect & r2) const
- {
- if (SizeX() > SizeY())
- {
- T const pivot = (m_minX + m_maxX) / 2;
- r1 = Rect<T>(m_minX, m_minY, pivot, m_maxY);
- r2 = Rect<T>(pivot, m_minY, m_maxX, m_maxY);
- }
- else
- {
- T const pivot = (m_minY + m_maxY) / 2;
- r1 = Rect<T>(m_minX, m_minY, m_maxX, pivot);
- r2 = Rect<T>(m_minX, pivot, m_maxX, m_maxY);
- }
- }
+ bool IsIntersect(Rect const & r) const
+ {
+ return !((m_maxX < r.m_minX) || (m_minX > r.m_maxX) || (m_maxY < r.m_minY) ||
+ (m_minY > r.m_maxY));
+ }
- void SetSizes(T dx, T dy)
- {
- ASSERT_GREATER ( dx, 0, () );
- ASSERT_GREATER ( dy, 0, () );
+ bool IsPointInside(Point<T> const & pt) const
+ {
+ return !(m_minX > pt.x || pt.x > m_maxX || m_minY > pt.y || pt.y > m_maxY);
+ }
- dx /= 2;
- dy /= 2;
+ bool IsRectInside(Rect<T> const & rect) const
+ {
+ return (IsPointInside(Point<T>(rect.minX(), rect.minY())) &&
+ IsPointInside(Point<T>(rect.maxX(), rect.maxY())));
+ }
- Point<T> const c = Center();
- m_minX = c.x - dx;
- m_minY = c.y - dy;
- m_maxX = c.x + dx;
- m_maxY = c.y + dy;
- }
+ Point<T> Center() const { return Point<T>((m_minX + m_maxX) / 2.0, (m_minY + m_maxY) / 2.0); }
+ T SizeX() const { return std::max(static_cast<T>(0), m_maxX - m_minX); }
+ T SizeY() const { return std::max(static_cast<T>(0), m_maxY - m_minY); }
- void SetSizesToIncludePoint(Point<T> const & pt)
+ void DivideByGreaterSize(Rect & r1, Rect & r2) const
+ {
+ if (SizeX() > SizeY())
{
- Point<T> const c = Center();
- T const dx = my::Abs(pt.x - c.x);
- T const dy = my::Abs(pt.y - c.y);
-
- m_minX = c.x - dx;
- m_minY = c.y - dy;
- m_maxX = c.x + dx;
- m_maxY = c.y + dy;
+ T const pivot = (m_minX + m_maxX) / 2;
+ r1 = Rect<T>(m_minX, m_minY, pivot, m_maxY);
+ r2 = Rect<T>(pivot, m_minY, m_maxX, m_maxY);
}
-
- void SetCenter(m2::Point<T> const & p)
+ else
{
- Offset(p - Center());
+ T const pivot = (m_minY + m_maxY) / 2;
+ r1 = Rect<T>(m_minX, m_minY, m_maxX, pivot);
+ r2 = Rect<T>(m_minX, pivot, m_maxX, m_maxY);
}
+ }
- T minX() const { return m_minX; }
- T minY() const { return m_minY; }
- T maxX() const { return m_maxX; }
- T maxY() const { return m_maxY; }
-
- void setMinX(T minX) { m_minX = minX; }
- void setMinY(T minY) { m_minY = minY; }
- void setMaxX(T maxX) { m_maxX = maxX; }
- void setMaxY(T maxY) { m_maxY = maxY; }
+ void SetSizes(T dx, T dy)
+ {
+ ASSERT_GREATER(dx, 0, ());
+ ASSERT_GREATER(dy, 0, ());
- void Scale(T scale)
- {
- scale *= 0.5;
-
- m2::Point<T> const center = Center();
- T const halfSizeX = SizeX() * scale;
- T const halfSizeY = SizeY() * scale;
- m_minX = center.x - halfSizeX;
- m_minY = center.y - halfSizeY;
- m_maxX = center.x + halfSizeX;
- m_maxY = center.y + halfSizeY;
- }
+ dx /= 2;
+ dy /= 2;
- void Inflate(T dx, T dy)
- {
- m_minX -= dx; m_maxX += dx;
- m_minY -= dy; m_maxY += dy;
- }
+ Point<T> const c = Center();
+ m_minX = c.x - dx;
+ m_minY = c.y - dy;
+ m_maxX = c.x + dx;
+ m_maxY = c.y + dy;
+ }
- bool Intersect(m2::Rect<T> const & r)
- {
- T newMinX = max(m_minX, r.minX());
- T newMaxX = min(m_maxX, r.maxX());
+ void SetSizesToIncludePoint(Point<T> const & pt)
+ {
+ Point<T> const c = Center();
+ T const dx = my::Abs(pt.x - c.x);
+ T const dy = my::Abs(pt.y - c.y);
+
+ m_minX = c.x - dx;
+ m_minY = c.y - dy;
+ m_maxX = c.x + dx;
+ m_maxY = c.y + dy;
+ }
- if (newMinX > newMaxX)
- return false;
+ void SetCenter(m2::Point<T> const & p) { Offset(p - Center()); }
- T newMinY = max(m_minY, r.minY());
- T newMaxY = min(m_maxY, r.maxY());
+ T minX() const { return m_minX; }
+ T minY() const { return m_minY; }
+ T maxX() const { return m_maxX; }
+ T maxY() const { return m_maxY; }
- if (newMinY > newMaxY)
- return false;
+ void setMinX(T minX) { m_minX = minX; }
+ void setMinY(T minY) { m_minY = minY; }
+ void setMaxX(T maxX) { m_maxX = maxX; }
+ void setMaxY(T maxY) { m_maxY = maxY; }
- m_minX = newMinX;
- m_minY = newMinY;
- m_maxX = newMaxX;
- m_maxY = newMaxY;
+ void Scale(T scale)
+ {
+ scale *= 0.5;
+
+ m2::Point<T> const center = Center();
+ T const halfSizeX = SizeX() * scale;
+ T const halfSizeY = SizeY() * scale;
+ m_minX = center.x - halfSizeX;
+ m_minY = center.y - halfSizeY;
+ m_maxX = center.x + halfSizeX;
+ m_maxY = center.y + halfSizeY;
+ }
- return true;
- }
+ void Inflate(T dx, T dy)
+ {
+ m_minX -= dx;
+ m_maxX += dx;
+ m_minY -= dy;
+ m_maxY += dy;
+ }
- /*
- bool operator < (m2::Rect<T> const & r) const
- {
- if (m_minX != r.m_minX)
- return m_minX < r.m_minX;
- if (m_minY != r.m_minY)
- return m_minY < r.m_minY;
- if (m_maxX != r.m_maxX)
- return m_maxX < r.m_maxX;
- if (m_maxY != r.m_maxY)
- return m_maxY < r.m_maxY;
+ bool Intersect(m2::Rect<T> const & r)
+ {
+ T newMinX = std::max(m_minX, r.minX());
+ T newMaxX = std::min(m_maxX, r.maxX());
+ if (newMinX > newMaxX)
return false;
- }
- */
- bool operator == (m2::Rect<T> const & r) const
- {
- return m_minX == r.m_minX && m_minY == r.m_minY && m_maxX == r.m_maxX && m_maxY == r.m_maxY;
- }
+ T newMinY = std::max(m_minY, r.minY());
+ T newMaxY = std::min(m_maxY, r.maxY());
- bool operator != (m2::Rect<T> const & r) const
- {
- return !(*this == r);
- }
- };
-
- template <typename T>
- inline bool IsEqual(Rect<T> const & r1, Rect<T> const & r2, double epsX, double epsY)
- {
- Rect<T> r = r1;
- r.Inflate(epsX, epsY);
- if (!r.IsRectInside(r2)) return false;
+ if (newMinY > newMaxY)
+ return false;
- r = r2;
- r.Inflate(epsX, epsY);
- if (!r.IsRectInside(r1)) return false;
+ m_minX = newMinX;
+ m_minY = newMinY;
+ m_maxX = newMaxX;
+ m_maxY = newMaxY;
return true;
}
- template <typename T>
- inline bool IsEqualSize(Rect<T> const & r1, Rect<T> const & r2, double epsX, double epsY)
+ bool operator==(m2::Rect<T> const & r) const
{
- return fabs(r1.SizeX() - r2.SizeX()) < epsX && fabs(r1.SizeY() - r2.SizeY()) < epsY;
+ return m_minX == r.m_minX && m_minY == r.m_minY && m_maxX == r.m_maxX && m_maxY == r.m_maxY;
}
- template <typename T>
- inline m2::Rect<T> const Add(m2::Rect<T> const & r, m2::Point<T> const & p)
- {
- return m2::Rect<T>(
- min(p.x, r.minX()),
- min(p.y, r.minY()),
- max(p.x, r.maxX()),
- max(p.y, r.maxY())
- );
- }
+ bool operator!=(m2::Rect<T> const & r) const { return !(*this == r); }
- template <typename T>
- inline m2::Rect<T> const Add(m2::Rect<T> const & r1, m2::Rect<T> const & r2)
+private:
+ enum
{
- return m2::Rect<T>(
- min(r2.minX(), r1.minX()),
- min(r2.minY(), r1.minY()),
- max(r2.maxX(), r1.maxX()),
- max(r2.maxY(), r1.maxY())
- );
- }
+ IsSigned = std::numeric_limits<T>::is_signed
+ };
- template <typename T>
- inline m2::Rect<T> const Offset(m2::Rect<T> const & r1, m2::Point<T> const & p)
- {
- return m2::Rect<T>(
- r1.minX() + p.x,
- r1.minY() + p.y,
- r1.maxX() + p.x,
- r1.maxY() + p.y
- );
- }
+ template <class TArchive, class TPoint>
+ friend TArchive & operator<<(TArchive & ar, Rect<TPoint> const & rect);
- template <typename T>
- inline m2::Rect<T> const Inflate(m2::Rect<T> const & r, T const & dx, T const & dy)
- {
- return m2::Rect<T>(
- r.minX() - dx,
- r.minY() - dy,
- r.maxX() + dx,
- r.maxY() + dy
- );
- }
+ template <class TArchive, class TPoint>
+ friend TArchive & operator>>(TArchive & ar, Rect<TPoint> & rect);
- template <typename T>
- inline m2::Rect<T> const Inflate(m2::Rect<T> const & r, m2::Point<T> const & p)
- {
- return Inflate(r, p.x, p.y);
- }
+ T m_minX, m_minY, m_maxX, m_maxY;
+};
- template <typename T>
- inline m2::Rect<T> const Offset(m2::Rect<T> const & r1, T const & dx, T const & dy)
- {
- return m2::Rect<T>(
- r1.minX() + dx,
- r1.minY() + dy,
- r1.maxX() + dx,
- r1.maxY() + dy
- );
- }
+using RectF = Rect<float>;
+using RectD = Rect<double>;
+using RectU = Rect<unsigned>;
+using RectU32 = Rect<uint32_t>;
+using RectI = Rect<int>;
- template <typename T, typename TCollection>
- inline bool HasIntersection(m2::Rect<T> const & rect, TCollection const & geometry)
- {
- for (auto const & g : geometry)
- {
- if (rect.IsIntersect(g))
- return true;
- }
+template <typename T>
+bool IsEqual(Rect<T> const & r1, Rect<T> const & r2, double epsX, double epsY)
+{
+ Rect<T> r = r1;
+ r.Inflate(epsX, epsY);
+ if (!r.IsRectInside(r2))
return false;
- };
- template <class TArchive, class PointT>
- TArchive & operator >> (TArchive & ar, m2::Rect<PointT> & rect)
- {
- ar >> rect.m_minX;
- ar >> rect.m_minY;
- ar >> rect.m_maxX;
- ar >> rect.m_maxY;
- return ar;
- }
+ r = r2;
+ r.Inflate(epsX, epsY);
+ if (!r.IsRectInside(r1))
+ return false;
- template <class TArchive, class PointT>
- TArchive & operator << (TArchive & ar, m2::Rect<PointT> const & rect)
- {
- ar << rect.m_minX;
- ar << rect.m_minY;
- ar << rect.m_maxX;
- ar << rect.m_maxY;
- return ar;
- }
+ return true;
+}
+
+template <typename T>
+bool IsEqualSize(Rect<T> const & r1, Rect<T> const & r2, double epsX, double epsY)
+{
+ return fabs(r1.SizeX() - r2.SizeX()) < epsX && fabs(r1.SizeY() - r2.SizeY()) < epsY;
+}
+
+template <typename T>
+m2::Rect<T> const Add(m2::Rect<T> const & r, m2::Point<T> const & p)
+{
+ return m2::Rect<T>(std::min(p.x, r.minX()), std::min(p.y, r.minY()), std::max(p.x, r.maxX()),
+ std::max(p.y, r.maxY()));
+}
+
+template <typename T>
+m2::Rect<T> const Add(m2::Rect<T> const & r1, m2::Rect<T> const & r2)
+{
+ return m2::Rect<T>(std::min(r2.minX(), r1.minX()), std::min(r2.minY(), r1.minY()),
+ std::max(r2.maxX(), r1.maxX()), std::max(r2.maxY(), r1.maxY()));
+}
+
+template <typename T>
+m2::Rect<T> const Offset(m2::Rect<T> const & r1, m2::Point<T> const & p)
+{
+ return m2::Rect<T>(r1.minX() + p.x, r1.minY() + p.y, r1.maxX() + p.x, r1.maxY() + p.y);
+}
+
+template <typename T>
+m2::Rect<T> const Inflate(m2::Rect<T> const & r, T const & dx, T const & dy)
+{
+ return m2::Rect<T>(r.minX() - dx, r.minY() - dy, r.maxX() + dx, r.maxY() + dy);
+}
+
+template <typename T>
+m2::Rect<T> const Inflate(m2::Rect<T> const & r, m2::Point<T> const & p)
+{
+ return Inflate(r, p.x, p.y);
+}
- typedef Rect<float> RectF;
- typedef Rect<double> RectD;
- typedef Rect<unsigned> RectU;
- typedef Rect<uint32_t> RectU32;
- typedef Rect<int> RectI;
+template <typename T>
+m2::Rect<T> const Offset(m2::Rect<T> const & r1, T const & dx, T const & dy)
+{
+ return m2::Rect<T>(r1.minX() + dx, r1.minY() + dy, r1.maxX() + dx, r1.maxY() + dy);
+}
- template <typename T>
- inline string DebugPrint(m2::Rect<T> const & r)
+template <typename T, typename TCollection>
+bool HasIntersection(m2::Rect<T> const & rect, TCollection const & geometry)
+{
+ for (auto const & g : geometry)
{
- ostringstream out;
- out.precision(20);
- out << "m2::Rect("
- << r.minX() << ", " << r.minY() << ", " << r.maxX() << ", " << r.maxY() << ")";
- return out.str();
+ if (rect.IsIntersect(g))
+ return true;
}
+ return false;
+};
+
+template <class TArchive, class PointT>
+TArchive & operator>>(TArchive & ar, m2::Rect<PointT> & rect)
+{
+ ar >> rect.m_minX;
+ ar >> rect.m_minY;
+ ar >> rect.m_maxX;
+ ar >> rect.m_maxY;
+ return ar;
+}
+
+template <class TArchive, class PointT>
+TArchive & operator<<(TArchive & ar, m2::Rect<PointT> const & rect)
+{
+ ar << rect.m_minX;
+ ar << rect.m_minY;
+ ar << rect.m_maxX;
+ ar << rect.m_maxY;
+ return ar;
+}
+
+template <typename T>
+std::string DebugPrint(m2::Rect<T> const & r)
+{
+ std::ostringstream out;
+ out.precision(20);
+ out << "m2::Rect(" << r.minX() << ", " << r.minY() << ", " << r.maxX() << ", " << r.maxY() << ")";
+ return out.str();
}
+} // namespace m2
diff --git a/geometry/region2d.hpp b/geometry/region2d.hpp
index e7a5e0f262..5bdb252613 100644
--- a/geometry/region2d.hpp
+++ b/geometry/region2d.hpp
@@ -6,358 +6,362 @@
#include "base/math.hpp"
-#include "std/algorithm.hpp"
-#include "std/type_traits.hpp"
-#include "std/utility.hpp"
-#include "std/vector.hpp"
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+#include <vector>
namespace m2
{
- namespace detail
- {
- struct DefEqualFloat
- {
- // 1e-9 is two orders of magnitude more accurate than our OSM source data.
- static double constexpr kPrecision = 1e-9;
-
- template <class TPoint>
- bool EqualPoints(TPoint const & p1, TPoint const & p2) const
- {
- static_assert(std::is_floating_point<typename TPoint::value_type>::value, "");
+namespace detail
+{
+struct DefEqualFloat
+{
+ // 1e-9 is two orders of magnitude more accurate than our OSM source data.
+ static double constexpr kPrecision = 1e-9;
- return my::AlmostEqualAbs(p1.x, p2.x, static_cast<typename TPoint::value_type>(kPrecision)) &&
- my::AlmostEqualAbs(p1.y, p2.y, static_cast<typename TPoint::value_type>(kPrecision));
- }
- template <class TCoord>
- bool EqualZeroSquarePrecision(TCoord val) const
- {
- static_assert(std::is_floating_point<TCoord>::value, "");
+ template <typename Point>
+ bool EqualPoints(Point const & p1, Point const & p2) const
+ {
+ static_assert(std::is_floating_point<typename Point::value_type>::value, "");
- return my::AlmostEqualAbs(val, 0.0, kPrecision * kPrecision);
- }
- // Determines if value of a val lays between a p1 and a p2 values with some precision.
- inline bool IsAlmostBetween(double val, double p1, double p2) const
- {
- return (val >= p1 - kPrecision && val <= p2 + kPrecision) ||
- (val <= p1 + kPrecision && val >= p2 - kPrecision);
- }
- };
+ return my::AlmostEqualAbs(p1.x, p2.x, static_cast<typename Point::value_type>(kPrecision)) &&
+ my::AlmostEqualAbs(p1.y, p2.y, static_cast<typename Point::value_type>(kPrecision));
+ }
- struct DefEqualInt
- {
- template <class TPoint>
- bool EqualPoints(TPoint const & p1, TPoint const & p2) const
- {
- return p1 == p2;
- }
- template <class TCoord>
- bool EqualZeroSquarePrecision(TCoord val) const
- {
- return val == 0;
- }
- inline bool IsAlmostBetween(double val, double left, double right) const
- {
- return (val >= left && val <= right) ||
- (val <= left && val >= right);
- }
- };
+ template <typename TCoord>
+ bool EqualZeroSquarePrecision(TCoord val) const
+ {
+ static_assert(std::is_floating_point<TCoord>::value, "");
- template <int floating> struct TraitsType;
- template <> struct TraitsType<1>
- {
- typedef DefEqualFloat EqualType;
- typedef double BigType;
- };
- template <> struct TraitsType<0>
- {
- typedef DefEqualInt EqualType;
- typedef int64_t BigType;
- };
+ return my::AlmostEqualAbs(val, 0.0, kPrecision * kPrecision);
}
-
- template <class PointT>
- class Region
+ // Determines if value of a val lays between a p1 and a p2 values with some precision.
+ bool IsAlmostBetween(double val, double p1, double p2) const
{
- template <class TArchive, class TPoint>
- friend TArchive & operator << (TArchive & ar, Region<TPoint> const & region);
- template <class TArchive, class TPoint>
- friend TArchive & operator >> (TArchive & ar, Region<TPoint> & region);
-
- public:
- typedef PointT ValueT;
- typedef typename PointT::value_type CoordT;
-
- private:
- typedef vector<PointT> ContainerT;
- typedef detail::TraitsType<is_floating_point<CoordT>::value> TraitsT;
-
- public:
- /// @name Needed for boost region concept.
- //@{
- typedef typename ContainerT::const_iterator IteratorT;
- IteratorT Begin() const { return m_points.begin(); }
- IteratorT End() const { return m_points.end(); }
- size_t Size() const { return m_points.size(); }
- //@}
-
- public:
- Region() = default;
-
- template <class Points>
- explicit Region(Points && points) : m_points(std::forward<Points>(points))
- {
- CalcLimitRect();
- }
+ return (val >= p1 - kPrecision && val <= p2 + kPrecision) ||
+ (val <= p1 + kPrecision && val >= p2 - kPrecision);
+ }
+};
- template <class IterT>
- Region(IterT first, IterT last) : m_points(first, last)
- {
- CalcLimitRect();
- }
+struct DefEqualInt
+{
+ template <typename Point>
+ bool EqualPoints(Point const & p1, Point const & p2) const
+ {
+ return p1 == p2;
+ }
- template <class IterT>
- void Assign(IterT first, IterT last)
- {
- m_points.assign(first, last);
- CalcLimitRect();
- }
+ template <typename TCoord>
+ bool EqualZeroSquarePrecision(TCoord val) const
+ {
+ return val == 0;
+ }
- template <class IterT, class Fn>
- void AssignEx(IterT first, IterT last, Fn fn)
- {
- m_points.reserve(distance(first, last));
+ bool IsAlmostBetween(double val, double left, double right) const
+ {
+ return (val >= left && val <= right) || (val <= left && val >= right);
+ }
+};
- while (first != last)
- m_points.push_back(fn(*first++));
+template <int floating>
+struct TraitsType;
- CalcLimitRect();
- }
+template <>
+struct TraitsType<1>
+{
+ typedef DefEqualFloat EqualType;
+ typedef double BigType;
+};
- void AddPoint(PointT const & pt)
- {
- m_points.push_back(pt);
- m_rect.Add(pt);
- }
+template <>
+struct TraitsType<0>
+{
+ typedef DefEqualInt EqualType;
+ typedef int64_t BigType;
+};
+} // namespace detail
- template <class TFunctor>
- void ForEachPoint(TFunctor toDo) const
- {
- for_each(m_points.begin(), m_points.end(), toDo);
- }
+template <typename Point>
+class Region
+{
+public:
+ using ValueT = Point;
+ using CoordT = typename Point::value_type;
+ using ContainerT = std::vector<Point>;
+ using TraitsT = detail::TraitsType<std::is_floating_point<CoordT>::value>;
+
+ /// @name Needed for boost region concept.
+ //@{
+ using IteratorT = typename ContainerT::const_iterator;
+ IteratorT Begin() const { return m_points.begin(); }
+ IteratorT End() const { return m_points.end(); }
+ size_t Size() const { return m_points.size(); }
+ //@}
+
+ Region() = default;
+
+ template <typename Points>
+ explicit Region(Points && points) : m_points(std::forward<Points>(points))
+ {
+ CalcLimitRect();
+ }
- inline m2::Rect<CoordT> const & GetRect() const { return m_rect; }
- inline size_t GetPointsCount() const { return m_points.size(); }
- inline bool IsValid() const { return GetPointsCount() > 2; }
+ template <typename IterT>
+ Region(IterT first, IterT last) : m_points(first, last)
+ {
+ CalcLimitRect();
+ }
- void Swap(Region<PointT> & rhs)
- {
- m_points.swap(rhs.m_points);
- std::swap(m_rect, rhs.m_rect);
- }
+ template <typename IterT>
+ void Assign(IterT first, IterT last)
+ {
+ m_points.assign(first, last);
+ CalcLimitRect();
+ }
- ContainerT const & Data() const { return m_points; }
+ template <typename IterT, typename Fn>
+ void AssignEx(IterT first, IterT last, Fn fn)
+ {
+ m_points.reserve(distance(first, last));
- template <class TEqualF>
- static inline bool IsIntersect(CoordT const & x11, CoordT const & y11, CoordT const & x12, CoordT const & y12,
- CoordT const & x21, CoordT const & y21, CoordT const & x22, CoordT const & y22,
- TEqualF equalF, PointT & pt)
- {
- double const divider = ((y12 - y11) * (x22 - x21) - (x12 - x11) * (y22-y21));
- if (equalF.EqualZeroSquarePrecision(divider))
- return false;
- double v = ((x12 - x11) * (y21 - y11) + (y12 - y11) * (x11 - x21)) / divider;
- PointT p(x21 + (x22 - x21) * v, y21 + (y22 - y21) * v);
-
- if (!equalF.IsAlmostBetween(p.x, x11, x12))
- return false;
- if (!equalF.IsAlmostBetween(p.x, x21, x22))
- return false;
- if (!equalF.IsAlmostBetween(p.y, y11, y12))
- return false;
- if (!equalF.IsAlmostBetween(p.y, y21, y22))
- return false;
-
- pt = p;
- return true;
- }
+ while (first != last)
+ m_points.push_back(fn(*first++));
- static inline bool IsIntersect(PointT const & p1, PointT const & p2, PointT const & p3, PointT const & p4 , PointT & pt)
- {
- return IsIntersect(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, typename TraitsT::EqualType(), pt);
- }
+ CalcLimitRect();
+ }
- public:
+ void AddPoint(Point const & pt)
+ {
+ m_points.push_back(pt);
+ m_rect.Add(pt);
+ }
- /// Taken from Computational Geometry in C and modified
- template <class TEqualF>
- bool Contains(PointT const & pt, TEqualF equalF) const
- {
- if (!m_rect.IsPointInside(pt))
- return false;
+ template <typename TFunctor>
+ void ForEachPoint(TFunctor toDo) const
+ {
+ for_each(m_points.begin(), m_points.end(), toDo);
+ }
- int rCross = 0; /* number of right edge/ray crossings */
- int lCross = 0; /* number of left edge/ray crossings */
+ m2::Rect<CoordT> const & GetRect() const { return m_rect; }
+ size_t GetPointsCount() const { return m_points.size(); }
+ bool IsValid() const { return GetPointsCount() > 2; }
- size_t const numPoints = m_points.size();
+ void Swap(Region<Point> & rhs)
+ {
+ m_points.swap(rhs.m_points);
+ std::swap(m_rect, rhs.m_rect);
+ }
- typedef typename TraitsT::BigType BigCoordT;
- typedef Point<BigCoordT> BigPointT;
+ ContainerT const & Data() const { return m_points; }
- BigPointT prev = BigPointT(m_points[numPoints - 1]) - BigPointT(pt);
- for (size_t i = 0; i < numPoints; ++i)
- {
- if (equalF.EqualPoints(m_points[i], pt))
- return true;
+ template <typename TEqualF>
+ static bool IsIntersect(CoordT const & x11, CoordT const & y11, CoordT const & x12,
+ CoordT const & y12, CoordT const & x21, CoordT const & y21,
+ CoordT const & x22, CoordT const & y22, TEqualF equalF, Point & pt)
+ {
+ double const divider = ((y12 - y11) * (x22 - x21) - (x12 - x11) * (y22 - y21));
+ if (equalF.EqualZeroSquarePrecision(divider))
+ return false;
+ double v = ((x12 - x11) * (y21 - y11) + (y12 - y11) * (x11 - x21)) / divider;
+ Point p(x21 + (x22 - x21) * v, y21 + (y22 - y21) * v);
- BigPointT const curr = BigPointT(m_points[i]) - BigPointT(pt);
+ if (!equalF.IsAlmostBetween(p.x, x11, x12))
+ return false;
+ if (!equalF.IsAlmostBetween(p.x, x21, x22))
+ return false;
+ if (!equalF.IsAlmostBetween(p.y, y11, y12))
+ return false;
+ if (!equalF.IsAlmostBetween(p.y, y21, y22))
+ return false;
- bool const rCheck = ((curr.y > 0) != (prev.y > 0));
- bool const lCheck = ((curr.y < 0) != (prev.y < 0));
+ pt = p;
+ return true;
+ }
- if (rCheck || lCheck)
- {
- ASSERT_NOT_EQUAL ( curr.y, prev.y, () );
-
- BigCoordT const delta = prev.y - curr.y;
- BigCoordT const cp = CrossProduct(curr, prev);
-
- // Squared precision is needed here because of comparison between cross product of two
- // vectors and zero. It's impossible to compare them relatively, so they're compared
- // absolutely, and, as cross product is proportional to product of lengths of both
- // operands precision must be squared too.
- if (!equalF.EqualZeroSquarePrecision(cp))
- {
- bool const PrevGreaterCurr = delta > 0.0;
-
- if (rCheck && ((cp > 0) == PrevGreaterCurr)) ++rCross;
- if (lCheck && ((cp > 0) != PrevGreaterCurr)) ++lCross;
- }
- }
+ static bool IsIntersect(Point const & p1, Point const & p2, Point const & p3, Point const & p4,
+ Point & pt)
+ {
+ return IsIntersect(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y,
+ typename TraitsT::EqualType(), pt);
+ }
- prev = curr;
- }
+ /// Taken from Computational Geometry in C and modified
+ template <typename TEqualF>
+ bool Contains(Point const & pt, TEqualF equalF) const
+ {
+ if (!m_rect.IsPointInside(pt))
+ return false;
- /* q on the edge if left and right cross are not the same parity. */
- if ((rCross & 1) != (lCross & 1))
- return true; // on the edge
+ int rCross = 0; /* number of right edge/ray crossings */
+ int lCross = 0; /* number of left edge/ray crossings */
- /* q inside if an odd number of crossings. */
- if (rCross & 1)
- return true; // inside
- else
- return false; // outside
- }
+ size_t const numPoints = m_points.size();
- bool Contains(PointT const & pt) const
- {
- return Contains(pt, typename TraitsT::EqualType());
- }
+ using BigCoordT = typename TraitsT::BigType;
+ using BigPoint = ::m2::Point<BigCoordT>;
- /// Finds point of intersection with the section.
- bool FindIntersection(PointT const & point1, PointT const & point2, PointT & result) const
+ BigPoint prev = BigPoint(m_points[numPoints - 1]) - BigPoint(pt);
+ for (size_t i = 0; i < numPoints; ++i)
{
- if (m_points.empty())
- return false;
- PointT const * prev = &m_points.back();
- for (PointT const & curr : m_points)
- {
- if (IsIntersect(point1, point2, *prev, curr, result))
- return true;
- prev = &curr;
- }
- return false;
- }
+ if (equalF.EqualPoints(m_points[i], pt))
+ return true;
- /// Slow check that point lies at the border.
- template <class TEqualF>
- bool AtBorder(PointT const & pt, double const delta, TEqualF equalF) const
- {
- if (!m_rect.IsPointInside(pt))
- return false;
+ BigPoint const curr = BigPoint(m_points[i]) - BigPoint(pt);
- const double squareDelta = delta*delta;
- size_t const numPoints = m_points.size();
+ bool const rCheck = ((curr.y > 0) != (prev.y > 0));
+ bool const lCheck = ((curr.y < 0) != (prev.y < 0));
- PointT prev = m_points[numPoints - 1];
- DistanceToLineSquare<PointT> distance;
- for (size_t i = 0; i < numPoints; ++i)
+ if (rCheck || lCheck)
{
- PointT const curr = m_points[i];
+ ASSERT_NOT_EQUAL(curr.y, prev.y, ());
- // Borders often have same points with ways
- if (equalF.EqualPoints(m_points[i], pt))
- return true;
+ BigCoordT const delta = prev.y - curr.y;
+ BigCoordT const cp = CrossProduct(curr, prev);
- distance.SetBounds(prev, curr);
- if (distance(pt) < squareDelta)
- return true;
+ // Squared precision is needed here because of comparison between cross product of two
+ // std::vectors and zero. It's impossible to compare them relatively, so they're compared
+ // absolutely, and, as cross product is proportional to product of lengths of both
+ // operands precision must be squared too.
+ if (!equalF.EqualZeroSquarePrecision(cp))
+ {
+ bool const PrevGreaterCurr = delta > 0.0;
- prev = curr;
+ if (rCheck && ((cp > 0) == PrevGreaterCurr))
+ ++rCross;
+ if (lCheck && ((cp > 0) != PrevGreaterCurr))
+ ++lCross;
+ }
}
- return false; // Point lies outside the border.
+ prev = curr;
}
- bool AtBorder(PointT const & pt, double const delta) const
+ /* q on the edge if left and right cross are not the same parity. */
+ if ((rCross & 1) != (lCross & 1))
+ return true; // on the edge
+
+ /* q inside if an odd number of crossings. */
+ if (rCross & 1)
+ return true; // inside
+ else
+ return false; // outside
+ }
+
+ bool Contains(Point const & pt) const { return Contains(pt, typename TraitsT::EqualType()); }
+
+ /// Finds point of intersection with the section.
+ bool FindIntersection(Point const & point1, Point const & point2, Point & result) const
+ {
+ if (m_points.empty())
+ return false;
+ Point const * prev = &m_points.back();
+ for (Point const & curr : m_points)
{
- return AtBorder(pt, delta, typename TraitsT::EqualType());
+ if (IsIntersect(point1, point2, *prev, curr, result))
+ return true;
+ prev = &curr;
}
+ return false;
+ }
- private:
- void CalcLimitRect()
+ /// Slow check that point lies at the border.
+ template <typename TEqualF>
+ bool AtBorder(Point const & pt, double const delta, TEqualF equalF) const
+ {
+ if (!m_rect.IsPointInside(pt))
+ return false;
+
+ const double squareDelta = delta * delta;
+ size_t const numPoints = m_points.size();
+
+ Point prev = m_points[numPoints - 1];
+ DistanceToLineSquare<Point> distance;
+ for (size_t i = 0; i < numPoints; ++i)
{
- m_rect.MakeEmpty();
- for (size_t i = 0; i < m_points.size(); ++i)
- m_rect.Add(m_points[i]);
- }
+ Point const curr = m_points[i];
- ContainerT m_points;
- m2::Rect<CoordT> m_rect;
+ // Borders often have same points with ways
+ if (equalF.EqualPoints(m_points[i], pt))
+ return true;
- template <class T> friend string DebugPrint(Region<T> const &);
- };
+ distance.SetBounds(prev, curr);
+ if (distance(pt) < squareDelta)
+ return true;
- template <class PointT>
- void swap(Region<PointT> & r1, Region<PointT> & r2)
- {
- r1.Swap(r2);
- }
+ prev = curr;
+ }
- template <class TArchive, class PointT>
- TArchive & operator >> (TArchive & ar, Region<PointT> & region)
- {
- ar >> region.m_rect;
- ar >> region.m_points;
- return ar;
+ return false; // Point lies outside the border.
}
- template <class TArchive, class PointT>
- TArchive & operator << (TArchive & ar, Region<PointT> const & region)
+ bool AtBorder(Point const & pt, double const delta) const
{
- ar << region.m_rect;
- ar << region.m_points;
- return ar;
+ return AtBorder(pt, delta, typename TraitsT::EqualType());
}
- template <class PointT>
- inline string DebugPrint(Region<PointT> const & r)
+private:
+ template <typename Archive, typename Pt>
+ friend Archive & operator<<(Archive & ar, Region<Pt> const & region);
+
+ template <typename Archive, typename Pt>
+ friend Archive & operator>>(Archive & ar, Region<Pt> & region);
+
+ template <typename T>
+ friend std::string DebugPrint(Region<T> const &);
+
+ void CalcLimitRect()
{
- return (DebugPrint(r.m_rect) + ::DebugPrint(r.m_points));
+ m_rect.MakeEmpty();
+ for (size_t i = 0; i < m_points.size(); ++i)
+ m_rect.Add(m_points[i]);
}
- template <class Point>
- bool RegionsContain(vector<Region<Point>> const & regions, Point const & point)
- {
- for (auto const & region : regions)
- {
- if (region.Contains(point))
- return true;
- }
+ ContainerT m_points;
+ m2::Rect<CoordT> m_rect;
+};
- return false;
+template <typename Point>
+void swap(Region<Point> & r1, Region<Point> & r2)
+{
+ r1.Swap(r2);
+}
+
+template <typename Archive, typename Point>
+Archive & operator>>(Archive & ar, Region<Point> & region)
+{
+ ar >> region.m_rect;
+ ar >> region.m_points;
+ return ar;
+}
+
+template <typename Archive, typename Point>
+Archive & operator<<(Archive & ar, Region<Point> const & region)
+{
+ ar << region.m_rect;
+ ar << region.m_points;
+ return ar;
+}
+
+template <typename Point>
+std::string DebugPrint(Region<Point> const & r)
+{
+ return (DebugPrint(r.m_rect) + ::DebugPrint(r.m_points));
+}
+
+template <typename Point>
+bool RegionsContain(std::vector<Region<Point>> const & regions, Point const & point)
+{
+ for (auto const & region : regions)
+ {
+ if (region.Contains(point))
+ return true;
}
- typedef Region<m2::PointD> RegionD;
- typedef Region<m2::PointI> RegionI;
- typedef Region<m2::PointU> RegionU;
+ return false;
}
+
+using RegionD = Region<m2::PointD>;
+using RegionI = Region<m2::PointI>;
+using RegionU = Region<m2::PointU>;
+} // namespace m2
diff --git a/geometry/robust_orientation.cpp b/geometry/robust_orientation.cpp
index abf07fc5fc..37eae2e101 100644
--- a/geometry/robust_orientation.cpp
+++ b/geometry/robust_orientation.cpp
@@ -2,10 +2,9 @@
#include "base/macros.hpp"
-#include "std/algorithm.hpp"
+#include <algorithm>
-extern "C"
-{
+extern "C" {
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconditional-uninitialized"
@@ -16,62 +15,61 @@ extern "C"
#endif
}
+using namespace std;
-namespace m2 { namespace robust
+namespace m2
{
- bool Init()
- {
- exactinit();
- return true;
- }
-
- double OrientedS(PointD const & p1, PointD const & p2, PointD const & p)
- {
- static bool res = Init();
- ASSERT_EQUAL ( res, true, () );
- UNUSED_VALUE(res);
+namespace robust
+{
+bool Init()
+{
+ exactinit();
+ return true;
+}
- double a[] = { p1.x, p1.y };
- double b[] = { p2.x, p2.y };
- double c[] = { p.x, p.y };
+double OrientedS(PointD const & p1, PointD const & p2, PointD const & p)
+{
+ static bool res = Init();
+ ASSERT_EQUAL(res, true, ());
+ UNUSED_VALUE(res);
- return orient2d(a, b, c);
- }
+ double a[] = {p1.x, p1.y};
+ double b[] = {p2.x, p2.y};
+ double c[] = {p.x, p.y};
- bool IsSegmentInCone(PointD const & v, PointD const & v1,
- PointD const & vPrev, PointD const & vNext)
- {
- double const cpLR = OrientedS(vPrev, vNext, v);
+ return orient2d(a, b, c);
+}
- if (cpLR == 0.0)
- {
- // Points vPrev, v, vNext placed on one line;
- // use property that polygon has CCW orientation.
- return OrientedS(vPrev, vNext, v1) > 0.0;
- }
+bool IsSegmentInCone(PointD const & v, PointD const & v1, PointD const & vPrev,
+ PointD const & vNext)
+{
+ double const cpLR = OrientedS(vPrev, vNext, v);
- if (cpLR < 0.0)
- {
- // vertex is concave
- return OrientedS(v, vPrev, v1) < 0.0 && OrientedS(v, vNext, v1) > 0.0;
- }
- else
- {
- // vertex is convex
- return OrientedS(v, vPrev, v1) < 0.0 || OrientedS(v, vNext, v1) > 0.0;
- }
+ if (cpLR == 0.0)
+ {
+ // Points vPrev, v, vNext placed on one line;
+ // use property that polygon has CCW orientation.
+ return OrientedS(vPrev, vNext, v1) > 0.0;
}
- bool SegmentsIntersect(PointD const & a, PointD const & b,
- PointD const & c, PointD const & d)
+ if (cpLR < 0.0)
{
- return
- max(a.x, b.x) >= min(c.x, d.x) &&
- min(a.x, b.x) <= max(c.x, d.x) &&
- max(a.y, b.y) >= min(c.y, d.y) &&
- min(a.y, b.y) <= max(c.y, d.y) &&
- OrientedS(a, b, c) * OrientedS(a, b, d) <= 0.0 &&
- OrientedS(c, d, a) * OrientedS(c, d, b) <= 0.0;
+ // vertex is concave
+ return OrientedS(v, vPrev, v1) < 0.0 && OrientedS(v, vNext, v1) > 0.0;
+ }
+ else
+ {
+ // vertex is convex
+ return OrientedS(v, vPrev, v1) < 0.0 || OrientedS(v, vNext, v1) > 0.0;
}
}
+
+bool SegmentsIntersect(PointD const & a, PointD const & b, PointD const & c, PointD const & d)
+{
+ return max(a.x, b.x) >= min(c.x, d.x) && min(a.x, b.x) <= max(c.x, d.x) &&
+ max(a.y, b.y) >= min(c.y, d.y) && min(a.y, b.y) <= max(c.y, d.y) &&
+ OrientedS(a, b, c) * OrientedS(a, b, d) <= 0.0 &&
+ OrientedS(c, d, a) * OrientedS(c, d, b) <= 0.0;
}
+} // namespace robust
+} // namespace m2
diff --git a/geometry/robust_orientation.hpp b/geometry/robust_orientation.hpp
index 5a9a6ee21e..3466ef9a0a 100644
--- a/geometry/robust_orientation.hpp
+++ b/geometry/robust_orientation.hpp
@@ -4,128 +4,139 @@
#include "base/stl_add.hpp"
-#include "std/algorithm.hpp"
+#include <algorithm>
+#include <iterator>
-
-namespace m2 { namespace robust
+namespace m2
+{
+namespace robust
{
- bool Init();
+bool Init();
- /// @return > 0, (p1, p2, p) - is CCW (left oriented)
- /// < 0, (p1, p2, p) - is CW (right oriented)
- /// Same as CrossProduct(p1 - p, p2 - p), but uses robust calculations.
- double OrientedS(PointD const & p1, PointD const & p2, PointD const & p);
+/// @return > 0, (p1, p2, p) - is CCW (left oriented)
+/// < 0, (p1, p2, p) - is CW (right oriented)
+/// Same as CrossProduct(p1 - p, p2 - p), but uses robust calculations.
+double OrientedS(PointD const & p1, PointD const & p2, PointD const & p);
- /// Is segment (v, v1) in cone (vPrev, v, vNext)?
- /// @precondition (vPrev, v, vNext) is CCW.
- bool IsSegmentInCone(PointD const & v, PointD const & v1,
- PointD const & vPrev, PointD const & vNext);
+/// Is segment (v, v1) in cone (vPrev, v, vNext)?
+/// @precondition (vPrev, v, vNext) is CCW.
+bool IsSegmentInCone(PointD const & v, PointD const & v1, PointD const & vPrev,
+ PointD const & vNext);
- bool SegmentsIntersect(PointD const & p1, PointD const & p2,
- PointD const & p3, PointD const & p4);
+bool SegmentsIntersect(PointD const & p1, PointD const & p2, PointD const & p3, PointD const & p4);
- template <typename T> bool Between(T a, T b, T c)
- {
- return min(a, b) <= c && c <= max(a, b);
- }
+template <typename T>
+bool Between(T a, T b, T c)
+{
+ return std::min(a, b) <= c && c <= std::max(a, b);
+}
- template <class PointT> bool IsInSection(PointT const & p1, PointT const & p2, PointT const & p)
- {
- return Between(p1.x, p2.x, p.x) && Between(p1.y, p2.y, p.y);
- }
+template <class PointT>
+bool IsInSection(PointT const & p1, PointT const & p2, PointT const & p)
+{
+ return Between(p1.x, p2.x, p.x) && Between(p1.y, p2.y, p.y);
+}
- template <typename IterT>
- bool CheckPolygonSelfIntersections(IterT beg, IterT end)
- {
- IterT last = end;
- --last;
+template <typename IterT>
+bool CheckPolygonSelfIntersections(IterT beg, IterT end)
+{
+ IterT last = end;
+ --last;
- for (IterT i = beg; i != last; ++i)
- for (IterT j = i; j != end; ++j)
+ for (IterT i = beg; i != last; ++i)
+ {
+ for (IterT j = i; j != end; ++j)
+ {
+ // do not check intersection of neibour segments
+ if (std::distance(i, j) <= 1 || (i == beg && j == last))
+ continue;
+
+ IterT ii = NextIterInCycle(i, beg, end);
+ IterT jj = NextIterInCycle(j, beg, end);
+ PointD a = *i, b = *ii, c = *j, d = *jj;
+
+ // check for rect intersection
+ if (std::max(a.x, b.x) < std::min(c.x, d.x) || std::min(a.x, b.x) > std::max(c.x, d.x) ||
+ std::max(a.y, b.y) < std::min(c.y, d.y) || std::min(a.y, b.y) > std::max(c.y, d.y))
{
- // do not check intersection of neibour segments
- if (distance(i, j) <= 1 || (i == beg && j == last))
- continue;
-
- IterT ii = NextIterInCycle(i, beg, end);
- IterT jj = NextIterInCycle(j, beg, end);
- PointD a = *i, b = *ii, c = *j, d = *jj;
-
- // check for rect intersection
- if (max(a.x, b.x) < min(c.x, d.x) ||
- min(a.x, b.x) > max(c.x, d.x) ||
- max(a.y, b.y) < min(c.y, d.y) ||
- min(a.y, b.y) > max(c.y, d.y))
- {
- continue;
- }
-
- double const s1 = OrientedS(a, b, c);
- double const s2 = OrientedS(a, b, d);
- double const s3 = OrientedS(c, d, a);
- double const s4 = OrientedS(c, d, b);
+ continue;
+ }
- // check if sections have any intersection
- if (s1 * s2 > 0.0 || s3 * s4 > 0.0)
- continue;
+ double const s1 = OrientedS(a, b, c);
+ double const s2 = OrientedS(a, b, d);
+ double const s3 = OrientedS(c, d, a);
+ double const s4 = OrientedS(c, d, b);
- // Common principle if any point lay exactly on section, check 2 variants:
- // - касание (><) - don't return as intersection;
- // - 'X'-crossing - return as intersection;
- // 'X'-crossing defines when points lay in different cones.
+ // check if sections have any intersection
+ if (s1 * s2 > 0.0 || s3 * s4 > 0.0)
+ continue;
- if (s1 == 0.0 && IsInSection(a, b, c))
- {
- PointD const prev = *PrevIterInCycle(j, beg, end);
+ // Common principle if any point lay exactly on section, check 2 variants:
+ // - касание (><) - don't return as intersection;
+ // - 'X'-crossing - return as intersection;
+ // 'X'-crossing defines when points lay in different cones.
- PointD test[] = { a, b };
- if (a == c) test[0] = *PrevIterInCycle(i, beg, end);
- if (b == c) test[1] = *NextIterInCycle(ii, beg, end);
+ if (s1 == 0.0 && IsInSection(a, b, c))
+ {
+ PointD const prev = *PrevIterInCycle(j, beg, end);
- if (IsSegmentInCone(c, test[0], prev, d) == IsSegmentInCone(c, test[1], prev, d))
- continue;
- }
+ PointD test[] = {a, b};
+ if (a == c)
+ test[0] = *PrevIterInCycle(i, beg, end);
+ if (b == c)
+ test[1] = *NextIterInCycle(ii, beg, end);
- if (s2 == 0.0 && IsInSection(a, b, d))
- {
- PointD const next = *NextIterInCycle(jj, beg, end);
+ if (IsSegmentInCone(c, test[0], prev, d) == IsSegmentInCone(c, test[1], prev, d))
+ continue;
+ }
- PointD test[] = { a, b };
- if (a == d) test[0] = *PrevIterInCycle(i, beg, end);
- if (b == d) test[1] = *NextIterInCycle(ii, beg, end);
+ if (s2 == 0.0 && IsInSection(a, b, d))
+ {
+ PointD const next = *NextIterInCycle(jj, beg, end);
- if (IsSegmentInCone(d, test[0], c, next) == IsSegmentInCone(d, test[1], c, next))
- continue;
- }
+ PointD test[] = {a, b};
+ if (a == d)
+ test[0] = *PrevIterInCycle(i, beg, end);
+ if (b == d)
+ test[1] = *NextIterInCycle(ii, beg, end);
- if (s3 == 0.0 && IsInSection(c, d, a))
- {
- PointD const prev = *PrevIterInCycle(i, beg, end);
+ if (IsSegmentInCone(d, test[0], c, next) == IsSegmentInCone(d, test[1], c, next))
+ continue;
+ }
- PointD test[] = { c, d };
- if (c == a) test[0] = *PrevIterInCycle(j, beg, end);
- if (d == a) test[1] = *NextIterInCycle(jj, beg, end);
+ if (s3 == 0.0 && IsInSection(c, d, a))
+ {
+ PointD const prev = *PrevIterInCycle(i, beg, end);
- if (IsSegmentInCone(a, test[0], prev, b) == IsSegmentInCone(a, test[1], prev, b))
- continue;
- }
+ PointD test[] = {c, d};
+ if (c == a)
+ test[0] = *PrevIterInCycle(j, beg, end);
+ if (d == a)
+ test[1] = *NextIterInCycle(jj, beg, end);
- if (s4 == 0.0 && IsInSection(c, d, b))
- {
- PointD const next = *NextIterInCycle(ii, beg, end);
+ if (IsSegmentInCone(a, test[0], prev, b) == IsSegmentInCone(a, test[1], prev, b))
+ continue;
+ }
- PointD test[] = { c, d };
- if (c == b) test[0] = *PrevIterInCycle(j, beg, end);
- if (d == b) test[1] = *NextIterInCycle(jj, beg, end);
+ if (s4 == 0.0 && IsInSection(c, d, b))
+ {
+ PointD const next = *NextIterInCycle(ii, beg, end);
- if (IsSegmentInCone(b, test[0], a, next) == IsSegmentInCone(b, test[1], a, next))
- continue;
- }
+ PointD test[] = {c, d};
+ if (c == b)
+ test[0] = *PrevIterInCycle(j, beg, end);
+ if (d == b)
+ test[1] = *NextIterInCycle(jj, beg, end);
- return true;
+ if (IsSegmentInCone(b, test[0], a, next) == IsSegmentInCone(b, test[1], a, next))
+ continue;
}
- return false;
+ return true;
+ }
}
+
+ return false;
}
-}
+} // namespace robust
+} // namespace m2
diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp
index 4d27415a2e..fabf1d5b56 100644
--- a/geometry/screenbase.cpp
+++ b/geometry/screenbase.cpp
@@ -1,11 +1,13 @@
#include "geometry/screenbase.hpp"
-#include "geometry/transformations.hpp"
#include "geometry/angles.hpp"
+#include "geometry/transformations.hpp"
#include "base/assert.hpp"
#include "base/logging.hpp"
-#include "std/cmath.hpp"
+#include <cmath>
+
+using namespace std;
double constexpr kPerspectiveAngleFOV = math::pi / 3.0;
double constexpr kMaxPerspectiveAngle1 = math::pi4;
@@ -15,22 +17,22 @@ double constexpr kStartPerspectiveScale1 = 1.7e-5;
double constexpr kEndPerspectiveScale1 = 0.3e-5;
double constexpr kEndPerspectiveScale2 = 0.13e-5;
-ScreenBase::ScreenBase() :
- m_ViewportRect(0, 0, 640, 480),
- m_PixelRect(m_ViewportRect),
- m_Scale(0.1),
- m_Angle(0.0),
- m_Org(320, 240),
- m_3dFOV(kPerspectiveAngleFOV),
- m_3dNearZ(0.001),
- m_3dFarZ(0.0),
- m_3dAngleX(0.0),
- m_3dMaxAngleX(0.0),
- m_3dScale(1.0),
- m_isPerspective(false),
- m_isAutoPerspective(false),
- m_GlobalRect(m_Org, ang::AngleD(0), m2::RectD(-320, -240, 320, 240)),
- m_ClipRect(m2::RectD(0, 0, 640, 480))
+ScreenBase::ScreenBase()
+ : m_ViewportRect(0, 0, 640, 480)
+ , m_PixelRect(m_ViewportRect)
+ , m_Scale(0.1)
+ , m_Angle(0.0)
+ , m_Org(320, 240)
+ , m_3dFOV(kPerspectiveAngleFOV)
+ , m_3dNearZ(0.001)
+ , m_3dFarZ(0.0)
+ , m_3dAngleX(0.0)
+ , m_3dMaxAngleX(0.0)
+ , m_3dScale(1.0)
+ , m_isPerspective(false)
+ , m_GlobalRect(m_Org, ang::AngleD(0), m2::RectD(-320, -240, 320, 240))
+ , m_ClipRect(m2::RectD(0, 0, 640, 480))
+ , m_isAutoPerspective(false)
{
m_GtoP = math::Identity<double, 3>();
m_PtoG = math::Identity<double, 3>();
@@ -42,10 +44,8 @@ ScreenBase::ScreenBase(m2::RectI const & pxRect, m2::AnyRectD const & glbRect)
SetFromRect(glbRect);
}
-ScreenBase::ScreenBase(ScreenBase const & s,
- m2::PointD const & org, double scale, double angle)
- : m_ViewportRect(s.m_ViewportRect),
- m_Scale(scale), m_Angle(angle), m_Org(org)
+ScreenBase::ScreenBase(ScreenBase const & s, m2::PointD const & org, double scale, double angle)
+ : m_ViewportRect(s.m_ViewportRect), m_Scale(scale), m_Angle(angle), m_Org(org)
{
UpdateDependentParameters();
}
@@ -54,25 +54,17 @@ void ScreenBase::UpdateDependentParameters()
{
m_PixelRect = CalculatePixelRect(m_Scale);
- m_PtoG = math::Shift( /// 5. shifting on (E0, N0)
- math::Rotate( /// 4. rotating on the screen angle
- math::Scale( /// 3. scaling to translate pixel sizes to global
- math::Scale( /// 2. swapping the Y axis??? why??? supposed to be a rotation on -pi / 2 here.
- math::Shift( /// 1. shifting for the pixel center to become (0, 0)
- math::Identity<double, 3>(),
- - m_PixelRect.Center()
- ),
- 1,
- -1
- ),
- m_Scale,
- m_Scale
- ),
- m_Angle.cos(),
- m_Angle.sin()
- ),
- m_Org
- );
+ m_PtoG = math::Shift( /// 5. shifting on (E0, N0)
+ math::Rotate( /// 4. rotating on the screen angle
+ math::Scale( /// 3. scaling to translate pixel sizes to global
+ math::Scale( /// 2. swapping the Y axis??? why??? supposed to be a rotation on -pi /
+ /// 2 here.
+ math::Shift( /// 1. shifting for the pixel center to become (0, 0)
+ math::Identity<double, 3>(), -m_PixelRect.Center()),
+ 1, -1),
+ m_Scale, m_Scale),
+ m_Angle.cos(), m_Angle.sin()),
+ m_Org);
m_GtoP = math::Inverse(m_PtoG);
@@ -102,13 +94,15 @@ double ScreenBase::CalculateAutoPerspectiveAngle(double scale)
if (scale > kEndPerspectiveScale1)
{
- double const k = (kStartPerspectiveScale1 - scale) / (kStartPerspectiveScale1 - kEndPerspectiveScale1);
+ double const k =
+ (kStartPerspectiveScale1 - scale) / (kStartPerspectiveScale1 - kEndPerspectiveScale1);
return kMaxPerspectiveAngle1 * k;
}
if (scale > kEndPerspectiveScale2)
{
- double const k = (kEndPerspectiveScale1 - scale) / (kEndPerspectiveScale1 - kEndPerspectiveScale2);
+ double const k =
+ (kEndPerspectiveScale1 - scale) / (kEndPerspectiveScale1 - kEndPerspectiveScale2);
return kMaxPerspectiveAngle1 + (kMaxPerspectiveAngle2 - kMaxPerspectiveAngle1) * k;
}
@@ -116,10 +110,7 @@ double ScreenBase::CalculateAutoPerspectiveAngle(double scale)
}
// static
-double ScreenBase::GetStartPerspectiveScale()
-{
- return kStartPerspectiveScale1;
-}
+double ScreenBase::GetStartPerspectiveScale() { return kStartPerspectiveScale1; }
double ScreenBase::CalculatePerspectiveAngle(double scale) const
{
@@ -147,10 +138,7 @@ void ScreenBase::SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & px
UpdateDependentParameters();
}
-void ScreenBase::SetFromRect(m2::AnyRectD const & glbRect)
-{
- SetFromRects(glbRect, m_PixelRect);
-}
+void ScreenBase::SetFromRect(m2::AnyRectD const & glbRect) { SetFromRects(glbRect, m_PixelRect); }
void ScreenBase::SetFromParams(m2::PointD const & org, double angle, double scale)
{
@@ -166,7 +154,7 @@ void ScreenBase::MatchGandP(m2::PointD const & g, m2::PointD const & p)
SetOrg(m_Org - g_current + g);
}
-void ScreenBase::MatchGandP3d(m2::PointD const & g, m2::PointD const &p3d)
+void ScreenBase::MatchGandP3d(m2::PointD const & g, m2::PointD const & p3d)
{
m2::PointD g_current = PtoG(P3dtoP(p3d));
SetOrg(m_Org - g_current + g);
@@ -208,10 +196,7 @@ void ScreenBase::OnSize(m2::RectI const & r)
UpdateDependentParameters();
}
-void ScreenBase::OnSize(int x0, int y0, int w, int h)
-{
- OnSize(m2::RectI(x0, y0, x0 + w, y0 + h));
-}
+void ScreenBase::OnSize(int x0, int y0, int w, int h) { OnSize(m2::RectI(x0, y0, x0 + w, y0 + h)); }
void ScreenBase::SetScale(double scale)
{
@@ -225,38 +210,22 @@ void ScreenBase::SetAngle(double angle)
UpdateDependentParameters();
}
-int ScreenBase::GetWidth() const
-{
- return my::rounds(m_PixelRect.SizeX());
-}
+int ScreenBase::GetWidth() const { return my::rounds(m_PixelRect.SizeX()); }
-int ScreenBase::GetHeight() const
-{
- return my::rounds(m_PixelRect.SizeY());
-}
+int ScreenBase::GetHeight() const { return my::rounds(m_PixelRect.SizeY()); }
-ScreenBase::MatrixT const
-ScreenBase::CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2,
- m2::PointD const & newPt1, m2::PointD const & newPt2,
- bool allowRotate)
+ScreenBase::MatrixT const ScreenBase::CalcTransform(m2::PointD const & oldPt1,
+ m2::PointD const & oldPt2,
+ m2::PointD const & newPt1,
+ m2::PointD const & newPt2, bool allowRotate)
{
double const s = newPt1.Length(newPt2) / oldPt1.Length(oldPt2);
double const a = allowRotate ? ang::AngleTo(newPt1, newPt2) - ang::AngleTo(oldPt1, oldPt2) : 0.0;
- MatrixT m =
- math::Shift(
- math::Scale(
- math::Rotate(
- math::Shift(
- math::Identity<double, 3>(),
- -oldPt1.x, -oldPt1.y
- ),
- a
- ),
- s, s
- ),
- newPt1.x, newPt1.y
- );
+ MatrixT m = math::Shift(
+ math::Scale(math::Rotate(math::Shift(math::Identity<double, 3>(), -oldPt1.x, -oldPt1.y), a),
+ s, s),
+ newPt1.x, newPt1.y);
return m;
}
@@ -296,7 +265,7 @@ void ScreenBase::GetTouchRect(m2::PointD const & pixPoint, double pixRadius,
void ScreenBase::GetTouchRect(m2::PointD const & pixPoint, double const pxWidth,
double const pxHeight, m2::AnyRectD & glbRect) const
{
- double const width = pxWidth * m_Scale;
+ double const width = pxWidth * m_Scale;
double const height = pxHeight * m_Scale;
glbRect = m2::AnyRectD(PtoG(pixPoint), m_Angle, m2::RectD(-width, -height, width, height));
}
@@ -309,17 +278,18 @@ bool IsPanningAndRotate(ScreenBase const & s1, ScreenBase const & s2)
m2::PointD c1 = r1.Center();
m2::PointD c2 = r2.Center();
- m2::PointD globPt(c1.x - r1.minX(),
- c1.y - r1.minY());
+ m2::PointD globPt(c1.x - r1.minX(), c1.y - r1.minY());
- m2::PointD p1 = s1.GtoP(s1.GlobalRect().ConvertFrom(c1)) - s1.GtoP(s1.GlobalRect().ConvertFrom(c1 + globPt));
- m2::PointD p2 = s2.GtoP(s2.GlobalRect().ConvertFrom(c2)) - s2.GtoP(s2.GlobalRect().ConvertFrom(c2 + globPt));
+ m2::PointD p1 =
+ s1.GtoP(s1.GlobalRect().ConvertFrom(c1)) - s1.GtoP(s1.GlobalRect().ConvertFrom(c1 + globPt));
+ m2::PointD p2 =
+ s2.GtoP(s2.GlobalRect().ConvertFrom(c2)) - s2.GtoP(s2.GlobalRect().ConvertFrom(c2 + globPt));
return p1.EqualDxDy(p2, 0.00001);
}
-void ScreenBase::ExtractGtoPParams(MatrixT const & m,
- double & a, double & s, double & dx, double & dy)
+void ScreenBase::ExtractGtoPParams(MatrixT const & m, double & a, double & s, double & dx,
+ double & dy)
{
s = sqrt(m(0, 0) * m(0, 0) + m(0, 1) * m(0, 1));
@@ -336,7 +306,8 @@ double ScreenBase::CalculateScale3d(double rotationAngle) const
// Ratio of the expanded plane's size to the original size.
double const y3dScale = cos(rotationAngle) + sin(rotationAngle) * tan(halfFOV + rotationAngle);
- double const x3dScale = 1.0 + 2 * sin(rotationAngle) * cos(halfFOV) / (cameraZ * cos(halfFOV + rotationAngle));
+ double const x3dScale =
+ 1.0 + 2 * sin(rotationAngle) * cos(halfFOV) / (cameraZ * cos(halfFOV + rotationAngle));
return max(x3dScale, y3dScale);
}
@@ -358,7 +329,8 @@ m2::RectD ScreenBase::CalculatePixelRect(double scale) const
// Place the camera at the distance, where it gives the same view of plane as the
// orthogonal projection does. Calculate what part of the map would be visible,
// when it is rotated through maxRotationAngle around its near horizontal side.
-void ScreenBase::ApplyPerspective(double currentRotationAngle, double maxRotationAngle, double angleFOV)
+void ScreenBase::ApplyPerspective(double currentRotationAngle, double maxRotationAngle,
+ double angleFOV)
{
ASSERT_GREATER(angleFOV, 0.0, ());
ASSERT_LESS(angleFOV, math::pi2, ());
@@ -418,11 +390,10 @@ void ScreenBase::SetRotationAngle(double rotationAngle)
Matrix3dT projectionM = math::Zero<double, 4>();
m_3dFarZ = cameraZ + 2.0 * sin(m_3dAngleX) * m_3dScale;
projectionM(0, 0) = projectionM(1, 1) = cameraZ;
- projectionM(2, 2) = m_3dAngleX != 0.0 ? (m_3dFarZ + m_3dNearZ) / (m_3dFarZ - m_3dNearZ)
- : 0.0;
+ projectionM(2, 2) = m_3dAngleX != 0.0 ? (m_3dFarZ + m_3dNearZ) / (m_3dFarZ - m_3dNearZ) : 0.0;
projectionM(2, 3) = 1.0;
- projectionM(3, 2) = m_3dAngleX != 0.0 ? -2.0 * m_3dFarZ * m_3dNearZ / (m_3dFarZ - m_3dNearZ)
- : 0.0;
+ projectionM(3, 2) =
+ m_3dAngleX != 0.0 ? -2.0 * m_3dFarZ * m_3dNearZ / (m_3dFarZ - m_3dNearZ) : 0.0;
m_Pto3d = scaleM * rotateM * translateM * projectionM;
m_3dtoP = math::Inverse(m_Pto3d);
@@ -442,10 +413,7 @@ void ScreenBase::ResetPerspective()
Move(0.0, -old_dy / 2.0);
}
-m2::PointD ScreenBase::PtoP3d(m2::PointD const & pt) const
-{
- return PtoP3d(pt, 0.0);
-}
+m2::PointD ScreenBase::PtoP3d(m2::PointD const & pt) const { return PtoP3d(pt, 0.0); }
double ScreenBase::GetZScale() const
{
diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp
index 7f45f9b3ac..2278883134 100644
--- a/geometry/screenbase.hpp
+++ b/geometry/screenbase.hpp
@@ -1,12 +1,11 @@
#pragma once
+#include "geometry/any_rect2d.hpp"
#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"
-#include "geometry/any_rect2d.hpp"
#include "base/matrix.hpp"
-
class ScreenBase
{
public:
@@ -14,55 +13,9 @@ public:
using Matrix3dT = math::Matrix<double, 4, 4>;
using Vector3dT = math::Matrix<double, 1, 4>;
-private:
- m2::RectD m_ViewportRect;
- m2::RectD m_PixelRect;
-
- double m_Scale;
- ang::AngleD m_Angle;
- m2::PointD m_Org;
-
- double m_3dFOV;
- double m_3dNearZ;
- double m_3dFarZ;
- double m_3dAngleX;
- double m_3dMaxAngleX;
- double m_3dScale;
- bool m_isPerspective;
- bool m_isAutoPerspective;
-
-protected:
- /// @group Dependent parameters
- /// Global to Pixel conversion matrix.
- /// |a11 a12 0|
- /// |x, y, 1| * |a21 a22 0| = |x', y', 1|
- /// |a31 a32 1|
- /// @{
- MatrixT m_GtoP;
-
- /// Pixel to Global conversion matrix. Inverted GtoP matrix.
- MatrixT m_PtoG;
-
- /// Global Rect
- m2::AnyRectD m_GlobalRect;
-
- /// X-axis aligned global rect used for clipping
- m2::RectD m_ClipRect;
-
- /// @}
-
- Matrix3dT m_Pto3d;
- Matrix3dT m_3dtoP;
-
- // Update dependent parameters from base parameters.
- // Must be called when base parameters changed.
- void UpdateDependentParameters();
-
-public:
ScreenBase();
ScreenBase(m2::RectI const & pxRect, m2::AnyRectD const & glbRect);
- ScreenBase(ScreenBase const & s,
- m2::PointD const & org, double scale, double angle);
+ ScreenBase(ScreenBase const & s, m2::PointD const & org, double scale, double angle);
void SetFromRect(m2::AnyRectD const & rect);
@@ -91,24 +44,18 @@ public:
int GetWidth() const;
int GetHeight() const;
- inline m2::PointD GtoP(m2::PointD const & pt) const
- {
- return pt * m_GtoP;
- }
+ m2::PointD GtoP(m2::PointD const & pt) const { return pt * m_GtoP; }
- inline m2::PointD PtoG(m2::PointD const & pt) const
- {
- return pt * m_PtoG;
- }
+ m2::PointD PtoG(m2::PointD const & pt) const { return pt * m_PtoG; }
- inline void GtoP(double & x, double & y) const
+ void GtoP(double & x, double & y) const
{
double tempX = x;
x = tempX * m_GtoP(0, 0) + y * m_GtoP(1, 0) + m_GtoP(2, 0);
y = tempX * m_GtoP(1, 0) + y * m_GtoP(1, 1) + m_GtoP(2, 1);
}
- inline void PtoG(double & x, double & y) const
+ void PtoG(double & x, double & y) const
{
double tempX = x;
x = tempX * m_PtoG(0, 0) + y * m_PtoG(1, 0) + m_PtoG(2, 0);
@@ -122,8 +69,8 @@ public:
void MatchGandP3d(m2::PointD const & g, m2::PointD const & p3d);
void GetTouchRect(m2::PointD const & pixPoint, double pixRadius, m2::AnyRectD & glbRect) const;
- void GetTouchRect(m2::PointD const & pixPoint, double const pxWidth,
- double const pxHeight, m2::AnyRectD & glbRect) const;
+ void GetTouchRect(m2::PointD const & pixPoint, double const pxWidth, double const pxHeight,
+ m2::AnyRectD & glbRect) const;
MatrixT const & GtoPMatrix() const { return m_GtoP; }
MatrixT const & PtoGMatrix() const { return m_PtoG; }
@@ -156,10 +103,7 @@ public:
m2::PointD PtoP3d(m2::PointD const & pt) const;
m2::PointD PtoP3d(m2::PointD const & pt, double ptZ) const;
- m2::RectD const & PixelRectIn3d() const
- {
- return m_ViewportRect;
- }
+ m2::RectD const & PixelRectIn3d() const { return m_ViewportRect; }
double CalculateScale3d(double rotationAngle) const;
m2::RectD CalculatePixelRect(double scale) const;
@@ -171,27 +115,69 @@ public:
static double CalculateAutoPerspectiveAngle(double scale);
static double GetStartPerspectiveScale();
- /// Compute arbitrary pixel transformation, that translates the (oldPt1, oldPt2) -> (newPt1, newPt2)
+ /// Compute arbitrary pixel transformation, that translates the (oldPt1, oldPt2) -> (newPt1,
+ /// newPt2)
static MatrixT const CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2,
m2::PointD const & newPt1, m2::PointD const & newPt2,
bool allowRotate);
-
/// Setting GtoP matrix extracts the Angle and m_Org parameters, leaving PixelRect intact
void SetGtoPMatrix(MatrixT const & m);
/// Extracting parameters from matrix, that is supposed to represent GtoP transformation
- static void ExtractGtoPParams(MatrixT const & m, double & a, double & s, double & dx, double & dy);
+ static void ExtractGtoPParams(MatrixT const & m, double & a, double & s, double & dx,
+ double & dy);
- bool operator != (ScreenBase const & src) const
- {
- return !(*this == src);
- }
+ bool operator!=(ScreenBase const & src) const { return !(*this == src); }
- bool operator == (ScreenBase const & src) const
+ bool operator==(ScreenBase const & src) const
{
return (m_GtoP == src.m_GtoP) && (m_PtoG == src.m_PtoG);
}
+
+protected:
+ // Update dependent parameters from base parameters.
+ // Must be called when base parameters changed.
+ void UpdateDependentParameters();
+
+ /// @group Dependent parameters
+ /// Global to Pixel conversion matrix.
+ /// |a11 a12 0|
+ /// |x, y, 1| * |a21 a22 0| = |x', y', 1|
+ /// |a31 a32 1|
+ /// @{
+ MatrixT m_GtoP;
+
+ /// Pixel to Global conversion matrix. Inverted GtoP matrix.
+ MatrixT m_PtoG;
+
+ /// Global Rect
+ m2::AnyRectD m_GlobalRect;
+
+ /// X-axis aligned global rect used for clipping
+ m2::RectD m_ClipRect;
+
+ /// @}
+
+ Matrix3dT m_Pto3d;
+ Matrix3dT m_3dtoP;
+
+private:
+ m2::RectD m_ViewportRect;
+ m2::RectD m_PixelRect;
+
+ double m_Scale;
+ ang::AngleD m_Angle;
+ m2::PointD m_Org;
+
+ double m_3dFOV;
+ double m_3dNearZ;
+ double m_3dFarZ;
+ double m_3dAngleX;
+ double m_3dMaxAngleX;
+ double m_3dScale;
+ bool m_isPerspective;
+ bool m_isAutoPerspective;
};
/// checking whether the s1 transforms into s2 without scaling, only with shift and rotation
diff --git a/geometry/segment2d.cpp b/geometry/segment2d.cpp
index f51d5940c7..913f83542c 100644
--- a/geometry/segment2d.cpp
+++ b/geometry/segment2d.cpp
@@ -3,16 +3,12 @@
#include "geometry/robust_orientation.hpp"
#include <algorithm>
+#include <string>
using namespace std;
namespace m2
{
-string DebugPrint(Segment2D const & segment)
-{
- return "(" + DebugPrint(segment.m_u) + ", " + DebugPrint(segment.m_v) + ")";
-}
-
bool IsPointOnSegmentEps(PointD const & pt, PointD const & p1, PointD const & p2, double eps)
{
double const t = robust::OrientedS(p1, p2, pt);
@@ -43,4 +39,9 @@ bool IsPointOnSegment(PointD const & pt, PointD const & p1, PointD const & p2)
double const kEps = 1e-100;
return IsPointOnSegmentEps(pt, p1, p2, kEps);
}
+
+std::string DebugPrint(Segment2D const & segment)
+{
+ return "(" + DebugPrint(segment.m_u) + ", " + DebugPrint(segment.m_v) + ")";
+}
} // namespace m2
diff --git a/geometry/tree4d.hpp b/geometry/tree4d.hpp
index 69aaf55f6c..e9011ae1e1 100644
--- a/geometry/tree4d.hpp
+++ b/geometry/tree4d.hpp
@@ -1,277 +1,243 @@
#pragma once
-#include "geometry/rect2d.hpp"
#include "geometry/point2d.hpp"
+#include "geometry/rect2d.hpp"
-#include "base/stl_add.hpp"
#include "base/logging.hpp"
+#include "base/stl_add.hpp"
-#include "std/sstream.hpp"
-#include "std/vector.hpp"
+#include <sstream>
+#include <string>
+#include <vector>
#include "3party/kdtree++/kdtree.hpp"
-
namespace m4
{
- template <typename T>
- struct TraitsDef
- {
- m2::RectD const LimitRect(T const & t) const
- {
- return t.GetLimitRect();
- }
- };
+template <typename T>
+struct TraitsDef
+{
+ m2::RectD const LimitRect(T const & t) const { return t.GetLimitRect(); }
+};
- template <class T, typename Traits = TraitsDef<T> >
- class Tree
+template <typename T, typename Traits = TraitsDef<T>>
+class Tree
+{
+ class ValueT
{
- class ValueT
+ void SetRect(m2::RectD const & r)
{
- void SetRect(m2::RectD const & r)
- {
- m_pts[0] = r.minX();
- m_pts[1] = r.minY();
- m_pts[2] = r.maxX();
- m_pts[3] = r.maxY();
- }
+ m_pts[0] = r.minX();
+ m_pts[1] = r.minY();
+ m_pts[2] = r.maxX();
+ m_pts[3] = r.maxY();
+ }
- public:
- T m_val;
- double m_pts[4];
+ public:
+ T m_val;
+ double m_pts[4];
- typedef double value_type;
+ typedef double value_type;
- ValueT(T const & t, m2::RectD const & r) : m_val(t)
- {
- SetRect(r);
- }
- ValueT(T && t, m2::RectD const & r) : m_val(move(t))
- {
- SetRect(r);
- }
+ ValueT(T const & t, m2::RectD const & r) : m_val(t) { SetRect(r); }
+ ValueT(T && t, m2::RectD const & r) : m_val(move(t)) { SetRect(r); }
- bool IsIntersect(m2::RectD const & r) const
- {
- return !((m_pts[2] <= r.minX()) || (m_pts[0] >= r.maxX()) ||
- (m_pts[3] <= r.minY()) || (m_pts[1] >= r.maxY()));
- }
+ bool IsIntersect(m2::RectD const & r) const
+ {
+ return !((m_pts[2] <= r.minX()) || (m_pts[0] >= r.maxX()) || (m_pts[3] <= r.minY()) ||
+ (m_pts[1] >= r.maxY()));
+ }
- bool operator ==(ValueT const & r) const
- {
- return (m_val == r.m_val);
- }
+ bool operator==(ValueT const & r) const { return (m_val == r.m_val); }
- string DebugPrint() const
- {
- ostringstream out;
+ std::string DebugPrint() const
+ {
+ std::ostringstream out;
- out << DebugPrint(m_val) << ", ("
- << m_pts[0] << ", "
- << m_pts[1] << ", "
- << m_pts[2] << ", "
- << m_pts[3] << ")";
+ out << DebugPrint(m_val) << ", (" << m_pts[0] << ", " << m_pts[1] << ", " << m_pts[2] << ", "
+ << m_pts[3] << ")";
- return out.str();
- }
+ return out.str();
+ }
- double operator[](size_t i) const { return m_pts[i]; }
+ double operator[](size_t i) const { return m_pts[i]; }
- m2::RectD GetRect() const { return m2::RectD(m_pts[0], m_pts[1], m_pts[2], m_pts[3]); }
- };
+ m2::RectD GetRect() const { return m2::RectD(m_pts[0], m_pts[1], m_pts[2], m_pts[3]); }
+ };
- typedef KDTree::KDTree<4, ValueT> TreeT;
- TreeT m_tree;
+ typedef KDTree::KDTree<4, ValueT> TreeT;
+ TreeT m_tree;
- // Do-class for rect-iteration in tree.
- template <class ToDo> class for_each_helper
- {
- m2::RectD const & m_rect;
- ToDo m_toDo;
-
- public:
- for_each_helper(m2::RectD const & r, ToDo toDo)
- : m_rect(r), m_toDo(toDo)
- {
- }
+ // Do-class for rect-iteration in tree.
+ template <typename ToDo>
+ class for_each_helper
+ {
+ m2::RectD const & m_rect;
+ ToDo m_toDo;
- bool ScanLeft(size_t plane, ValueT const & v) const
- {
- switch (plane & 3) // % 4
- {
- case 2: return m_rect.minX() < v[2];
- case 3: return m_rect.minY() < v[3];
- default: return true;
- }
- }
+ public:
+ for_each_helper(m2::RectD const & r, ToDo toDo) : m_rect(r), m_toDo(toDo) {}
- bool ScanRight(size_t plane, ValueT const & v) const
+ bool ScanLeft(size_t plane, ValueT const & v) const
+ {
+ switch (plane & 3) // % 4
{
- switch (plane & 3) // % 4
- {
- case 0: return m_rect.maxX() > v[0];
- case 1: return m_rect.maxY() > v[1];
- default: return true;
- }
+ case 2: return m_rect.minX() < v[2];
+ case 3: return m_rect.minY() < v[3];
+ default: return true;
}
+ }
- void operator() (ValueT const & v) const
+ bool ScanRight(size_t plane, ValueT const & v) const
+ {
+ switch (plane & 3) // % 4
{
- if (v.IsIntersect(m_rect))
- m_toDo(v);
+ case 0: return m_rect.maxX() > v[0];
+ case 1: return m_rect.maxY() > v[1];
+ default: return true;
}
- };
+ }
- template <class ToDo> for_each_helper<ToDo> GetFunctor(m2::RectD const & rect, ToDo toDo) const
+ void operator()(ValueT const & v) const
{
- return for_each_helper<ToDo>(rect, toDo);
+ if (v.IsIntersect(m_rect))
+ m_toDo(v);
}
+ };
- protected:
- Traits m_traits;
- m2::RectD GetLimitRect(T const & t) const { return m_traits.LimitRect(t); }
+ template <typename ToDo>
+ for_each_helper<ToDo> GetFunctor(m2::RectD const & rect, ToDo toDo) const
+ {
+ return for_each_helper<ToDo>(rect, toDo);
+ }
- public:
- Tree(Traits const & traits = Traits()) : m_traits(traits) {}
+protected:
+ Traits m_traits;
+ m2::RectD GetLimitRect(T const & t) const { return m_traits.LimitRect(t); }
- typedef T elem_t;
+public:
+ Tree(Traits const & traits = Traits()) : m_traits(traits) {}
- void Add(T const & obj)
- {
- Add(obj, GetLimitRect(obj));
- }
- void Add(T && obj)
- {
- Add(move(obj), GetLimitRect(obj));
- }
+ typedef T elem_t;
- void Add(T const & obj, m2::RectD const & rect)
- {
- m_tree.insert(ValueT(obj, rect));
- }
- void Add(T && obj, m2::RectD const & rect)
- {
- m_tree.insert(ValueT(move(obj), rect));
- }
+ void Add(T const & obj) { Add(obj, GetLimitRect(obj)); }
+ void Add(T && obj) { Add(move(obj), GetLimitRect(obj)); }
- private:
- template <class CompareT>
- void ReplaceImpl(T const & obj, m2::RectD const & rect, CompareT comp)
- {
- bool skip = false;
- vector<ValueT const *> isect;
+ void Add(T const & obj, m2::RectD const & rect) { m_tree.insert(ValueT(obj, rect)); }
+ void Add(T && obj, m2::RectD const & rect) { m_tree.insert(ValueT(move(obj), rect)); }
- m_tree.for_each(GetFunctor(rect, [&] (ValueT const & v)
- {
- if (skip)
- return;
-
- switch (comp(obj, v.m_val))
- {
- case 1:
- isect.push_back(&v);
- break;
- case -1:
- skip = true;
- break;
- }
- }));
+private:
+ template <typename CompareT>
+ void ReplaceImpl(T const & obj, m2::RectD const & rect, CompareT comp)
+ {
+ bool skip = false;
+ std::vector<ValueT const *> isect;
+ m_tree.for_each(GetFunctor(rect, [&](ValueT const & v) {
if (skip)
return;
- for (ValueT const * v : isect)
- m_tree.erase(*v);
+ switch (comp(obj, v.m_val))
+ {
+ case 1: isect.push_back(&v); break;
+ case -1: skip = true; break;
+ }
+ }));
- Add(obj, rect);
- }
+ if (skip)
+ return;
- public:
- template <class CompareT>
- void ReplaceAllInRect(T const & obj, CompareT comp)
- {
- ReplaceImpl(obj, GetLimitRect(obj), [&comp] (T const & t1, T const & t2)
- {
+ for (ValueT const * v : isect)
+ m_tree.erase(*v);
+
+ Add(obj, rect);
+ }
+
+public:
+ template <typename CompareT>
+ void ReplaceAllInRect(T const & obj, CompareT comp)
+ {
+ ReplaceImpl(obj, GetLimitRect(obj),
+ [&comp](T const & t1, T const & t2) { return comp(t1, t2) ? 1 : -1; });
+ }
+
+ template <typename EqualT, class CompareT>
+ void ReplaceEqualInRect(T const & obj, EqualT eq, CompareT comp)
+ {
+ ReplaceImpl(obj, GetLimitRect(obj), [&](T const & t1, T const & t2) {
+ if (eq(t1, t2))
return comp(t1, t2) ? 1 : -1;
- });
- }
+ else
+ return 0;
+ });
+ }
- template <class EqualT, class CompareT>
- void ReplaceEqualInRect(T const & obj, EqualT eq, CompareT comp)
- {
- ReplaceImpl(obj, GetLimitRect(obj), [&] (T const & t1, T const & t2)
- {
- if (eq(t1, t2))
- return comp(t1, t2) ? 1 : -1;
- else
- return 0;
- });
- }
+ void Erase(T const & obj, m2::RectD const & r)
+ {
+ ValueT val(obj, r);
+ m_tree.erase_exact(val);
+ }
- void Erase(T const & obj, m2::RectD const & r)
- {
- ValueT val(obj, r);
- m_tree.erase_exact(val);
- }
+ void Erase(T const & obj)
+ {
+ ValueT val(obj, m_traits.LimitRect(obj));
+ m_tree.erase_exact(val);
+ }
- void Erase(T const & obj)
- {
- ValueT val(obj, m_traits.LimitRect(obj));
- m_tree.erase_exact(val);
- }
+ template <typename ToDo>
+ void ForEach(ToDo && toDo) const
+ {
+ for (ValueT const & v : m_tree)
+ toDo(v.m_val);
+ }
- template <class ToDo>
- void ForEach(ToDo && toDo) const
- {
- for (ValueT const & v : m_tree)
- toDo(v.m_val);
- }
- template <class ToDo>
- void ForEachEx(ToDo && toDo) const
- {
- for (ValueT const & v : m_tree)
- toDo(v.GetRect(), v.m_val);
- }
+ template <typename ToDo>
+ void ForEachEx(ToDo && toDo) const
+ {
+ for (ValueT const & v : m_tree)
+ toDo(v.GetRect(), v.m_val);
+ }
- template <class ToDo>
- bool FindNode(ToDo && toDo) const
- {
- for (ValueT const & v : m_tree)
- if (toDo(v.m_val))
- return true;
+ template <typename ToDo>
+ bool FindNode(ToDo && toDo) const
+ {
+ for (ValueT const & v : m_tree)
+ if (toDo(v.m_val))
+ return true;
- return false;
- }
+ return false;
+ }
- template <class ToDo>
- void ForEachInRect(m2::RectD const & rect, ToDo && toDo) const
- {
- m_tree.for_each(GetFunctor(rect, [&toDo] (ValueT const & v) { toDo(v.m_val); }));
- }
- template <class ToDo>
- void ForEachInRectEx(m2::RectD const & rect, ToDo && toDo) const
- {
- m_tree.for_each(GetFunctor(rect, [&toDo] (ValueT const & v) { toDo(v.GetRect(), v.m_val); }));
- }
+ template <typename ToDo>
+ void ForEachInRect(m2::RectD const & rect, ToDo && toDo) const
+ {
+ m_tree.for_each(GetFunctor(rect, [&toDo](ValueT const & v) { toDo(v.m_val); }));
+ }
- bool IsEmpty() const { return m_tree.empty(); }
+ template <typename ToDo>
+ void ForEachInRectEx(m2::RectD const & rect, ToDo && toDo) const
+ {
+ m_tree.for_each(GetFunctor(rect, [&toDo](ValueT const & v) { toDo(v.GetRect(), v.m_val); }));
+ }
- size_t GetSize() const { return m_tree.size(); }
+ bool IsEmpty() const { return m_tree.empty(); }
- void Clear() { m_tree.clear(); }
+ size_t GetSize() const { return m_tree.size(); }
- string DebugPrint() const
- {
- ostringstream out;
- for (ValueT const & v : m_tree.begin())
- out << v.DebugPrint() << ", ";
- return out.str();
- }
- };
+ void Clear() { m_tree.clear(); }
- template <typename T, typename Traits>
- string DebugPrint(Tree<T, Traits> const & t)
+ std::string DebugPrint() const
{
- return t.DebugPrint();
+ std::ostringstream out;
+ for (ValueT const & v : m_tree.begin())
+ out << v.DebugPrint() << ", ";
+ return out.str();
}
+};
+
+template <typename T, typename Traits>
+std::string DebugPrint(Tree<T, Traits> const & t)
+{
+ return t.DebugPrint();
}
+} // namespace m4