diff options
author | Maxim Pimenov <m@maps.me> | 2018-07-24 19:23:33 +0300 |
---|---|---|
committer | Vlad Mihaylenko <vxmihaylenko@gmail.com> | 2018-07-25 18:49:59 +0300 |
commit | 4632c8a8b5f07818297f1962a14c696f5366381a (patch) | |
tree | e886430c57e05754faddbc44511c161681ae560d /geometry | |
parent | abc28557e2cff5d6298489f370d8dd95bbba32ed (diff) |
[geometry] AnyRect refactoring.
Diffstat (limited to 'geometry')
-rw-r--r-- | geometry/any_rect2d.hpp | 101 | ||||
-rw-r--r-- | geometry/geometry_tests/anyrect_test.cpp | 70 |
2 files changed, 86 insertions, 85 deletions
diff --git a/geometry/any_rect2d.hpp b/geometry/any_rect2d.hpp index 5e118f0047..bad6da6eb3 100644 --- a/geometry/any_rect2d.hpp +++ b/geometry/any_rect2d.hpp @@ -7,6 +7,7 @@ #include "base/math.hpp" +#include <array> #include <string> namespace m2 @@ -41,18 +42,18 @@ public: Point<T> const & LocalZero() const { return m_zero; } - Point<T> const GlobalZero() const + Point<T> GlobalZero() const { - return Convert(m_zero, i(), j(), m2::Point<T>(1, 0), m2::Point<T>(0, 1)); + return Convert(m_zero, i(), j(), Point<T>(1, 0), Point<T>(0, 1)); } - Point<T> const i() const { return Point<T>(m_angle.cos(), m_angle.sin()); } + Point<T> i() const { return Point<T>(m_angle.cos(), m_angle.sin()); } - Point<T> const j() const { return Point<T>(-m_angle.sin(), m_angle.cos()); } + Point<T> j() const { return Point<T>(-m_angle.sin(), m_angle.cos()); } void SetAngle(ang::Angle<T> const & a) { - m2::Point<T> glbZero = GlobalZero(); + Point<T> glbZero = GlobalZero(); m_angle = a; m_zero = Convert(glbZero, Point<T>(1, 0), Point<T>(0, 1), i(), j()); @@ -60,25 +61,27 @@ public: ang::Angle<T> const & Angle() const { return m_angle; } - Point<T> const GlobalCenter() const { return ConvertFrom(m_rect.Center()); } + Point<T> GlobalCenter() const { return ConvertFrom(m_rect.Center()); } - Point<T> const LocalCenter() const { return m_rect.Center(); } + Point<T> LocalCenter() const { return m_rect.Center(); } T GetMaxSize() const { return max(m_rect.SizeX(), m_rect.SizeY()); } bool EqualDxDy(AnyRect<T> const & r, T eps) const { - m2::Point<T> arr1[4]; + std::array<Point<T>, 4> arr1; GetGlobalPoints(arr1); sort(arr1, arr1 + 4); - m2::Point<T> arr2[4]; + std::array<Point<T>, 4> arr2; r.GetGlobalPoints(arr2); sort(arr2, arr2 + 4); for (size_t i = 0; i < 4; ++i) + { if (!arr1[i].EqualDxDy(arr2[i], eps)) return false; + } return true; } @@ -87,28 +90,29 @@ public: bool IsRectInside(AnyRect<T> const & r) const { - m2::Point<T> pts[4]; + std::array<Point<T>, 4> pts; r.GetGlobalPoints(pts); - ConvertTo(pts, 4); + ConvertTo(pts); return m_rect.IsPointInside(pts[0]) && m_rect.IsPointInside(pts[1]) && m_rect.IsPointInside(pts[2]) && m_rect.IsPointInside(pts[3]); } bool IsIntersect(AnyRect<T> const & r) const { - m2::Point<T> pts[4]; if (r.GetLocalRect() == Rect<T>()) return false; + std::array<Point<T>, 4> pts; r.GetGlobalPoints(pts); - ConvertTo(pts, 4); + ConvertTo(pts); - m2::Rect<T> r1(pts[0], pts[0]); - r1.Add(pts[1]); - r1.Add(pts[2]); - r1.Add(pts[3]); + { + Rect<T> r1; + for (auto const & p : pts) + r1.Add(p); - if (!GetLocalRect().IsIntersect(r1)) - return false; + if (!GetLocalRect().IsIntersect(r1)) + return false; + } if (r.IsRectInside(*this)) return true; @@ -121,51 +125,44 @@ public: } /// Convert into coordinate system of this AnyRect - Point<T> const ConvertTo(Point<T> const & p) const + Point<T> ConvertTo(Point<T> const & p) const { - m2::Point<T> i1(1, 0); - m2::Point<T> j1(0, 1); + Point<T> i1(1, 0); + Point<T> j1(0, 1); return Convert(p - Convert(m_zero, i(), j(), i1, j1), i1, j1, i(), j()); } - void ConvertTo(Point<T> * pts, size_t count) const + void ConvertTo(std::array<Point<T>, 4> & pts) const { - for (size_t i = 0; i < count; ++i) - pts[i] = ConvertTo(pts[i]); + for (auto & p : pts) + p = ConvertTo(p); } /// Convert into global coordinates from the local coordinates of this AnyRect - Point<T> const ConvertFrom(Point<T> const & p) const + Point<T> ConvertFrom(Point<T> const & p) const { - return Convert(p + m_zero, i(), j(), m2::Point<T>(1, 0), m2::Point<T>(0, 1)); - } - - void ConvertFrom(Point<T> * pts, size_t count) const - { - for (size_t i = 0; i < count; ++i) - pts[i] = ConvertFrom(pts[i]); + return Convert(p + m_zero, i(), j(), Point<T>(1, 0), Point<T>(0, 1)); } Rect<T> const & GetLocalRect() const { return m_rect; } - Rect<T> const GetGlobalRect() const + Rect<T> GetGlobalRect() const { - Point<T> pts[4]; + std::array<Point<T>, 4> pts; GetGlobalPoints(pts); - Rect<T> res(pts[0], pts[1]); - res.Add(pts[2]); - res.Add(pts[3]); - + Rect<T> res; + for (auto const & p : pts) + res.Add(p); return res; } - void GetGlobalPoints(Point<T> * pts) const + void GetGlobalPoints(std::array<Point<T>, 4> & 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()))); + pts[0] = ConvertFrom(Point<T>(m_rect.minX(), m_rect.minY())); + pts[1] = ConvertFrom(Point<T>(m_rect.minX(), m_rect.maxY())); + pts[2] = ConvertFrom(Point<T>(m_rect.maxX(), m_rect.maxY())); + pts[3] = ConvertFrom(Point<T>(m_rect.maxX(), m_rect.minY())); } template <typename U> @@ -176,13 +173,11 @@ public: void Add(AnyRect<T> const & r) { - Point<T> pts[4]; + std::array<Point<T>, 4> pts; 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]); + ConvertTo(pts); + for (auto const & p : pts) + m_rect.Add(p); } void Offset(Point<T> const & p) { m_zero = ConvertTo(ConvertFrom(m_zero) + p); } @@ -191,15 +186,15 @@ public: void SetSizesToIncludePoint(Point<T> const & p) { m_rect.SetSizesToIncludePoint(ConvertTo(p)); } - friend std::string DebugPrint(m2::AnyRect<T> const & r) + friend std::string DebugPrint(AnyRect<T> const & r) { return "{ Zero = " + DebugPrint(r.m_zero) + ", Rect = " + DebugPrint(r.m_rect) + ", Ang = " + DebugPrint(r.m_angle) + " }"; } 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) + static Point<T> Convert(Point<T> const & p, Point<T> const & fromI, Point<T> const & fromJ, + Point<T> const & toI, Point<T> const & toJ) { Point<T> res; diff --git a/geometry/geometry_tests/anyrect_test.cpp b/geometry/geometry_tests/anyrect_test.cpp index 33f4323ca1..f1575546cd 100644 --- a/geometry/geometry_tests/anyrect_test.cpp +++ b/geometry/geometry_tests/anyrect_test.cpp @@ -2,53 +2,58 @@ #include "geometry/any_rect2d.hpp" -#include "std/cmath.hpp" +#include <array> +#include <cmath> +using namespace std; + +namespace m2 +{ UNIT_TEST(AnyRect_TestConvertTo) { - m2::AnyRectD r(m2::PointD(0, 0), math::pi / 4, m2::RectD(0, 0, 10, 10)); + AnyRectD r(PointD(0, 0), math::pi / 4, RectD(0, 0, 10, 10)); - m2::PointD pt1(100, 0); + PointD pt1(100, 0); double const sqrt2 = sqrt(2.0); - TEST(r.ConvertTo(pt1).EqualDxDy(m2::PointD(100 / sqrt2, -100 / sqrt2), 10e-5), ()); - TEST(r.ConvertTo(m2::PointD(100, 100)).EqualDxDy(m2::PointD(100 * sqrt2, 0), 10e-5), ()); + TEST(r.ConvertTo(pt1).EqualDxDy(PointD(100 / sqrt2, -100 / sqrt2), 10e-5), ()); + TEST(r.ConvertTo(PointD(100, 100)).EqualDxDy(PointD(100 * sqrt2, 0), 10e-5), ()); - m2::AnyRectD r1(m2::PointD(100, 100), math::pi / 4, m2::RectD(0, 0, 10, 10)); + AnyRectD r1(PointD(100, 100), math::pi / 4, RectD(0, 0, 10, 10)); - m2::PointD pt(100, 100 + 50 * sqrt2); + PointD pt(100, 100 + 50 * sqrt2); - TEST(r1.ConvertTo(pt).EqualDxDy(m2::PointD(50, 50), 10e-5), ()); + TEST(r1.ConvertTo(pt).EqualDxDy(PointD(50, 50), 10e-5), ()); } UNIT_TEST(AnyRect_TestConvertFrom) { - m2::AnyRectD r(m2::PointD(100, 100), math::pi / 6, m2::RectD(0, 0, 10, 10)); + AnyRectD r(PointD(100, 100), math::pi / 6, RectD(0, 0, 10, 10)); double const sqrt3 = sqrt(3.0); - TEST(r.ConvertFrom(m2::PointD(50, 0)).EqualDxDy(m2::PointD(100 + 50 * sqrt3 / 2 , 100 + 50 * 1 / 2.0), 10e-5), ()); - TEST(r.ConvertTo(m2::PointD(100 + 50 * sqrt3 / 2, 100 + 50 * 1.0 / 2)).EqualDxDy(m2::PointD(50, 0), 10e-5), ()); + TEST(r.ConvertFrom(PointD(50, 0)).EqualDxDy(PointD(100 + 50 * sqrt3 / 2 , 100 + 50 * 1 / 2.0), 10e-5), ()); + TEST(r.ConvertTo(PointD(100 + 50 * sqrt3 / 2, 100 + 50 * 1.0 / 2)).EqualDxDy(PointD(50, 0), 10e-5), ()); } UNIT_TEST(AnyRect_ZeroRect) { - m2::AnyRectD r0(m2::RectD(0, 0, 0, 0)); - m2::PointD const centerPt(300.0, 300.0); - m2::AnyRectD r1(m2::Offset(r0, centerPt)); + AnyRectD r0(RectD(0, 0, 0, 0)); + PointD const centerPt(300.0, 300.0); + AnyRectD r1(Offset(r0, centerPt)); TEST_EQUAL(r1.GlobalCenter(), centerPt, ()); - m2::AnyRectD r2(m2::Inflate(r0, 2.0, 2.0)); - TEST_EQUAL(r2.GetLocalRect(), m2::RectD(-2, -2, 2, 2), ()); + AnyRectD r2(Inflate(r0, 2.0, 2.0)); + TEST_EQUAL(r2.GetLocalRect(), RectD(-2, -2, 2, 2), ()); } UNIT_TEST(AnyRect_TestIntersection) { - m2::AnyRectD r0(m2::PointD(93.196, 104.21), 1.03, m2::RectD(2, 0, 4, 15)); - m2::AnyRectD r1(m2::PointD(99.713, 116.02), -1.03, m2::RectD(0, 0, 14, 14)); + AnyRectD r0(PointD(93.196, 104.21), 1.03, RectD(2, 0, 4, 15)); + AnyRectD r1(PointD(99.713, 116.02), -1.03, RectD(0, 0, 14, 14)); - m2::PointD pts[4]; + array<PointD, 4> pts; r0.GetGlobalPoints(pts); - r1.ConvertTo(pts, 4); - m2::RectD r2(pts[0].x, pts[0].y, pts[0].x, pts[0].y); + r1.ConvertTo(pts); + RectD r2(pts[0].x, pts[0].y, pts[0].x, pts[0].y); r2.Add(pts[1]); r2.Add(pts[2]); r2.Add(pts[3]); @@ -58,29 +63,30 @@ UNIT_TEST(AnyRect_TestIntersection) UNIT_TEST(AnyRect_TestIsIntersect) { - m2::AnyRectD r0(m2::PointD(100, 100), math::pi / 6, m2::RectD(0, 0, 50, 20)); - m2::AnyRectD r1(m2::PointD(100, 100), math::pi / 6, m2::RectD(0, -10, 50, 10)); - m2::AnyRectD r2(m2::PointD(100, 100), math::pi / 6, m2::RectD(0, -21, 50, -1)); + AnyRectD r0(PointD(100, 100), math::pi / 6, RectD(0, 0, 50, 20)); + AnyRectD r1(PointD(100, 100), math::pi / 6, RectD(0, -10, 50, 10)); + AnyRectD r2(PointD(100, 100), math::pi / 6, RectD(0, -21, 50, -1)); TEST(r0.IsIntersect(r1), ()); TEST(r1.IsIntersect(r2), ()); TEST(!r0.IsIntersect(r2), ()); TEST(r1.IsIntersect(r2), ()); - m2::AnyRectD r3(m2::PointD(50, 50), math::pi / 8, m2::RectD(0, 0, 80, 30)); + AnyRectD r3(PointD(50, 50), math::pi / 8, RectD(0, 0, 80, 30)); TEST(r0.IsIntersect(r3), ()); } UNIT_TEST(AnyRect_SetSizesToIncludePoint) { - m2::AnyRectD rect(m2::PointD(100, 100), math::pi / 6, m2::RectD(0, 0, 50, 50)); + AnyRectD rect(PointD(100, 100), math::pi / 6, RectD(0, 0, 50, 50)); - TEST(!rect.IsPointInside(m2::PointD(0, 0)), ()); - TEST(!rect.IsPointInside(m2::PointD(200, 200)), ()); + TEST(!rect.IsPointInside(PointD(0, 0)), ()); + TEST(!rect.IsPointInside(PointD(200, 200)), ()); - rect.SetSizesToIncludePoint(m2::PointD(0, 0)); - TEST(rect.IsPointInside(m2::PointD(0, 0)), ()); + rect.SetSizesToIncludePoint(PointD(0, 0)); + TEST(rect.IsPointInside(PointD(0, 0)), ()); - rect.SetSizesToIncludePoint(m2::PointD(200, 200)); - TEST(rect.IsPointInside(m2::PointD(200, 200)), ()); + rect.SetSizesToIncludePoint(PointD(200, 200)); + TEST(rect.IsPointInside(PointD(200, 200)), ()); } +} // namespace m2 |