Project
Loading...
Searching...
No Matches
IntervalXY.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
16
17#ifndef MATHUTILS_INCLUDE_MATHUTILS_DETAIL_INTERVALXY_H_
18#define MATHUTILS_INCLUDE_MATHUTILS_DETAIL_INTERVALXY_H_
19
20#include "GPUCommonDef.h"
21#include "GPUCommonRtypes.h"
22#include "GPUCommonMath.h"
23#ifndef GPUCA_GPUCODE_DEVICE
24#include <cmath>
25#include <tuple>
26#endif
27
29
30namespace o2
31{
32namespace math_utils
33{
34namespace detail
35{
36
37template <typename T>
39{
40 public:
41 using value_t = T;
42
44 GPUd() IntervalXY(T x = T(), T y = T(), T dx = T(), T dy = T());
45 GPUd() T getX0() const;
46 GPUd() T getY0() const;
47 GPUd() T& getX0();
48 GPUd() T& getY0();
49 GPUd() T getX1() const;
50 GPUd() T getY1() const;
51 GPUd() T getDX() const;
52 GPUd() T getDY() const;
53 GPUd() T& getDX();
54 GPUd() T& getDY();
55
56 GPUd() void setX0(T x0);
57 GPUd() void setY0(T y0);
58 GPUd() void setX1(T x1);
59 GPUd() void setY1(T y1);
60 GPUd() void setDX(T dx);
61 GPUd() void setDY(T dy);
62 GPUd() void setEdges(T x0, T y0, T x1, T y1);
63
64 GPUd() void eval(T t, T& x, T& y) const;
65#ifndef GPUCA_GPUCODE_DEVICE
66 std::tuple<T, T> eval(T t) const;
67#endif
68
69 GPUd() void getLineCoefs(T& a, T& b, T& c) const;
70
79 GPUd() bool seenByCircle(const CircleXY<T>& circle, T eps) const;
80
81 GPUd() bool circleCrossParam(const CircleXY<T>& circle, T& t) const;
82
92 GPUd() bool seenByLine(const IntervalXY<T>& other, T eps) const;
93
97 GPUd() bool lineCrossParam(const IntervalXY<T>& other, T& t) const;
98
99 private:
100 T mX, mY;
101 T mDx, mDY;
102
103 ClassDefNV(IntervalXY, 2);
104};
105
106template <typename T>
107GPUdi() IntervalXY<T>::IntervalXY(T x, T y, T dx, T dy) : mX(x), mY(y), mDx(dx), mDY(dy)
108{
109}
110
111template <typename T>
112GPUdi() T IntervalXY<T>::getX0() const
113{
114 return mX;
115}
116
117template <typename T>
118GPUdi() T IntervalXY<T>::getY0() const
119{
120 return mY;
121}
122
123template <typename T>
124GPUdi() T& IntervalXY<T>::getX0()
125{
126 return mX;
127}
128
129template <typename T>
130GPUdi() T& IntervalXY<T>::getY0()
131{
132 return mY;
133}
134
135template <typename T>
136GPUdi() T IntervalXY<T>::getX1() const
137{
138 return mX + mDx;
139}
140template <typename T>
141GPUdi() T IntervalXY<T>::getY1() const
142{
143 return mY + mDY;
144}
145template <typename T>
146GPUdi() T IntervalXY<T>::getDX() const
147{
148 return mDx;
149}
150template <typename T>
151GPUdi() T IntervalXY<T>::getDY() const
152{
153 return mDY;
154}
155
156template <typename T>
157GPUdi() T& IntervalXY<T>::getDX()
158{
159 return mDx;
160}
161template <typename T>
162GPUdi() T& IntervalXY<T>::getDY()
163{
164 return mDY;
165}
166
167template <typename T>
168GPUdi() void IntervalXY<T>::setX0(T x0)
169{
170 mX = x0;
171}
172
173template <typename T>
174GPUdi() void IntervalXY<T>::setY0(T y0)
175{
176 mY = y0;
177}
178template <typename T>
179GPUdi() void IntervalXY<T>::setX1(T x1)
180{
181 mDx = x1 - mX;
182}
183template <typename T>
184GPUdi() void IntervalXY<T>::setY1(T y1)
185{
186 mDY = y1 - mY;
187}
188template <typename T>
189GPUdi() void IntervalXY<T>::setDX(T dx)
190{
191 mDx = dx;
192}
193template <typename T>
194GPUdi() void IntervalXY<T>::setDY(T dy)
195{
196 mDY = dy;
197}
198
199template <typename T>
200GPUdi() void IntervalXY<T>::setEdges(T x0, T y0, T x1, T y1)
201{
202 mX = x0;
203 mY = y0;
204 mDx = x1 - x0;
205 mDY = y1 - y0;
206}
207
208#ifndef GPUCA_GPUCODE_DEVICE
209template <typename T>
210std::tuple<T, T> IntervalXY<T>::eval(T t) const
211{
212 return {mX + t * mDx, mY + t * mDY};
213}
214#endif
215
216template <typename T>
217GPUdi() void IntervalXY<T>::eval(T t, T& x, T& y) const
218{
219 x = mX + t * mDx;
220 y = mY + t * mDY;
221}
222
223template <typename T>
224GPUdi() void IntervalXY<T>::getLineCoefs(T& a, T& b, T& c) const
225{
226 // convert to line parameters in canonical form: a*x+b*y+c = 0
227 c = mX * mDY - mY * mDx;
228 if (c) {
229 a = -mDY;
230 b = mDx;
231 } else if (fabs(mDx) > fabs(mDY)) {
232 a = 0.;
233 b = -1.;
234 c = mY;
235 } else {
236 a = -1.;
237 b = 0.;
238 c = mX;
239 }
240}
241
242template <typename T>
243GPUdi() bool IntervalXY<T>::seenByCircle(const CircleXY<T>& circle, T eps) const
244{
245 T dx0 = mX - circle.xC;
246 T dy0 = mY - circle.yC;
247 T dx1 = dx0 + mDx;
248 T dy1 = dy0 + mDY;
249 if (eps > 0.) {
250 const T dxeps = eps * mDx, dyeps = eps * mDY;
251 dx0 -= dxeps;
252 dx1 += dxeps;
253 dy0 -= dyeps;
254 dy1 += dyeps;
255 }
256 // distance^2 from circle center to edges
257 const T d02 = dx0 * dx0 + dy0 * dy0;
258 const T d12 = dx1 * dx1 + dy1 * dy1;
259 const T rC2 = circle.rC * circle.rC;
260
261 return (d02 - rC2) * (d12 - rC2) < 0;
262}
263template <typename T>
264GPUdi() bool IntervalXY<T>::circleCrossParam(const CircleXY<T>& circle, T& t) const
265{
266 const T dx = mX - circle.xC;
267 const T dy = mY - circle.yC;
268 const T del2I = 1.f / (mDx * mDx + mDY * mDY);
269 const T b = (dx * mDx + dy * mDY) * del2I;
270 const T c = del2I * (dx * dx + dy * dy - circle.rC * circle.rC);
271 T det = b * b - c;
272 if (det < 0.f) {
273 return false;
274 }
275 det = gpu::CAMath::Sqrt(det);
276 const T t0 = -b - det;
277 const T t1 = -b + det;
278 // select the one closer to [0:1] interval
279 t = (gpu::CAMath::Abs(t0 - 0.5f) < gpu::CAMath::Abs(t1 - 0.5f)) ? t0 : t1;
280 return true;
281}
282
283template <typename T>
284GPUdi() bool IntervalXY<T>::seenByLine(const IntervalXY<T>& other, T eps) const
285{
286 T a, b, c; // find equation of the line a*x+b*y+c = 0
287 other.getLineCoefs(a, b, c);
288 T x0, y0, x1, y1;
289 eval(-eps, x0, y0);
290 eval(1.f + eps, x1, y1);
291
292 return (a * x0 + b * y0 + c) * (a * x1 + b * y1 + c) < 0;
293}
294
295template <typename T>
296GPUdi() bool IntervalXY<T>::lineCrossParam(const IntervalXY<T>& other, T& t) const
297{
298 // tolerance
299 constexpr float eps = 1.e-9f;
300 const T dx = other.getX0() - mX;
301 const T dy = other.getY0() - mY;
302 const T det = -mDx * other.getY0() + mDY * other.getX0();
303 if (gpu::CAMath::Abs(det) < eps) {
304 return false; // parallel
305 }
306 t = (-dx * other.getY0() + dy * other.getX0()) / det;
307 return true;
308}
309
310} // namespace detail
311} // namespace math_utils
312} // namespace o2
313
314#endif /* MATHUTILS_INCLUDE_MATHUTILS_DETAIL_INTERVALXY_H_ */
T value_t
2D interval in lab frame defined by its one edge and signed projection lengths on X,...
Definition IntervalXY.h:43
std::tuple< T, T > eval(T t) const
Definition IntervalXY.h:210
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint GLfloat GLfloat GLfloat GLfloat y1
Definition glcorearb.h:5034
GLuint GLfloat GLfloat GLfloat x1
Definition glcorearb.h:5034
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLuint GLfloat x0
Definition glcorearb.h:5034
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition glcorearb.h:5034
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLuint GLfloat GLfloat y0
Definition glcorearb.h:5034
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition glcorearb.h:5034
GPUdi() int nint(T x)
Definition basicMath.h:66
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
VectorOfTObjectPtrs other