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:
authorVladimir Byko-Ianko <v.bykoianko@corp.mail.ru>2015-01-16 18:00:47 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:36:29 +0300
commitdf256d265d532446b83e2297f49bb6abb35a1ef5 (patch)
treed56a22a1a8e31677f984ff8c6f273b42ae2a2771 /geometry
parent45ddd3714cd6d108444f27579532ee677e49dfa2 (diff)
Drawing turn-arrows under the navigation route was implemented.
Diffstat (limited to 'geometry')
-rw-r--r--geometry/geometry_tests/point_test.cpp28
-rw-r--r--geometry/point2d.hpp35
2 files changed, 63 insertions, 0 deletions
diff --git a/geometry/geometry_tests/point_test.cpp b/geometry/geometry_tests/point_test.cpp
index 609ce8c84d..71eaa24964 100644
--- a/geometry/geometry_tests/point_test.cpp
+++ b/geometry/geometry_tests/point_test.cpp
@@ -57,3 +57,31 @@ UNIT_TEST(PointInTriangle_EmptyTriangle)
m2::PointD pt(27, 31);
TEST(!m2::IsPointStrictlyInsideTriangle(m2::PointD(0, 16), pt, pt, pt), ());
}
+
+/// @todo add more tests
+UNIT_TEST(ArrowPoints)
+{
+ m2::PointF p1, p2, p3;
+
+ m2::ArrowPoints(m2::PointF(0, 0), m2::PointF(1, 0), 1.f, 1.f, p1, p2, p3);
+ TEST(m2::AlmostEqual(p1, m2::PointF(1.f, 1.f)), ());
+ TEST(m2::AlmostEqual(p2, m2::PointF(2.f, 0.f)), ());
+ TEST(m2::AlmostEqual(p3, m2::PointF(1.f, -1.f)), ());
+
+ m2::PointD d1, d2, d3;
+ m2::ArrowPoints(m2::PointD(-1., 2.), m2::PointD(-1., 100.), 2., 5., d1, d2, d3);
+ TEST(m2::AlmostEqual(d1, m2::PointD(-3.f, 100.f)), ());
+ TEST(m2::AlmostEqual(d2, m2::PointD(-1.f, 105.f)), ());
+ TEST(m2::AlmostEqual(d3, m2::PointD(1.f, 100.f)), ());
+}
+
+UNIT_TEST(PointAtSegment)
+{
+ m2::PointF p1, p2, p3;
+
+ TEST(m2::AlmostEqual(m2::PointAtSegment(m2::PointF(0, 0), m2::PointF(1, 0), 0.5f), m2::PointF(0.5f, 0.f)), ());
+ TEST(m2::AlmostEqual(m2::PointAtSegment(m2::PointF(0, 0), m2::PointF(0, 1), 0.3f), m2::PointF(0.f, 0.3f)), ());
+ TEST(m2::AlmostEqual(m2::PointAtSegment(m2::PointD(0., 0.), m2::PointD(30., 40.), 5.), m2::PointD(3., 4.)), ());
+ TEST(m2::AlmostEqual(m2::PointAtSegment(m2::PointF(-3, -4), m2::PointF(-30, -40), 5.f), m2::PointF(-6.f, -8.f)), ());
+ TEST(m2::AlmostEqual(m2::PointAtSegment(m2::PointD(14., -48.), m2::PointD(70., -240.), 25.), m2::PointD(21., -72.)), ());
+}
diff --git a/geometry/point2d.hpp b/geometry/point2d.hpp
index c75ca2667e..f37195b4bf 100644
--- a/geometry/point2d.hpp
+++ b/geometry/point2d.hpp
@@ -142,6 +142,14 @@ namespace m2
double const module = this->Length();
return Point<T>(x / module, y / module);
}
+
+ pair<Point<T>, Point<T> > Normals(T prolongationFactor = 1) const
+ {
+ T const prolongatedX = prolongationFactor * x;
+ T const prolongatedY = prolongationFactor * y;
+ return 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)
@@ -311,6 +319,33 @@ namespace m2
return my::AlmostEqual(a.x, b.x, maxULPs) && my::AlmostEqual(a.y, b.y, maxULPs);
}
+ /// Calculate three point of a triangle (p1, p2 and p3) which gives a arrow at the end of segment s, f
+ /// with respect to w - arrow's width and l - arrow's length
+ template <typename T>
+ void ArrowPoints(Point<T> const & b, Point<T> const & e, T w, T l,
+ Point<T> & p1, Point<T> & p2, Point<T> & p3)
+ {
+ ASSERT(!m2::AlmostEqual(b, e), ());
+ Point<T> const beVec = e - b;
+ Point<T> beNormalizedVec = beVec.Normalize();
+ pair<Point<T>, Point<T> > beNormVecs = beNormalizedVec.Normals(w);
+
+ p1 = e + beNormVecs.first;
+ p2 = e + beNormalizedVec * l;
+ p3 = 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, 0.0, p12.Length());
+ return p1 + p12.Normalize() * shiftFromP1;
+ }
+
template <class TArchive, class PointT>
TArchive & operator >> (TArchive & ar, m2::Point<PointT> & pt)
{