diff options
author | Alex Zolotarev <deathbaba@gmail.com> | 2010-12-05 19:24:16 +0300 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-22 22:33:57 +0300 |
commit | d6e12b7ce4bcbf0ccd1c07eb25de143422913c34 (patch) | |
tree | a7e910c330ce4da9b4f2d8be76067adece2561c4 /geometry/geometry_tests/intersect_test.cpp |
One Month In Minsk. Made in Belarus.
Diffstat (limited to 'geometry/geometry_tests/intersect_test.cpp')
-rw-r--r-- | geometry/geometry_tests/intersect_test.cpp | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/geometry/geometry_tests/intersect_test.cpp b/geometry/geometry_tests/intersect_test.cpp new file mode 100644 index 0000000000..803b5a1b33 --- /dev/null +++ b/geometry/geometry_tests/intersect_test.cpp @@ -0,0 +1,130 @@ +#include "../../base/SRC_FIRST.hpp" + +#include "equality.hpp" + +#include "../../testing/testing.hpp" + +#include "../../geometry/rect_intersect.hpp" +#include "../../geometry/angles.hpp" + +#include "../../base/start_mem_debug.hpp" + +using namespace test; + +m2::PointD get_point(m2::RectD const & r, int ind) +{ + switch (ind % 4) + { + case 0: return r.LeftBottom(); + case 1: return r.LeftTop(); + case 2: return r.RightTop(); + case 3: return r.RightBottom(); + default: + ASSERT ( false, () ); + return m2::PointD(); + } +} + +void make_section_longer(m2::PointD & p1, m2::PointD & p2, double sm = 10.0) +{ + if (p1.x == p2.x) + { + if (p1.y > p2.y) sm = -sm; + + p1.y -= sm; + p2.y += sm; + } + else if (p1.y == p2.y) + { + if (p1.x > p2.x) sm = -sm; + + p1.x -= sm; + p2.x += sm; + } + else + { + double const az = ang::AngleTo(p1, p2); + p1.Move(-sm, az); + p2.Move(sm, az); + } +} + +template <class TComp> +void check_full_equal(m2::RectD const & r, m2::PointD const & p1, m2::PointD const & p2, TComp comp) +{ + m2::PointD pp1 = p1; + m2::PointD pp2 = p2; + make_section_longer(pp1, pp2); + + TEST(m2::Intersect(r, pp1, pp2), ()); + TEST(comp(pp1, p1) && comp(pp2, p2), ()); +} + +void check_inside(m2::RectD const & r, m2::PointD p1, m2::PointD p2) +{ + double const sm = p1.Length(p2) / 4.0; + make_section_longer(p1, p2, -sm); + + m2::PointD pp1 = p1; + m2::PointD pp2 = p2; + TEST(m2::Intersect(r, p1, p2), ()); + TEST((pp1 == p1) && (pp2 == p2), ()); +} + +void check_intersect_boundaries(m2::RectD const & r) +{ + for (int i = 0; i < 4; ++i) + { + check_full_equal(r, get_point(r, i), get_point(r, i+1), strict_equal()); + check_inside(r, get_point(r, i), get_point(r, i+1)); + } +} + +void check_intersect_diagonal(m2::RectD const & r) +{ + for (int i = 0; i < 4; ++i) + { + check_full_equal(r, get_point(r, i), get_point(r, i+2), epsilon_equal()); + check_inside(r, get_point(r, i), get_point(r, i+2)); + } +} + +void check_sides(m2::RectD const & r) +{ + for (int i = 0; i < 4; ++i) + { + m2::PointD p1 = (get_point(r, i) + get_point(r, i+1)) / 2.0; + m2::PointD p2 = (get_point(r, i + 2) + get_point(r, i+3)) / 2.0; + check_full_equal(r, p1, p2, strict_equal()); + check_inside(r, p1, p2); + } +} + +void check_eps_boundaries(m2::RectD const & r, double eps = 1.0E-6) +{ + m2::RectD rr = r; + rr.Inflate(eps, eps); + + for (int i = 0; i < 4; ++i) + { + m2::PointD p1 = get_point(rr, i); + m2::PointD p2 = get_point(rr, i+1); + + TEST(!m2::Intersect(r, p1, p2), ()); + } + + rr = r; + rr.Inflate(-eps, -eps); + + for (int i = 0; i < 4; ++i) + check_inside(r, get_point(rr, i), get_point(rr, i+1)); +} + +UNIT_TEST(IntersectRectSection) +{ + m2::RectD r(-1, -1, 2, 2); + check_intersect_boundaries(r); + check_intersect_diagonal(r); + check_sides(r); + check_eps_boundaries(r); +} |