BornAgain  1.18.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 scattering at grazing incidence
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/Types/Exceptions.h"
18 
19 #include <boost/geometry.hpp>
20 #include <boost/geometry/geometries/point_xy.hpp>
21 #include <boost/geometry/geometries/polygon.hpp>
22 
23 using namespace boost::geometry;
24 
25 //! The private data for polygons to hide boost dependency from the header
27 {
28 public:
29  typedef model::d2::point_xy<double> point_t;
30  typedef model::polygon<point_t> polygon_t;
32  void init_from(const std::vector<double>& x, const std::vector<double>& y);
33  void get_points(std::vector<double>& xpos, std::vector<double>& ypos);
34 };
35 
36 void PolygonPrivate::init_from(const std::vector<double>& x, const std::vector<double>& y)
37 {
38  if (x.size() != y.size())
40  "Polygon::Polygon(const std::vector<double>& x, const std::vector<double>& y) "
41  "Error. Sizes of arrays must conincide.");
42  std::vector<point_t> points;
43  for (size_t i = 0; i < x.size(); ++i)
44  points.push_back(point_t(x[i], y[i]));
45  assign_points(polygon, points);
46  correct(polygon);
47 }
48 
49 void PolygonPrivate::get_points(std::vector<double>& xpos, std::vector<double>& ypos)
50 {
51  xpos.clear();
52  ypos.clear();
53  for (auto it = polygon.outer().begin(); it != polygon.outer().end(); ++it) {
54  // for vectors of x and y, extract the x/y from the point
55  xpos.push_back(boost::geometry::get<0>(*it));
56  ypos.push_back(boost::geometry::get<1>(*it));
57  }
58 }
59 
60 //! @param x Vector of x-coordinates of polygon points.
61 //! @param y Vector of y-coordinates of polygon points.
62 
63 // IMPORTANT Input parameters are not "const reference" to be able to work from python
64 // (auto conversion of python list to vector<double>).
65 Polygon::Polygon(const std::vector<double> x, const std::vector<double> y)
66  : IShape2D("Polygon"), m_d(new PolygonPrivate)
67 {
68  m_d->init_from(x, y);
69 }
70 
71 // IMPORTANT Input parameter is not "const reference" to be able to work from python
72 // (auto conversion of python list to vector<vector<double>>).
73 //! Polygon defined by two dimensional array with (x,y) coordinates of polygon points.
74 //! The size of second dimension should be 2. If polygon is unclosed (the last point
75 //! doesn't repeat the first one), it will be closed automatically.
76 //! @param points Two dimensional vector of (x,y) coordinates of polygon points.
77 Polygon::Polygon(const std::vector<std::vector<double>> points)
78  : IShape2D("Polygon"), m_d(new PolygonPrivate)
79 {
80  std::vector<double> x;
81  std::vector<double> y;
82  for (size_t i = 0; i < points.size(); ++i) {
83  if (points[i].size() != 2)
85  "Polygon(const std::vector<std::vector<double> >& points) -> Error. "
86  " Should be two-dimensional array with second dimension of 2 size.");
87  x.push_back(points[i][0]);
88  y.push_back(points[i][1]);
89  }
90  m_d->init_from(x, y);
91 }
92 
93 Polygon::Polygon(const PolygonPrivate* d) : IShape2D("Polygon"), m_d(new PolygonPrivate(*d)) {}
94 
96 {
97  delete m_d;
98 }
99 
100 bool Polygon::contains(double x, double y) const
101 {
102  // return within(PolygonPrivate::point_t(x, y), m_d->polygon); // not including borders
103  return covered_by(PolygonPrivate::point_t(x, y), m_d->polygon); // including borders
104 }
105 
106 bool Polygon::contains(const Bin1D& binx, const Bin1D& biny) const
107 {
108  return contains(binx.getMidPoint(), biny.getMidPoint());
109 }
110 
111 double Polygon::getArea() const
112 {
113  return area(m_d->polygon);
114 }
115 
116 void Polygon::getPoints(std::vector<double>& xpos, std::vector<double>& ypos) const
117 {
118  m_d->get_points(xpos, ypos);
119 }
120 
121 void Polygon::print(std::ostream& ostr) const
122 {
123  ostr << wkt<PolygonPrivate::polygon_t>(m_d->polygon);
124 }
Defines structs Bin1D, Bin1DCVector.
Defines many exception classes in namespace Exceptionss.
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:27
model::polygon< point_t > polygon_t
Definition: Polygon.cpp:30
model::d2::point_xy< double > point_t
Definition: Polygon.cpp:29
polygon_t polygon
Definition: Polygon.cpp:31
void init_from(const std::vector< double > &x, const std::vector< double > &y)
Definition: Polygon.cpp:36
void get_points(std::vector< double > &xpos, std::vector< double > &ypos)
Definition: Polygon.cpp:49
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:100
PolygonPrivate * m_d
Definition: Polygon.h:52
void getPoints(std::vector< double > &xpos, std::vector< double > &ypos) const
Definition: Polygon.cpp:116
virtual void print(std::ostream &ostr) const
Definition: Polygon.cpp:121
Polygon(const std::vector< double > x, const std::vector< double > y)
Definition: Polygon.cpp:65
virtual ~Polygon()
Definition: Polygon.cpp:95
double getArea() const
Definition: Polygon.cpp:111
Definition: Bin.h:20
double getMidPoint() const
Definition: Bin.h:25