Welcome to mirror list, hosted at ThFree Co, Russian Federation.

polyline2d.hpp « geometry - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d10c1cccf513e96877e9c035c25593c462192eca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#pragma once

#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"
#include "geometry/distance.hpp"

#include "base/internal/message.hpp"

#include "std/initializer_list.hpp"
#include "std/vector.hpp"

namespace m2
{

template <typename T>
class PolylineT
{
  vector<Point<T> > m_points;

public:
  PolylineT() {}
  PolylineT(initializer_list<Point<T> > points) : m_points(points)
  {
    ASSERT_GREATER(m_points.size(), 1, ());
  }
  explicit PolylineT(vector<Point<T> > const & points) : m_points(points)
  {
    ASSERT_GREATER(m_points.size(), 1, ());
  }
  template <class IterT> PolylineT(IterT beg, IterT end) : m_points(beg, end)
  {
    ASSERT_GREATER(m_points.size(), 1, ());
  }

  double GetLength() const
  {
    // @todo add cached value and lazy init
    double dist = 0;
    for (size_t i = 1; i < m_points.size(); ++i)
      dist += m_points[i-1].Length(m_points[i]);
    return dist;
  }

  double GetShortestSquareDistance(m2::Point<T> const & point) const
  {
    double res = numeric_limits<double>::max();
    m2::DistanceToLineSquare<m2::Point<T> > d;

    TIter i = Begin();
    for (TIter j = i + 1; j != End(); ++i, ++j)
    {
      d.SetBounds(*i, *j);
      res = min(res, d(point));
    }

    return res;
  }

  Rect<T> GetLimitRect() const
  {
    // @todo add cached value and lazy init
    m2::Rect<T> rect;
    for (size_t i = 0; i < m_points.size(); ++i)
      rect.Add(m_points[i]);
    return rect;
  }

  void Clear() { m_points.clear(); }
  void Add(Point<T> const & pt) { m_points.push_back(pt); }
  void Swap(PolylineT & rhs)
  {
    m_points.swap(rhs.m_points);
  }

  size_t GetSize() const { return m_points.size(); }

  bool operator==(PolylineT<T> const & rhs) const { return m_points == rhs.m_points; }

  typedef vector<Point<T> > TContainer;
  typedef typename TContainer::const_iterator TIter;
  TIter Begin() const { return m_points.begin(); }
  TIter End() const { return m_points.end(); }
  Point<T> const & Front() const { return m_points.front(); }
  Point<T> const & Back() const { return m_points.back(); }

  Point<T> const & GetPoint(size_t idx) const
  {
    ASSERT_LESS(idx, m_points.size(), ());
    return m_points[idx];
  }

  vector<Point<T> > const & GetPoints() const { return m_points; }

  friend string DebugPrint(PolylineT<T> const & p)
  {
    return ::DebugPrint(p.m_points);
  }
};

typedef PolylineT<double> PolylineD;

}