diff options
author | Yuri Gorshenin <y@maps.me> | 2017-09-27 17:44:05 +0300 |
---|---|---|
committer | mpimenov <mpimenov@users.noreply.github.com> | 2017-09-28 18:54:14 +0300 |
commit | e04d25505fb37abff651434ed4e29e7692af808f (patch) | |
tree | 72ff1216127379085f9141eec89165e09172896b /geometry | |
parent | 6737cd92217fdd9e02ee0e19eddc45156e7b104a (diff) |
[indexer] Simplified boundaries encoding/decoding.
Diffstat (limited to 'geometry')
-rw-r--r-- | geometry/CMakeLists.txt | 1 | ||||
-rw-r--r-- | geometry/bounding_box.cpp | 21 | ||||
-rw-r--r-- | geometry/bounding_box.hpp | 32 | ||||
-rw-r--r-- | geometry/calipers_box.cpp | 4 | ||||
-rw-r--r-- | geometry/calipers_box.hpp | 12 | ||||
-rw-r--r-- | geometry/diamond_box.cpp | 17 | ||||
-rw-r--r-- | geometry/diamond_box.hpp | 27 | ||||
-rw-r--r-- | geometry/geometry.pro | 1 | ||||
-rw-r--r-- | geometry/point2d.hpp | 3 |
9 files changed, 105 insertions, 13 deletions
diff --git a/geometry/CMakeLists.txt b/geometry/CMakeLists.txt index 5985cef06e..7c42d28dde 100644 --- a/geometry/CMakeLists.txt +++ b/geometry/CMakeLists.txt @@ -19,6 +19,7 @@ set( convex_hull.hpp covering.hpp covering_utils.hpp + diamond_box.cpp diamond_box.hpp distance.hpp distance_on_sphere.cpp diff --git a/geometry/bounding_box.cpp b/geometry/bounding_box.cpp index 957f51ff6b..d968239e2f 100644 --- a/geometry/bounding_box.cpp +++ b/geometry/bounding_box.cpp @@ -1,6 +1,7 @@ #include "geometry/bounding_box.hpp" #include <algorithm> +#include <sstream> using namespace std; @@ -14,14 +15,24 @@ BoundingBox::BoundingBox(vector<PointD> const & points) void BoundingBox::Add(double x, double y) { - m_minX = min(m_minX, x); - m_minY = min(m_minY, y); - m_maxX = max(m_maxX, x); - m_maxY = max(m_maxY, y); + m_min.x = min(m_min.x, x); + m_min.y = min(m_min.y, y); + m_max.x = max(m_max.x, x); + m_max.y = max(m_max.y, y); } bool BoundingBox::HasPoint(double x, double y) const { - return x >= m_minX && x <= m_maxX && y >= m_minY && y <= m_maxY; + return x >= m_min.x && x <= m_max.x && y >= m_min.y && y <= m_max.y; +} + +string DebugPrint(BoundingBox const & bbox) +{ + ostringstream os; + os << "BoundingBox [ "; + os << "min: " << DebugPrint(bbox.Min()) << ", "; + os << "max: " << DebugPrint(bbox.Max()); + os << " ]"; + return os.str(); } } // namespace m2 diff --git a/geometry/bounding_box.hpp b/geometry/bounding_box.hpp index a343e93093..2e9209cfab 100644 --- a/geometry/bounding_box.hpp +++ b/geometry/bounding_box.hpp @@ -2,7 +2,10 @@ #include "geometry/point2d.hpp" +#include "base/visitor.hpp" + #include <limits> +#include <string> #include <vector> namespace m2 @@ -19,17 +22,34 @@ public: bool HasPoint(PointD const & p) const { return HasPoint(p.x, p.y); } bool HasPoint(double x, double y) const; - PointD Min() const { return PointD(m_minX, m_minY); } - PointD Max() const { return PointD(m_maxX, m_maxY); } + PointD Min() const { return m_min; } + PointD Max() const { return m_max; } + + std::vector<m2::PointD> Points() const + { + std::vector<m2::PointD> points(4); + points[0] = Min(); + points[2] = Max(); + points[1] = PointD(points[2].x, points[0].y); + points[3] = PointD(points[0].x, points[2].y); + return points; + } + + bool operator==(BoundingBox const & rhs) const + { + return m_min == rhs.m_min && m_max == rhs.m_max; + } + + DECLARE_VISITOR(visitor(m_min), visitor(m_max)) private: static_assert(std::numeric_limits<double>::has_infinity, ""); static double constexpr kPositiveInfinity = std::numeric_limits<double>::infinity(); static double constexpr kNegativeInfinity = -kPositiveInfinity; - double m_minX = kPositiveInfinity; - double m_minY = kPositiveInfinity; - double m_maxX = kNegativeInfinity; - double m_maxY = kNegativeInfinity; + m2::PointD m_min = m2::PointD(kPositiveInfinity, kPositiveInfinity); + m2::PointD m_max = m2::PointD(kNegativeInfinity, kNegativeInfinity); }; + +std::string DebugPrint(BoundingBox const & bbox); } // namespace m2 diff --git a/geometry/calipers_box.cpp b/geometry/calipers_box.cpp index 046c81a89f..a5ad7fe27b 100644 --- a/geometry/calipers_box.cpp +++ b/geometry/calipers_box.cpp @@ -86,7 +86,7 @@ CalipersBox::CalipersBox(vector<PointD> const & points) : m_points({}) { ConvexHull hull(points, kEps); - if (hull.Size() < 4) + if (hull.Size() < 3) { m_points = hull.Points(); return; @@ -147,4 +147,6 @@ bool CalipersBox::HasPoint(PointD const & p) const } return true; } + +string DebugPrint(CalipersBox const & cbox) { return "CalipersBox " + ::DebugPrint(cbox.Points()); } } // namespace m2 diff --git a/geometry/calipers_box.hpp b/geometry/calipers_box.hpp index 19119ad147..6cf7299dc5 100644 --- a/geometry/calipers_box.hpp +++ b/geometry/calipers_box.hpp @@ -2,12 +2,15 @@ #include "geometry/point2d.hpp" +#include "base/visitor.hpp" + +#include <string> #include <vector> namespace m2 { // When the size of the convex hull over a set of |points| is less -// than 4, stores convex hull explicitly, otherwise stores smallest +// than 3, stores convex hull explicitly, otherwise stores smallest // rectangle containing the hull. Note that at least one side of the // rectangle should contain a facet of the hull, and in general sides // of the rectangle may not be parallel to the axes. In any case, @@ -15,6 +18,7 @@ namespace m2 class CalipersBox { public: + CalipersBox() = default; CalipersBox(std::vector<PointD> const & points); std::vector<PointD> const & Points() const { return m_points; } @@ -22,7 +26,13 @@ public: bool HasPoint(PointD const & p) const; bool HasPoint(double x, double y) const { return HasPoint(PointD(x, y)); } + bool operator==(CalipersBox const & rhs) const { return m_points == rhs.m_points; } + + DECLARE_VISITOR(visitor(m_points)) + private: std::vector<PointD> m_points; }; + +std::string DebugPrint(CalipersBox const & cbox); } // namespace m2 diff --git a/geometry/diamond_box.cpp b/geometry/diamond_box.cpp new file mode 100644 index 0000000000..07fc21e1a2 --- /dev/null +++ b/geometry/diamond_box.cpp @@ -0,0 +1,17 @@ +#include "geometry/diamond_box.hpp" + +using namespace std; + +namespace m2 +{ +DiamondBox::DiamondBox(vector<PointD> const & points) +{ + for (auto const & p : points) + Add(p); +} + +string DebugPrint(DiamondBox const & dbox) +{ + return "DiamondBox [ " + ::DebugPrint(dbox.Points()) + " ]"; +} +} // namespace m2 diff --git a/geometry/diamond_box.hpp b/geometry/diamond_box.hpp index 5bbd4d2f6f..436eca4009 100644 --- a/geometry/diamond_box.hpp +++ b/geometry/diamond_box.hpp @@ -3,6 +3,11 @@ #include "geometry/bounding_box.hpp" #include "geometry/point2d.hpp" +#include "base/visitor.hpp" + +#include <string> +#include <vector> + namespace m2 { // Bounding box for a set of points on the plane, rotated by 45 @@ -10,13 +15,35 @@ namespace m2 class DiamondBox { public: + DiamondBox() = default; + DiamondBox(std::vector<PointD> const & points); + void Add(PointD const & p) { return Add(p.x, p.y); } void Add(double x, double y) { return m_box.Add(x + y, x - y); } bool HasPoint(PointD const & p) const { return HasPoint(p.x, p.y); } bool HasPoint(double x, double y) const { return m_box.HasPoint(x + y, x - y); } + std::vector<m2::PointD> Points() const + { + auto points = m_box.Points(); + for (auto & p : points) + p = ToOrig(p); + return points; + } + + bool operator==(DiamondBox const & rhs) const { return m_box == rhs.m_box; } + + DECLARE_VISITOR(visitor(m_box)) + private: + static m2::PointD ToOrig(m2::PointD const & p) + { + return m2::PointD(0.5 * (p.x + p.y), 0.5 * (p.x - p.y)); + } + BoundingBox m_box; }; + +std::string DebugPrint(DiamondBox const & dbox); } // namespace m2 diff --git a/geometry/geometry.pro b/geometry/geometry.pro index bf5bd72b54..fcef54da1b 100644 --- a/geometry/geometry.pro +++ b/geometry/geometry.pro @@ -15,6 +15,7 @@ SOURCES += \ calipers_box.cpp \ clipping.cpp \ convex_hull.cpp \ + diamond_box.cpp \ distance_on_sphere.cpp \ latlon.cpp \ line2d.cpp \ diff --git a/geometry/point2d.hpp b/geometry/point2d.hpp index 4eaffd1fc0..409e7936f9 100644 --- a/geometry/point2d.hpp +++ b/geometry/point2d.hpp @@ -175,6 +175,9 @@ namespace m2 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) { |