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:
authorYuri Gorshenin <y@maps.me>2016-02-02 14:51:48 +0300
committerSergey Yershov <yershov@corp.mail.ru>2016-03-23 16:16:43 +0300
commitb1c96c007315b4127522a2e1aa7af90d9d8501fd (patch)
tree3691705a01a1c78725ff3b9adc637235e70d1983 /geometry
parenta038f7cc6b468603d4aa329af830fe45c896fe63 (diff)
Review fixes.
Diffstat (limited to 'geometry')
-rw-r--r--geometry/geometry_tests/robust_test.cpp62
-rw-r--r--geometry/segment2d.cpp35
-rw-r--r--geometry/segment2d.hpp8
-rw-r--r--geometry/triangle2d.cpp4
4 files changed, 87 insertions, 22 deletions
diff --git a/geometry/geometry_tests/robust_test.cpp b/geometry/geometry_tests/robust_test.cpp
index d20703361f..fc54df02ac 100644
--- a/geometry/geometry_tests/robust_test.cpp
+++ b/geometry/geometry_tests/robust_test.cpp
@@ -11,17 +11,17 @@ namespace
{
using P = m2::PointD;
-template <typename IterT>
-void CheckSelfIntersections(IterT beg, IterT end, bool res)
+template <typename TIt>
+void CheckSelfIntersections(TIt beg, TIt end, bool res)
{
TEST_EQUAL(CheckPolygonSelfIntersections(beg, end), res, ());
- using ReverseIterT = reverse_iterator<IterT>;
- TEST_EQUAL(CheckPolygonSelfIntersections(ReverseIterT(end), ReverseIterT(beg)), res, ());
+ using TRevIt = reverse_iterator<TIt>;
+ TEST_EQUAL(CheckPolygonSelfIntersections(TRevIt(end), TRevIt(beg)), res, ());
}
-bool InsideSegment(P const & p, P const ps[])
+bool OnSegment(P const & p, P const ps[])
{
- return IsPointInsideSegment(p, ps[0], ps[1]);
+ return IsPointOnSegment(p, ps[0], ps[1]);
}
bool InsideTriangle(P const & p, P const ps[])
@@ -42,26 +42,48 @@ UNIT_TEST(Segment_Smoke)
double constexpr eps = 1.0E-10;
{
P ps[] = {{0, 0}, {1, 0}};
- TEST(InsideSegment(ps[0], ps), ());
- TEST(InsideSegment(ps[1], ps), ());
- TEST(InsideSegment(P(0.5, 0), ps), ());
+ TEST(OnSegment(ps[0], ps), ());
+ TEST(OnSegment(ps[1], ps), ());
+ TEST(OnSegment(P(0.5, 0), ps), ());
- TEST(InsideSegment(P(eps, 0), ps), ());
- TEST(InsideSegment(P(1.0 - eps, 0), ps), ());
+ TEST(OnSegment(P(eps, 0), ps), ());
+ TEST(OnSegment(P(1.0 - eps, 0), ps), ());
- TEST(!InsideSegment(P(-eps, 0), ps), ());
- TEST(!InsideSegment(P(1.0 + eps, 0), ps), ());
- TEST(!InsideSegment(P(eps, eps), ps), ());
- TEST(!InsideSegment(P(eps, -eps), ps), ());
+ TEST(!OnSegment(P(-eps, 0), ps), ());
+ TEST(!OnSegment(P(1.0 + eps, 0), ps), ());
+ TEST(!OnSegment(P(eps, eps), ps), ());
+ TEST(!OnSegment(P(eps, -eps), ps), ());
}
{
P ps[] = {{10, 10}, {10, 10}};
- TEST(InsideSegment(ps[0], ps), ());
- TEST(InsideSegment(ps[1], ps), ());
- TEST(!InsideSegment(P(10 - eps, 10), ps), ());
- TEST(!InsideSegment(P(10 + eps, 10), ps), ());
- TEST(!InsideSegment(P(0, 0), ps), ());
+ TEST(OnSegment(ps[0], ps), ());
+ TEST(OnSegment(ps[1], ps), ());
+ TEST(!OnSegment(P(10 - eps, 10), ps), ());
+ TEST(!OnSegment(P(10 + eps, 10), ps), ());
+ TEST(!OnSegment(P(0, 0), ps), ());
+ }
+
+ // Paranoid tests.
+ {
+ P ps[] = {{0, 0}, {1e100, 1e100}};
+ TEST(OnSegment(ps[0], ps), ());
+ TEST(OnSegment(ps[1], ps), ());
+ TEST(OnSegment(P(1e50, 1e50), ps), ());
+ TEST(!OnSegment(P(1e50, 1.00000000001e50), ps), ());
+
+ TEST(OnSegment(P(1e-100, 1e-100), ps), ());
+ TEST(!OnSegment(P(1e-100, 1e-100 + 1e-115), ps), ());
+ }
+
+ {
+ P ps[] = {{0, 0}, {2e100, 1e100}};
+ TEST(OnSegment(P(2.0 / 3.0, 1.0 / 3.0), ps), ());
+ }
+
+ {
+ P ps[] = {{0, 0}, {1e-15, 1e-15}};
+ TEST(!OnSegment(P(1e-16, 2.0 * 1e-16), ps), ());
}
}
diff --git a/geometry/segment2d.cpp b/geometry/segment2d.cpp
new file mode 100644
index 0000000000..bf7d05a12f
--- /dev/null
+++ b/geometry/segment2d.cpp
@@ -0,0 +1,35 @@
+#include "geometry/segment2d.hpp"
+
+#include "geometry/robust_orientation.hpp"
+
+#include "std/algorithm.hpp"
+
+namespace m2
+{
+bool IsPointOnSegment(m2::PointD const & pt, m2::PointD const & p1, m2::PointD const & p2)
+{
+ // The epsilon here is chosen quite arbitrarily, to pass paranoid
+ // tests and to match our real-data geometry precision. If you have
+ // better ideas how to check whether pt belongs to (p1, p2) segment
+ // more precisely or without kEps, feel free to submit a pull
+ // request.
+ double const kEps = 1e-100;
+
+ double const t = robust::OrientedS(p1, p2, pt);
+
+ if (fabs(t) > kEps)
+ return false;
+
+ double minX = p1.x;
+ double maxX = p2.x;
+ if (maxX < minX)
+ swap(maxX, minX);
+
+ double minY = p1.y;
+ double maxY = p2.y;
+ if (maxY < minY)
+ swap(maxY, minY);
+
+ return pt.x >= minX && pt.x <= maxX && pt.y >= minY && pt.y <= maxY;
+}
+} // namespace m2
diff --git a/geometry/segment2d.hpp b/geometry/segment2d.hpp
new file mode 100644
index 0000000000..e5e64bb054
--- /dev/null
+++ b/geometry/segment2d.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "geometry/point2d.hpp"
+
+namespace m2
+{
+bool IsPointOnSegment(m2::PointD const & pt, m2::PointD const & p1, m2::PointD const & p2);
+} // namespace m2
diff --git a/geometry/triangle2d.cpp b/geometry/triangle2d.cpp
index cbecf3a7f4..1bd0f56f4c 100644
--- a/geometry/triangle2d.cpp
+++ b/geometry/triangle2d.cpp
@@ -18,8 +18,8 @@ bool IsPointInsideTriangle(m2::PointD const & pt, m2::PointD const & p1,
// on (p1, p2), (p2, p3) or (p3, p1).
if (s1 == 0.0 && s2 == 0.0 && s3 == 0.0)
{
- return IsPointInsideSegment(pt, p1, p2) || IsPointInsideSegment(pt, p2, p3) ||
- IsPointInsideSegment(pt, p3, p1);
+ return IsPointOnSegment(pt, p1, p2) || IsPointOnSegment(pt, p2, p3) ||
+ IsPointOnSegment(pt, p3, p1);
}
return ((s1 >= 0.0 && s2 >= 0.0 && s3 >= 0.0) ||