Belle II Software development
ParameterLine2D.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#pragma once
9
10#include <tracking/trackingUtilities/geometry/GeneralizedCircle.h>
11#include <tracking/trackingUtilities/geometry/Line2D.h>
12#include <tracking/trackingUtilities/geometry/VectorUtil.h>
13
14#include <tracking/trackingUtilities/numerics/Quadratic.h>
15#include <tracking/trackingUtilities/numerics/EForwardBackward.h>
16#include <tracking/trackingUtilities/numerics/ERightLeft.h>
17#include <tracking/trackingUtilities/numerics/ERotation.h>
18#include <tracking/trackingUtilities/numerics/ESign.h>
19
20#include <Math/Vector2D.h>
21
22#include <utility>
23#include <cmath>
24#include <iosfwd>
25
26namespace Belle2 {
31 namespace TrackingUtilities {
32
34
41
42 public:
45 : m_support(0.0, 0.0)
46 , m_tangential(0.0, 0.0)
47 {
48 }
49
51 ParameterLine2D(const ROOT::Math::XYVector& support, const ROOT::Math::XYVector& tangential)
54 {
55 }
56
58
61 static ParameterLine2D fromSlopeIntercept(const double slope, const double intercept)
62 {
63 return ParameterLine2D(ROOT::Math::XYVector(0.0, intercept), ROOT::Math::XYVector(1.0, slope));
64 }
65
68
72 const double intercept,
73 const EForwardBackward orientation)
74 {
75 return ParameterLine2D(ROOT::Math::XYVector(0.0, intercept),
76 ROOT::Math::XYVector(orientation, static_cast<double>(orientation) * slope));
77 }
78
80
84 static ParameterLine2D throughPoints(const ROOT::Math::XYVector& start, const ROOT::Math::XYVector& end)
85 {
86 return ParameterLine2D(start, end - start);
87 }
88
90
95 explicit ParameterLine2D(const Line2D& line)
96 : m_support(line.support())
97 , m_tangential(line.tangential())
98 {
99 }
100
102
110 static ParameterLine2D touchingCircles(const ROOT::Math::XYVector& fromCenter,
111 double fromSignedRadius,
112 const ROOT::Math::XYVector& toCenter,
113 double toSignedRadius);
114
116
120 operator Line2D()
121 {
122 return Line2D(distanceToOrigin(), VectorUtil::unit(normal()));
123 } // not optimal yet. tangential.R() is getting calculated two times.
124
125 public:
127 const ROOT::Math::XYVector& tangential() const
128 {
129 return m_tangential;
130 }
131
132 ROOT::Math::XYVector normal() const
133 {
134 return VectorUtil::Orthogonal(tangential(), ERotation::c_Clockwise);
135 }
136
138 const ROOT::Math::XYVector& support() const
139 {
140 return m_support;
141 }
142
144 ROOT::Math::XYVector at(const double parameter) const
145 {
146 return tangential() * parameter += support();
147 }
148
151 EForwardBackward alignedWithFirst() const
152 {
153 return static_cast<EForwardBackward>(sign(tangential().X()));
154 }
155
158 EForwardBackward alignedWithSecond() const
159 {
160 return static_cast<EForwardBackward>(sign(tangential().Y()));
161 }
162
164
170 {
171 if (m_tangential.R() != 0.0) {
172 m_tangential *= (1. / m_tangential.R());
173 }
174 }
175
178 {
179 m_support.SetXY(0, 0);
180 m_tangential.SetXY(0, 0);
181 }
182
184 bool isInvalid() const
185 {
186 return VectorUtil::isNull(m_tangential);
187 }
188
190 void reverse()
191 {
193 }
194
197 {
198 return ParameterLine2D(support(), -tangential());
199 }
200
201 public:
203
205 double distance(const ROOT::Math::XYVector& point) const
206 {
207 return distanceToOrigin() - VectorUtil::orthogonalComp(point, tangential());
208 }
209
211
213 double distance(const double first, const double second) const
214 {
215 return distance(ROOT::Math::XYVector(first, second));
216 }
217
219 double distanceToOrigin() const
220 {
221 return VectorUtil::orthogonalComp(support(), tangential());
222 }
223
225 double absoluteDistance(const ROOT::Math::XYVector& point) const
226 {
227 return fabs(distance(point));
228 }
229
231 ERightLeft isRightOrLeft(const ROOT::Math::XYVector& point) const
232 {
233 return static_cast<ERightLeft>(sign(distance(point)));
234 }
235
237 bool isLeft(const ROOT::Math::XYVector& rhs) const
238 {
239 return isRightOrLeft(rhs) == ERightLeft::c_Left;
240 }
241
243 bool isRight(const ROOT::Math::XYVector& rhs) const
244 {
245 return isRightOrLeft(rhs) == ERightLeft::c_Right;
246 }
247
249 ROOT::Math::XYVector closest(const ROOT::Math::XYVector& point) const
250 {
251 double norm_squared = tangential().Mag2();
252 return VectorUtil::compose(tangential(),
253 tangential().Dot(point) / norm_squared,
254 VectorUtil::Cross(tangential(), support()) / norm_squared);
255 }
256
258 double closestAt(const ROOT::Math::XYVector& point) const
259 {
260 return (tangential().Dot(point) - tangential().Dot(support())) / tangential().Mag2();
261 }
262
264 ROOT::Math::XYVector closestToOrigin() const
265 {
266 return VectorUtil::Orthogonal(tangential()) *
267 (VectorUtil::Cross(tangential(), support()) / tangential().Mag2());
268 }
269
271 double closestToOriginAt() const
272 {
273 return -tangential().Dot(support()) / tangential().Mag2();
274 }
275
277 double lengthOnCurve(const ROOT::Math::XYVector& from, const ROOT::Math::XYVector& to) const
278 {
279 return (to.Dot(tangential()) - from.Dot(tangential())) / tangential().R();
280 }
281
283 double intersectionAt(const Line2D& line) const
284 {
285 return -(line.n0() + support().Dot(line.normal())) / tangential().Dot(line.normal());
286 }
287
289 double intersectionAt(const ParameterLine2D& line) const
290 {
291 return (VectorUtil::Cross(line.tangential(), support()) - VectorUtil::Cross(line.tangential(), line.support())) /
292 VectorUtil::Cross(tangential(), line.tangential());
293 }
294
296
300 std::pair<double, double> intersectionsAt(const GeneralizedCircle& genCircle) const
301 {
302 double a = genCircle.n3() * tangential().Mag2();
303 double b = tangential().Dot(genCircle.gradient(support()));
304 double c = genCircle.fastDistance(support());
305
306 return solveQuadraticABC(a, b, c);
307 }
308
310 ROOT::Math::XYVector intersection(const Line2D& line) const
311 {
312 return at(intersectionAt(line));
313 }
314
316 ROOT::Math::XYVector intersection(const ParameterLine2D& line) const
317 {
318 return at(intersectionAt(line));
319 }
320
324
327 void passiveMoveAtBy(const double delta)
328 {
329 m_support += tangential() * delta;
330 }
331
333 void moveBy(const ROOT::Math::XYVector& by)
334 {
335 m_support += by;
336 }
337
340 void moveAlongFirst(const double first)
341 {
342 m_support.SetX(m_support.X() + first);
343 }
344
347 void moveAlongSecond(const double second)
348 {
349 m_support.SetY(m_support.Y() + second);
350 }
351
354 void passiveMoveBy(const ROOT::Math::XYVector& by)
355 {
356 m_support -= by;
357 }
358
361 void passiveMoveAlongFirst(const double first)
362 {
363 m_support.SetX(m_support.X() - first);
364 }
365
368 void passiveMoveAlongSecond(const double second)
369 {
370 m_support.SetY(m_support.Y() - second);
371 }
372
373
378
380 double slope() const
381 {
382 return tangential().Y() / tangential().X();
383 }
384
386 double inverseSlope() const
387 {
388 return tangential().X() / tangential().Y();
389 }
390
392 double intercept() const
393 {
394 return support().Y() - slope() * support().X();
395 }
396
398 double zero() const
399 {
400 return support().X() - inverseSlope() * support().Y();
401 }
402
404 double map(const double first) const
405 {
406 return support().Y() + slope() * (first - support().X());
407 }
408
410 double operator()(const double first) const
411 {
412 return map(first);
413 }
414
416 double inverseMap(const double second) const
417 {
418 return support().X() + inverseSlope() * (second - support().Y());
419 }
420
422 void invert()
423 {
424 m_tangential.SetXY(m_tangential.Y(), m_tangential.X());
425 m_support.SetXY(m_support.Y(), m_support.X());
426 }
427
430 {
431 return ParameterLine2D(ROOT::Math::XYVector(support().Y(), support().X()),
432 ROOT::Math::XYVector(tangential().Y(), tangential().X()));
433 }
434
435
436 private:
438 ROOT::Math::XYVector m_support;
439
441 ROOT::Math::XYVector m_tangential;
442 };
443
445 std::ostream& operator<<(std::ostream& output, const ParameterLine2D& line);
446 }
448}
ROOT::Math::XYVector gradient(const ROOT::Math::XYVector &point) const
Gradient of the distance field Gives the gradient of the approximated distance field for the given po...
double fastDistance(const ROOT::Math::XYVector &point) const
Approximate distance.
double n3() const
Getter for the fourth circle parameter.
A two dimensional normal line.
Definition Line2D.h:39
A line with a support point and tangential vector.
ParameterLine2D()
Default constructor for ROOT compatibility.
EForwardBackward alignedWithFirst() const
Indicates if the tangential vector point in a common direction with the first coordinate axes.
static ParameterLine2D fromSlopeIntercept(const double slope, const double intercept)
Constructs a line with slope and intercept.
bool isRight(const ROOT::Math::XYVector &rhs) const
Return if the point given is right of the line.
ROOT::Math::XYVector normal() const
Gives the normal vector of the line.
double zero() const
First coordinate for second being zero.
static ParameterLine2D fromSlopeIntercept(const double slope, const double intercept, const EForwardBackward orientation)
Constructs a line with slope and intercept.
bool isInvalid() const
Check it the line is in an invalid state.
void reverse()
Reverses the tangential vector inplace.
ROOT::Math::XYVector intersection(const Line2D &line) const
Gives the point where the two lines meet. Infinities for parallels.
const ROOT::Math::XYVector & support() const
Gives the support vector of the line.
static ParameterLine2D throughPoints(const ROOT::Math::XYVector &start, const ROOT::Math::XYVector &end)
Static constructor for a line between to points.
double map(const double first) const
Method mapping the first coordinate to the second according to the line.
void moveBy(const ROOT::Math::XYVector &by)
Moves the line in the given direction in place. Corresponds to an active transformation.
ParameterLine2D(const Line2D &line)
Upcast the normal representation to a parameter line.
bool isLeft(const ROOT::Math::XYVector &rhs) const
Return if the point given is left of the line.
ROOT::Math::XYVector closest(const ROOT::Math::XYVector &point) const
Gives the position at the closest approach on the line to point.
ROOT::Math::XYVector closestToOrigin() const
Gives the position of closest approach to the origin.
double closestAt(const ROOT::Math::XYVector &point) const
Gives the line parameter at the closest approach to point.
std::pair< double, double > intersectionsAt(const GeneralizedCircle &genCircle) const
Gives the line parameters of this line, where it intersects with the generalized circle.
double distanceToOrigin() const
Gives the signed distance of the origin.
double intercept() const
Second coordinate for first being zero.
void moveAlongFirst(const double first)
Moves the line along the first coordinate axes in place.
double intersectionAt(const Line2D &line) const
Gives the line parameter where the two lines meet. Infinity for parallels.
void passiveMoveAtBy(const double delta)
Moves the support point by the given amount of the parameter in the forward direction.
ROOT::Math::XYVector m_support
Support vector of the line.
double inverseSlope() const
The inverse line slope.
double inverseMap(const double second) const
Method for the inverse mapping the second coordinate to the first according to the line.
double operator()(const double first) const
Operator mapping the first coordinate to the second according to the line.
ParameterLine2D(const ROOT::Math::XYVector &support, const ROOT::Math::XYVector &tangential)
Standard constructor taking the support point and the tangential vector.
double distance(const ROOT::Math::XYVector &point) const
Gives the signed distance of a point to the line.
void invert()
Turns the line into its inverse function in place. Orientation will be flipped as well.
void passiveMoveAlongFirst(const double first)
Moves the coordinate system along the first coordinate axes in place.
void invalidate()
Clear all information from the line.
ERightLeft isRightOrLeft(const ROOT::Math::XYVector &point) const
Return if the point given is right or left of the line.
ParameterLine2D reversed() const
Makes a copy line which has the opposite tangential vector but same support point.
void passiveMoveBy(const ROOT::Math::XYVector &by)
Moves the coordinate system in the given direction in place.
ROOT::Math::XYVector intersection(const ParameterLine2D &line) const
Gives the point where the two lines meet. Infinities for parallels.
EForwardBackward alignedWithSecond() const
Indicates if the tangential vector point in a common direction with the second coordinate axes.
double intersectionAt(const ParameterLine2D &line) const
Gives the line parameter of this line where the two lines meet. Infinity for parallels.
ParameterLine2D inverted() const
Gives the line associated with the inverse function as a copy.
double distance(const double first, const double second) const
Calculates the signed distance of the point given by its to coordinates to the line.
double absoluteDistance(const ROOT::Math::XYVector &point) const
Gives the unsigned distance of a point to the line.
void normalize()
Normalizes the tangential vector inplace.
void passiveMoveAlongSecond(const double second)
Moves the coordinate system along the second coordinate axes in place.
const ROOT::Math::XYVector & tangential() const
Gives the tangential vector of the line.
ROOT::Math::XYVector at(const double parameter) const
Evaluates the line formula at the parameter given.
double lengthOnCurve(const ROOT::Math::XYVector &from, const ROOT::Math::XYVector &to) const
Denotes the length on the line between the two points.
double closestToOriginAt() const
Gives the line parameter at the closest approach to the origin.
ROOT::Math::XYVector m_tangential
Tangential vector of the line.
void moveAlongSecond(const double second)
Moves the line along the second coordinate axes in place.
static ParameterLine2D touchingCircles(const ROOT::Math::XYVector &fromCenter, double fromSignedRadius, const ROOT::Math::XYVector &toCenter, double toSignedRadius)
Constructs a line touching two circles in one point each.
Abstract base class for different kinds of events.