BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
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 #include "Base/Util/Assert.h"
18 
19 #include <boost/geometry.hpp>
20 
21 //! The private data for polygons to hide boost dependency from the header
22 class PolygonPrivate {
23 public:
24  using point_t = boost::geometry::model::d2::point_xy<double>;
25  using polygon_t = boost::geometry::model::polygon<point_t>;
26  PolygonPrivate(const std::vector<double>& x, const std::vector<double>& y);
27  PolygonPrivate(const std::vector<std::pair<double, double>>& pts);
28  polygon_t polygon;
29  void get_points(std::vector<double>& xpos, std::vector<double>& ypos); // TODO const or no-&
30 };
31 
32 PolygonPrivate::PolygonPrivate(const std::vector<double>& x, const std::vector<double>& y)
33 {
34  ASSERT(x.size() == y.size());
35  std::vector<point_t> points;
36  for (size_t i = 0; i < x.size(); ++i)
37  points.emplace_back(x[i], y[i]);
38  boost::geometry::assign_points(polygon, points);
39  boost::geometry::correct(polygon);
40 }
41 
42 PolygonPrivate::PolygonPrivate(const std::vector<std::pair<double, double>>& pts)
43 {
44  std::vector<point_t> points;
45  for (const std::pair<double, double>& p : pts)
46  points.emplace_back(p.first, p.second);
47  boost::geometry::assign_points(polygon, points);
48  boost::geometry::correct(polygon);
49 }
50 
51 void PolygonPrivate::get_points(std::vector<double>& xpos, std::vector<double>& ypos)
52 {
53  xpos.clear();
54  ypos.clear();
55  for (auto it = polygon.outer().begin(); it != polygon.outer().end(); ++it) {
56  // for vectors of x and y, extract the x/y from the point
57  xpos.push_back(boost::geometry::get<0>(*it));
58  ypos.push_back(boost::geometry::get<1>(*it));
59  }
60 }
61 
62 // ************************************************************************************************
63 
64 //! @param x Vector of x-coordinates of polygon points.
65 //! @param y Vector of y-coordinates of polygon points.
66 
67 // IMPORTANT Input parameters are not "const reference" to be able to work from python
68 // (auto conversion of python list to vector<double>).
69 //! If polygon is unclosed (the last point doesn't repeat the first one), it will
70 //! be closed automatically.
71 Polygon::Polygon(const std::vector<double> x, const std::vector<double> y)
72  : IShape2D("Polygon")
73  , m_d(new PolygonPrivate(x, y))
74 {
75 }
76 
77 // IMPORTANT Input parameter is not "const reference" to be able to work from python
78 // (auto conversion of python list to vector<pair<double,double>>).
79 //! If polygon is unclosed (the last point doesn't repeat the first one), it will
80 //! be closed automatically.
81 //! @param points Two dimensional vector of (x,y) coordinates of polygon points.
82 Polygon::Polygon(const std::vector<std::pair<double, double>> points)
83  : IShape2D("Polygon")
84  , m_d(new PolygonPrivate(points))
85 {
86 }
87 
88 Polygon::Polygon(const PolygonPrivate* d)
89  : IShape2D("Polygon")
90  , m_d(new PolygonPrivate(*d))
91 {
92 }
93 
95 {
96  delete m_d;
97 }
98 
99 bool Polygon::contains(double x, double y) const
100 {
101  // including borders
102  return boost::geometry::covered_by(PolygonPrivate::point_t(x, y), m_d->polygon);
103 }
104 
105 bool Polygon::contains(const Bin1D& binx, const Bin1D& biny) const
106 {
107  return Polygon::contains(binx.center(), biny.center());
108 }
109 
110 double Polygon::getArea() const
111 {
112  return boost::geometry::area(m_d->polygon);
113 }
114 
115 void Polygon::getPoints(std::vector<double>& xpos, std::vector<double>& ypos) const
116 {
117  m_d->get_points(xpos, ypos);
118 }
119 
120 void Polygon::print(std::ostream& ostr) const
121 {
122  ostr << boost::geometry::wkt<PolygonPrivate::polygon_t>(m_d->polygon);
123 }
Defines the macro ASSERT.
#define ASSERT(condition)
Definition: Assert.h:45
Defines structs Bin1D, Bin1DCVector.
boost::geometry::model::d2::point_xy< double > point_t
Definition: Line.cpp:22
Defines class Polygon.
Definition: Bin.h:20
double center() const
Definition: Bin.h:30
Basic class for all shapes in 2D.
Definition: IShape2D.h:26
bool contains(double x, double y) const override
Returns true if point with given coordinates is inside or on border of the shape.
Definition: Polygon.cpp:99
Polygon(std::vector< double > x, std::vector< double > y)
If polygon is unclosed (the last point doesn't repeat the first one), it will be closed automatically...
Definition: Polygon.cpp:71
PolygonPrivate * m_d
Definition: Polygon.h:51
void getPoints(std::vector< double > &xpos, std::vector< double > &ypos) const
Definition: Polygon.cpp:115
void print(std::ostream &ostr) const override
Definition: Polygon.cpp:120
~Polygon() override
Definition: Polygon.cpp:94
double getArea() const
Definition: Polygon.cpp:110