Project
Loading...
Searching...
No Matches
Polygon.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#ifndef O2_MCH_CONTOUR_POLYGON_H
16#define O2_MCH_CONTOUR_POLYGON_H
17
18#include <iostream>
19#include <utility>
20#include <vector>
21#include <initializer_list>
22#include <sstream>
23#include <algorithm>
24#include "BBox.h"
25#include "Vertex.h"
26
27namespace o2
28{
29namespace mch
30{
31namespace contour
32{
33
34template <typename T>
35class Polygon;
36
37template <typename T>
38std::vector<o2::mch::contour::Vertex<T>> getVertices(const Polygon<T>& polygon);
39
40template <typename T>
41std::vector<o2::mch::contour::Vertex<T>> getSortedVertices(const Polygon<T>& polygon);
42
43template <typename T>
45{
46 public:
47 using size_type = typename std::vector<o2::mch::contour::Vertex<T>>::size_type;
48
49 Polygon() = default;
50
51 template <typename InputIterator>
52 Polygon(InputIterator first, InputIterator last)
53 {
54 std::copy(first, last, std::back_inserter(mVertices));
55 }
56
57 Polygon(std::initializer_list<o2::mch::contour::Vertex<T>> args) : mVertices{args} {}
58
59 o2::mch::contour::Vertex<T> firstVertex() const { return mVertices.front(); }
60
61 size_type size() const { return mVertices.size(); }
62
63 bool empty() const { return size() == 0; }
64
65 o2::mch::contour::Vertex<T> operator[](int i) const { return mVertices[i]; }
66
67 bool isCounterClockwiseOriented() const { return signedArea() > 0.0; }
68
69 bool isManhattan() const
70 {
71 for (auto i = 0; i < mVertices.size() - 1; ++i) {
72 if (!isVertical(mVertices[i], mVertices[i + 1]) && !isHorizontal(mVertices[i], mVertices[i + 1])) {
73 return false;
74 }
75 }
76 return true;
77 }
78
79 bool isClosed() const { return mVertices.back() == mVertices.front(); }
80
81 bool contains(T x, T y) const;
82
83 double signedArea() const
84 {
88 double area{0.0};
89 for (auto i = 0; i < mVertices.size() - 1; ++i) {
90 auto& current = mVertices[i];
91 auto& next = mVertices[i + 1];
92 area += current.x * next.y - next.x * current.y;
93 }
94 return area * 0.5;
95 }
96
97 void scale(T sx, T sy)
98 {
99 for (auto i = 0; i < mVertices.size(); ++i) {
100 mVertices[i].x *= sx;
101 mVertices[i].y *= sy;
102 }
103 }
104
105 void translate(T dx, T dy)
106 {
107 for (auto i = 0; i < mVertices.size(); ++i) {
108 mVertices[i].x += dx;
109 mVertices[i].y += dy;
110 }
111 }
112
113 friend std::ostream& operator<<(std::ostream& os, const Polygon<T>& polygon)
114 {
115 os << "POLYGON(";
116 os << polygon.mVertices;
117 os << ")";
118 return os;
119 }
120
121 private:
122 std::vector<o2::mch::contour::Vertex<T>> mVertices;
123};
124
125template <typename T>
127{
128 if (!polygon.isClosed()) {
129 auto vertices = getVertices(polygon);
130 vertices.push_back(polygon.firstVertex());
131 Polygon<T> pol(vertices.begin(), vertices.end());
132 if (!pol.isManhattan()) {
133 throw std::logic_error("closing resulted in non Manhattan polygon");
134 }
135 return pol;
136 }
137 return polygon;
138}
139
140template <typename T>
141bool operator!=(const Polygon<T>& lhs, const Polygon<T>& rhs)
142{
143 return !(rhs == lhs);
144}
145
150template <typename T>
151bool operator==(const Polygon<T>& lhs, const Polygon<T>& rhs)
152{
153 if (lhs.size() != rhs.size()) {
154 return false;
155 }
156
157 auto l = getSortedVertices(lhs);
158 auto r = getSortedVertices(rhs);
159
160 if (l.size() != r.size()) {
161 return false;
162 }
163
164 for (auto i = 0; i < l.size(); ++i) {
165 if (l[i] != r[i]) {
166 return false;
167 }
168 }
169 return true;
170}
171
172template <typename T>
173bool Polygon<T>::contains(T xp, T yp) const
174{
175 // Note that this algorithm yields unpredicatable result if the point xp,yp
176 // is on one edge of the polygon. Should not generally matters, except when comparing
177 // two different implementations maybe.
178 //
179 // TODO : look e.g. to http://alienryderflex.com/polygon/ for some possible optimizations
180 // (e.g. pre-computation)
181 //
182 if (!isClosed()) {
183 throw std::invalid_argument("contains method can only work with closed polygons");
184 }
185
186 auto j = mVertices.size() - 1;
187 bool oddNodes{false};
188 for (auto i = 0; i < mVertices.size(); i++) {
189 if ((mVertices[i].y < yp && mVertices[j].y >= yp) || (mVertices[j].y < yp && mVertices[i].y >= yp)) {
190 if (mVertices[i].x +
191 (yp - mVertices[i].y) / (mVertices[j].y - mVertices[i].y) * (mVertices[j].x - mVertices[i].x) <
192 xp) {
193 oddNodes = !oddNodes;
194 }
195 }
196 j = i;
197 }
198 return oddNodes;
199}
200
201template <typename T>
202std::vector<o2::mch::contour::Vertex<T>> getVertices(const Polygon<T>& polygon)
203{
204 std::vector<o2::mch::contour::Vertex<T>> vertices;
205 vertices.reserve(polygon.size());
206 for (auto i = 0; i < polygon.size(); ++i) {
207 vertices.push_back(polygon[i]);
208 }
209 return vertices;
210}
211
212template <typename T>
213std::vector<o2::mch::contour::Vertex<T>> getSortedVertices(const Polygon<T>& polygon)
214{
215 std::vector<o2::mch::contour::Vertex<T>> vertices;
216 auto size = polygon.size();
217 if (polygon.isClosed()) {
218 --size;
219 }
220 vertices.reserve(size);
221 for (auto i = 0; i < size; ++i) {
222 vertices.push_back(polygon[i]);
223 }
224 std::sort(vertices.begin(), vertices.end());
225 return vertices;
226}
227
228template <typename T>
229BBox<T> getBBox(const std::vector<Vertex<T>>& vertices)
230{
231
232 T xmin{std::numeric_limits<T>::max()};
233 T xmax{std::numeric_limits<T>::lowest()};
234 T ymin{std::numeric_limits<T>::max()};
235 T ymax{std::numeric_limits<T>::lowest()};
236
237 for (const auto& v : vertices) {
238 xmin = std::min(xmin, v.x);
239 xmax = std::max(xmax, v.x);
240 ymin = std::min(ymin, v.y);
241 ymax = std::max(ymax, v.y);
242 }
243 return {xmin, ymin, xmax, ymax};
244}
245
246template <typename T>
248{
251
252 auto vertices = getVertices(polygon);
253 return getBBox(vertices);
254}
255
256template <typename T>
257BBox<T> getBBox(const std::vector<Polygon<T>>& polygons)
258{
261
262 T xmin{std::numeric_limits<T>::max()};
263 T xmax{std::numeric_limits<T>::lowest()};
264 T ymin{std::numeric_limits<T>::max()};
265 T ymax{std::numeric_limits<T>::lowest()};
266
267 for (const auto& p : polygons) {
268 auto b = getBBox(p);
269 xmin = std::min(xmin, b.xmin());
270 xmax = std::max(xmax, b.xmax());
271 ymin = std::min(ymin, b.ymin());
272 ymax = std::max(ymax, b.ymax());
273 }
274 return {xmin, ymin, xmax, ymax};
275}
276
277template <typename T>
278auto squaredDistancePointToPolygon(const Vertex<T>& point, const Polygon<T>& polygon) -> decltype(point.x * point.x)
279{
280 T d{std::numeric_limits<T>::max()};
281 for (auto i = 0; i < polygon.size() - 1; ++i) {
282 auto s0 = polygon[i];
283 auto s1 = polygon[i + 1];
284 auto d2 = squaredDistanceOfPointToSegment(point, s0, s1);
285 d = std::min(d2, d);
286 }
287 return d;
288}
289
290} // namespace contour
291} // namespace mch
292} // namespace o2
293
294#endif
int32_t i
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events d
uint32_t j
Definition RawData.h:0
void translate(T dx, T dy)
Definition Polygon.h:105
bool isClosed() const
Definition Polygon.h:79
bool isCounterClockwiseOriented() const
Definition Polygon.h:67
double signedArea() const
Definition Polygon.h:83
bool contains(T x, T y) const
Definition Polygon.h:173
size_type size() const
Definition Polygon.h:61
o2::mch::contour::Vertex< T > operator[](int i) const
Definition Polygon.h:65
Polygon(InputIterator first, InputIterator last)
Definition Polygon.h:52
void scale(T sx, T sy)
Definition Polygon.h:97
o2::mch::contour::Vertex< T > firstVertex() const
Definition Polygon.h:59
typename std::vector< o2::mch::contour::Vertex< T > >::size_type size_type
Definition Polygon.h:47
Polygon(std::initializer_list< o2::mch::contour::Vertex< T > > args)
Definition Polygon.h:57
bool isManhattan() const
Definition Polygon.h:69
friend std::ostream & operator<<(std::ostream &os, const Polygon< T > &polygon)
Definition Polygon.h:113
GLint GLenum GLint x
Definition glcorearb.h:403
GLsizeiptr size
Definition glcorearb.h:659
const GLdouble * v
Definition glcorearb.h:832
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition glcorearb.h:5034
GLint first
Definition glcorearb.h:399
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint y
Definition glcorearb.h:270
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
Definition glcorearb.h:5034
std::vector< o2::mch::contour::Vertex< T > > getVertices(const std::vector< o2::mch::contour::Polygon< T > > &polygons)
Definition Contour.h:31
auto squaredDistancePointToPolygon(const Vertex< T > &point, const Polygon< T > &polygon) -> decltype(point.x *point.x)
Definition Polygon.h:278
auto squaredDistanceOfPointToSegment(const Vertex< T > &p, const Vertex< T > &p0, const Vertex< T > &p1) -> decltype(p0.x *p1.x)
Definition Vertex.h:117
bool isHorizontal(const Vertex< T > &a, const Vertex< T > &b)
Definition Vertex.h:92
bool operator!=(const Contour< T > &lhs, const Contour< T > &rhs)
Definition Contour.h:126
BBox< T > getBBox(const Contour< T > &contour)
Definition Contour.h:176
Polygon< T > close(Polygon< T > polygon)
Definition Polygon.h:126
bool operator==(const Contour< T > &lhs, const Contour< T > &rhs)
Definition Contour.h:136
std::vector< o2::mch::contour::Vertex< T > > getSortedVertices(const std::vector< o2::mch::contour::Polygon< T > > &polygons)
Definition Contour.h:44
bool isVertical(const Vertex< T > &a, const Vertex< T > &b)
Definition Vertex.h:86
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...