BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
Polygon.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Device/Mask/Polygon.cpp
6 //! @brief Implements class Polygon.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 #include "Device/Mask/Polygon.h"
16 #include "Base/Axis/Bin.h"
17 
18 #include <boost/geometry.hpp>
19 #include <boost/geometry/geometries/point_xy.hpp>
20 #include <boost/geometry/geometries/polygon.hpp>
21 
22 using namespace boost::geometry;
23 
24 //! The private data for polygons to hide boost dependency from the header
26 public:
27  typedef model::d2::point_xy<double> point_t;
28  typedef model::polygon<point_t> polygon_t;
30  void init_from(const std::vector<double>& x, const std::vector<double>& y);
31  void get_points(std::vector<double>& xpos, std::vector<double>& ypos);
32 };
33 
34 void PolygonPrivate::init_from(const std::vector<double>& x, const std::vector<double>& y)
35 {
36  if (x.size() != y.size())
37  throw std::runtime_error(
38  "Polygon::Polygon(const std::vector<double>& x, const std::vector<double>& y) "
39  "Error. Sizes of arrays must conincide.");
40  std::vector<point_t> points;
41  for (size_t i = 0; i < x.size(); ++i)
42  points.push_back(point_t(x[i], y[i]));
43  assign_points(polygon, points);
44  correct(polygon);
45 }
46 
47 void PolygonPrivate::get_points(std::vector<double>& xpos, std::vector<double>& ypos)
48 {
49  xpos.clear();
50  ypos.clear();
51  for (auto it = polygon.outer().begin(); it != polygon.outer().end(); ++it) {
52  // for vectors of x and y, extract the x/y from the point
53  xpos.push_back(boost::geometry::get<0>(*it));
54  ypos.push_back(boost::geometry::get<1>(*it));
55  }
56 }
57 
58 //! @param x Vector of x-coordinates of polygon points.
59 //! @param y Vector of y-coordinates of polygon points.
60 
61 // IMPORTANT Input parameters are not "const reference" to be able to work from python
62 // (auto conversion of python list to vector<double>).
63 Polygon::Polygon(const std::vector<double> x, const std::vector<double> y)
64  : IShape2D("Polygon"), m_d(new PolygonPrivate)
65 {
66  m_d->init_from(x, y);
67 }
68 
69 // IMPORTANT Input parameter is not "const reference" to be able to work from python
70 // (auto conversion of python list to vector<vector<double>>).
71 //! Polygon defined by two dimensional array with (x,y) coordinates of polygon points.
72 //! The size of second dimension should be 2. If polygon is unclosed (the last point
73 //! doesn't repeat the first one), it will be closed automatically.
74 //! @param points Two dimensional vector of (x,y) coordinates of polygon points.
75 Polygon::Polygon(const std::vector<std::vector<double>> points)
76  : IShape2D("Polygon"), m_d(new PolygonPrivate)
77 {
78  std::vector<double> x;
79  std::vector<double> y;
80  for (size_t i = 0; i < points.size(); ++i) {
81  if (points[i].size() != 2)
82  throw std::runtime_error(
83  "Polygon(const std::vector<std::vector<double> >& points) -> Error. "
84  " Should be two-dimensional array with second dimension of 2 size.");
85  x.push_back(points[i][0]);
86  y.push_back(points[i][1]);
87  }
88  m_d->init_from(x, y);
89 }
90 
91 Polygon::Polygon(const PolygonPrivate* d) : IShape2D("Polygon"), m_d(new PolygonPrivate(*d)) {}
92 
94 {
95  delete m_d;
96 }
97 
98 bool Polygon::contains(double x, double y) const
99 {
100  // return within(PolygonPrivate::point_t(x, y), m_d->polygon); // not including borders
101  return covered_by(PolygonPrivate::point_t(x, y), m_d->polygon); // including borders
102 }
103 
104 bool Polygon::contains(const Bin1D& binx, const Bin1D& biny) const
105 {
106  return contains(binx.center(), biny.center());
107 }
108 
109 double Polygon::getArea() const
110 {
111  return area(m_d->polygon);
112 }
113 
114 void Polygon::getPoints(std::vector<double>& xpos, std::vector<double>& ypos) const
115 {
116  m_d->get_points(xpos, ypos);
117 }
118 
119 void Polygon::print(std::ostream& ostr) const
120 {
121  ostr << wkt<PolygonPrivate::polygon_t>(m_d->polygon);
122 }
Defines structs Bin1D, Bin1DCVector.
Defines class Polygon.
Basic class for all shapes in 2D.
Definition: IShape2D.h:27
The private data for polygons to hide boost dependency from the header.
Definition: Polygon.cpp:25
model::polygon< point_t > polygon_t
Definition: Polygon.cpp:28
model::d2::point_xy< double > point_t
Definition: Polygon.cpp:27
polygon_t polygon
Definition: Polygon.cpp:29
void init_from(const std::vector< double > &x, const std::vector< double > &y)
Definition: Polygon.cpp:34
void get_points(std::vector< double > &xpos, std::vector< double > &ypos)
Definition: Polygon.cpp:47
virtual bool contains(double x, double y) const
Returns true if point with given coordinates is inside or on border of the shape.
Definition: Polygon.cpp:98
PolygonPrivate * m_d
Definition: Polygon.h:51
void getPoints(std::vector< double > &xpos, std::vector< double > &ypos) const
Definition: Polygon.cpp:114
virtual void print(std::ostream &ostr) const
Definition: Polygon.cpp:119
Polygon(const std::vector< double > x, const std::vector< double > y)
Definition: Polygon.cpp:63
virtual ~Polygon()
Definition: Polygon.cpp:93
double getArea() const
Definition: Polygon.cpp:109
Definition: Bin.h:20
double center() const
Definition: Bin.h:25