Simpact Cyan
Population based event driven simulation using mNRM
polygon2d.h
1 #ifndef POLYGON2D_H
2 
3 #define POLYGON2D_H
4 
5 #include "errut/errorbase.h"
6 #include <algorithm>
7 #include <vector>
8 
11 {
12 public:
13  Polygon2D() { m_numCoords = 0; }
14  ~Polygon2D() { }
15 
16  bool init(const std::vector<double> &xCoords, const std::vector<double> &yCoords);
17  bool init(const std::vector<std::pair<double, double> > &points);
18  bool init(const std::vector<Point2D> &points);
19  bool isInside(double x, double y) const;
20  int getNumberOfPoints() const { return m_numCoords; }
21 private:
22  std::vector<std::pair<double, double> > m_xyCoords;
23  int m_numCoords;
24 };
25 
26 inline bool Polygon2D::init(const std::vector<double> &xCoords, const std::vector<double> &yCoords)
27 {
28  if (xCoords.size() != yCoords.size())
29  {
30  setErrorString("Number of X and Y coordinates is not the same");
31  return false;
32  }
33 
34  std::vector<std::pair<double,double> > points(xCoords.size());
35 
36  for (int i = 0 ; i < xCoords.size() ; i++)
37  points[i] = std::pair<double, double>(xCoords[i], yCoords[i]);
38 
39  return init(points);
40 }
41 
42 inline bool Polygon2D::init(const std::vector<std::pair<double, double> > &points)
43 {
44  if (points.size() < 3)
45  {
46  setErrorString("Too few points to be a polygon");
47  return false;
48  }
49 
50  m_numCoords = points.size();
51  m_xyCoords.resize(m_numCoords+1);
52 
53  for (int i = 0 ; i < m_numCoords ; i++)
54  m_xyCoords[i] = points[i];
55 
56  m_xyCoords[m_numCoords] = points[0];
57 
58  return true;
59 }
60 
61 inline bool Polygon2D::init(const std::vector<Point2D> &points)
62 {
63  if (points.size() < 3)
64  {
65  setErrorString("Too few points to be a polygon");
66  return false;
67  }
68 
69  m_numCoords = points.size();
70  m_xyCoords.resize(m_numCoords+1);
71 
72  for (int i = 0 ; i < m_numCoords ; i++)
73  m_xyCoords[i] = std::pair<double, double>(points[i].x, points[i].y);
74 
75  m_xyCoords[m_numCoords] = std::pair<double, double>(points[0].x, points[0].y);
76 
77  return true;
78 }
79 
80 inline bool Polygon2D::isInside(double x, double y) const
81 {
82  int intersections = 0;
83 
84  for (int i = 0 ; i < m_numCoords ; i++)
85  {
86  double y1 = m_xyCoords[i].second;
87  double y2 = m_xyCoords[i+1].second;
88  double Y1 = y1;
89  double Y2 = y2;
90 
91  if (Y2 < Y1)
92  {
93  double tmp = Y1;
94  Y1 = Y2;
95  Y2 = tmp;
96  }
97 
98  if (Y1 < y && y <= Y2)
99  {
100  double x1 = m_xyCoords[i].first;
101  double x2 = m_xyCoords[i+1].first;
102 
103  if (x <= std::max(x1, x2))
104  {
105  if (x1 == x2)
106  intersections++;
107  else
108  {
109  double x0 = ((y - y1)*(x2 - x1))/(y2 - y1) + x1;
110 
111  if (x <= x0)
112  intersections++;
113  }
114  }
115  }
116  }
117  return (intersections&1)?true:false;
118 }
119 
120 #endif // GRALE_POLYGON2D_H
121 
Base class which allows an error message to be set.
Definition: errorbase.h:49
void setErrorString(const std::string &str) const
Derived classes can use this member function to store an error message.
Definition: errorbase.h:67
This class can be used to represent a polygon.
Definition: polygon2d.h:10