Belle II Software  release-08-01-10
Vector2D.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/trackFindingCDC/numerics/Quadratic.h>
11 
12 #include <tracking/trackFindingCDC/numerics/EForwardBackward.h>
13 #include <tracking/trackFindingCDC/numerics/ERightLeft.h>
14 #include <tracking/trackFindingCDC/numerics/ERotation.h>
15 #include <tracking/trackFindingCDC/numerics/ESign.h>
16 
17 #include <utility>
18 #include <string>
19 #include <iosfwd>
20 #include <cmath>
21 
22 class TVector2;
23 
24 namespace Belle2 {
29  namespace TrackFindingCDC {
35  class Vector2D {
36 
37  public:
40  : m_x(0.0)
41  , m_y(0.0)
42  {
43  }
44 
46  explicit Vector2D(const TVector2& tVector2);
47 
49  Vector2D(const double x, const double y)
50  : m_x(x)
51  , m_y(y)
52  {
53  }
54 
61  Vector2D(const Vector2D& coordinateVec, const double parallelCoor, const double orthoCoor)
62  : m_x(coordinateVec.x() * parallelCoor - coordinateVec.y() * orthoCoor)
63  , m_y(coordinateVec.y() * parallelCoor + coordinateVec.x() * orthoCoor)
64  {
65  }
66 
68  Vector2D& operator=(const TVector2& tvector);
69 
71  static Vector2D Phi(const double phi)
72  {
73  return std::isnan(phi) ? Vector2D(0.0, 0.0) : Vector2D(cos(phi), sin(phi));
74  }
75 
78 
82  static Vector2D
83  compose(const Vector2D& coordinateVec, const double parallelCoor, const double orthoCoor)
84  {
85  return Vector2D(coordinateVec, parallelCoor, orthoCoor);
86  }
87 
89 
93  static Vector2D average(const Vector2D& one, const Vector2D& two)
94  {
95  if (one.hasNAN()) {
96  return two;
97  } else if (two.hasNAN()) {
98  return one;
99  } else {
100  return Vector2D((one.x() + two.x()) / 2.0, (one.y() + two.y()) / 2.0);
101  }
102  }
103 
105 
110  static Vector2D average(const Vector2D& one, const Vector2D& two, const Vector2D& three)
111  {
112 
113  if (one.hasNAN()) {
114  return average(two, three);
115  } else if (two.hasNAN()) {
116  return average(one, three);
117  } else if (three.hasNAN()) {
118  return average(one, two);
119  } else {
120  return Vector2D((one.x() + two.x() + three.x()) / 3.0,
121  (one.y() + two.y() + three.y()) / 3.0);
122  }
123  }
124 
126  operator const TVector2();
127 
129  bool operator==(const Vector2D& rhs) const
130  {
131  return x() == rhs.x() and y() == rhs.y();
132  }
133 
135 
141  bool operator<(const Vector2D& rhs) const
142  {
143  return normSquared() < rhs.normSquared() or
144  (normSquared() == rhs.normSquared() and (phi() < rhs.phi()));
145  }
146 
148 
150  {
151  return Vector2D(0.0, 0.0);
152  }
153 
155  bool isNull() const
156  {
157  return x() == 0.0 and y() == 0.0;
158  }
159 
161  bool hasNAN() const
162  {
163  return std::isnan(x()) or std::isnan(y());
164  }
165 
167  std::string __str__() const;
168 
170  double dot(const Vector2D& rhs) const
171  {
172  return x() * rhs.x() + y() * rhs.y();
173  }
175  double cross(const Vector2D& rhs) const
176  {
177  return x() * rhs.y() - y() * rhs.x();
178  }
179 
181  double normSquared() const
182  {
183  return x() * x() + y() * y();
184  }
185 
187  double norm() const
188  {
189  return hypot2(x(), y());
190  }
191 
199  double cosWith(const Vector2D& rhs) const
200  {
201  return dot(rhs) / (norm() * rhs.norm());
202  }
204  double sinWith(const Vector2D& rhs) const
205  {
206  return cross(rhs) / (norm() * rhs.norm());
207  }
209  double angleWith(const Vector2D& rhs) const
210  {
211  return atan2(cross(rhs), dot(rhs));
212  }
214 
216  double distance(const Vector2D& rhs = Vector2D(0.0, 0.0)) const
217  {
218  double deltaX = x() - rhs.x();
219  double deltaY = y() - rhs.y();
220  return hypot2(deltaX, deltaY);
221  }
222 
224  Vector2D& scale(const double factor)
225  {
226  m_x *= factor;
227  m_y *= factor;
228  return *this;
229  }
231  Vector2D& operator*=(const double factor)
232  {
233  return scale(factor);
234  }
235 
237  Vector2D scaled(const double factor) const
238  {
239  return Vector2D(x() * factor, y() * factor);
240  }
241 
243  friend Vector2D operator*(const Vector2D& vec2D, const double factor)
244  {
245  return vec2D.scaled(factor);
246  }
247 
249  Vector2D& divide(const double denominator)
250  {
251  m_x /= denominator;
252  m_y /= denominator;
253  return *this;
254  }
255 
257  Vector2D& operator/=(const double denominator)
258  {
259  return divide(denominator);
260  }
261 
263  Vector2D divided(const double denominator) const
264  {
265  return Vector2D(x() / denominator, y() / denominator);
266  }
268  Vector2D operator/(const double denominator) const
269  {
270  return divided(denominator);
271  }
272 
274  Vector2D& add(const Vector2D& rhs)
275  {
276  m_x += rhs.x();
277  m_y += rhs.y();
278  return *this;
279  }
280 
283  {
284  return add(rhs);
285  }
286 
289  {
290  m_x -= rhs.x();
291  m_y -= rhs.y();
292  return *this;
293  }
296  {
297  return subtract(rhs);
298  }
299 
302  {
303  return Vector2D(-y(), x());
304  }
305 
307  Vector2D orthogonal(const ERotation ccwInfo) const
308  {
309  return isValid(ccwInfo) ? Vector2D(-static_cast<double>(ccwInfo) * y(), static_cast<double>(ccwInfo) * x()) : Vector2D();
310  }
311 
313 
315  double normalize()
316  {
317  double originalLength = norm();
318  if (originalLength != 0.0) divide(originalLength);
319  return originalLength;
320  }
321 
323 
325  double normalizeTo(const double toLength)
326  {
327  double originalLength = norm();
328  if (originalLength != 0.0) scale(toLength / originalLength);
329  return originalLength;
330  }
331 
333  Vector2D unit() const
334  {
335  return isNull() ? Vector2D(0.0, 0.0) : divided(norm());
336  }
337 
340  {
341  scale(-1.0);
342  return *this;
343  }
344 
347  {
348  return scaled(-1.0);
349  }
352  {
353  return reversed();
354  }
355 
357  void flipFirst()
358  {
359  m_x = -x();
360  }
361 
363  void flipSecond()
364  {
365  m_y = -y();
366  }
367 
371  {
372  return Vector2D(-x(), y());
373  }
374 
378  {
379  return Vector2D(x(), -y());
380  }
381 
383  Vector2D flippedOver(const Vector2D& reflectionLine) const
384  {
385  return *this - orthogonalVector(reflectionLine) * 2;
386  }
387 
389  Vector2D flippedAlong(const Vector2D& flippingDirection) const
390  {
391  return *this - parallelVector(flippingDirection) * 2;
392  }
393 
395 
398  {
399  divide(normSquared());
400  }
401 
403 
406  {
407  return divided(normSquared());
408  }
409 
411  Vector2D operator+(const Vector2D& rhs) const
412  {
413  return Vector2D(x() + rhs.x(), y() + rhs.y());
414  }
415 
417  Vector2D operator-(const Vector2D& rhs) const
418  {
419  return Vector2D(x() - rhs.x(), y() - rhs.y());
420  }
421 
423  double parallelComp(const Vector2D& relativTo) const
424  {
425  return relativTo.dot(*this) / relativTo.norm();
426  }
427 
429  Vector2D parallelVector(const Vector2D& relativTo) const
430  {
431  return relativTo.scaled(relativTo.dot(*this) / relativTo.normSquared());
432  }
433 
435 
437  double unnormalizedParallelComp(const Vector2D& relativTo) const
438  {
439  return relativTo.dot(*this);
440  }
441 
443 
444  double orthogonalComp(const Vector2D& relativTo) const
445  {
446  return relativTo.cross(*this) / relativTo.norm();
447  }
448 
450  Vector2D orthogonalVector(const Vector2D& relativTo) const
451  {
452  return relativTo.scaled(relativTo.cross(*this) / relativTo.normSquared()).orthogonal();
453  }
454 
456 
458  double unnormalizedOrthogonalComp(const Vector2D& relativTo) const
459  {
460  return relativTo.cross(*this);
461  }
462 
466  {
467  return static_cast<ERightLeft>(-sign(unnormalizedOrthogonalComp(rhs)));
468  }
469 
471  bool isLeftOf(const Vector2D& rhs) const
472  {
473  return isRightOrLeftOf(rhs) == ERightLeft::c_Left;
474  }
475 
477  bool isRightOf(const Vector2D& rhs) const
478  {
479  return isRightOrLeftOf(rhs) == ERightLeft::c_Right;
480  }
481 
484  ERotation isCCWOrCWOf(const Vector2D& rhs) const
485  {
486  return static_cast<ERotation>(sign(unnormalizedOrthogonalComp(rhs)));
487  }
488 
491  bool isCCWOf(const Vector2D& rhs) const
492  {
493  return isCCWOrCWOf(rhs) == ERotation::c_CounterClockwise;
494  }
495 
498  bool isCWOf(const Vector2D& rhs) const
499  {
500  return isCCWOrCWOf(rhs) == ERotation::c_Clockwise;
501  }
502 
506  {
507  return static_cast<EForwardBackward>(sign(unnormalizedParallelComp(rhs)));
508  }
509 
512  bool isForwardOf(const Vector2D& rhs) const
513  {
514  return isForwardOrBackwardOf(rhs) == EForwardBackward::c_Forward;
515  }
516 
519  bool isBackwardOf(const Vector2D& rhs) const
520  {
521  return isForwardOrBackwardOf(rhs) == EForwardBackward::c_Backward;
522  }
523 
524  private:
526  static bool sameSign(float n1, float n2, float n3)
527  {
528  return ((n1 > 0 and n2 > 0 and n3 > 0) or (n1 < 0 and n2 < 0 and n3 < 0));
529  }
530 
531  public:
537  bool isBetween(const Vector2D& lower, const Vector2D& upper) const
538  {
539  // Set up a linear (nonorthogonal) transformation that maps
540  // lower -> (1, 0)
541  // upper -> (0, 1)
542  // Check whether this transformation is orientation conserving
543  // If yes this vector must lie in the first quadrant to be between lower and upper
544  // If no it must lie in some other quadrant.
545  double det = lower.cross(upper);
546  if (det == 0) {
547  // lower and upper are coaligned
548  return isRightOf(lower) and isLeftOf(upper);
549  } else {
550  bool flipsOrientation = det < 0;
551 
552  double transformedX = cross(upper);
553  double transformedY = -cross(lower);
554  bool inFirstQuadrant = sameSign(det, transformedX, transformedY);
555  if (flipsOrientation) {
556  inFirstQuadrant = not inFirstQuadrant;
557  }
558  return inFirstQuadrant;
559  }
560  }
561 
564  {
565  std::swap(m_x, m_y);
566  }
567 
569  double cylindricalR() const
570  {
571  return hypot2(x(), y());
572  }
573 
575  void setCylindricalR(const double cylindricalR)
576  {
577  scale(cylindricalR / norm());
578  }
579 
581  double phi() const
582  {
583  return isNull() ? NAN : atan2(y(), x());
584  }
585 
587  void passiveMoveBy(const Vector2D& by)
588  {
589  subtract(by);
590  }
591 
594  {
595  return *this - by;
596  }
597 
601  Vector2D passiveRotatedBy(const Vector2D& phiVec) const
602  {
604  }
605 
607  double x() const
608  {
609  return m_x;
610  }
612  void setX(const double x)
613  {
614  m_x = x;
615  }
617  double y() const
618  {
619  return m_y;
620  }
622  void setY(const double y)
623  {
624  m_y = y;
625  }
626 
628  void setXY(const double x, const double y)
629  {
630  setX(x);
631  setY(y);
632  }
634  void setXY(const Vector2D& xy)
635  {
636  m_x = xy.x();
637  m_y = xy.y();
638  }
639 
641  double first() const
642  {
643  return m_x;
644  }
646  void setFirst(const double first)
647  {
648  m_x = first;
649  }
651  double second() const
652  {
653  return m_y;
654  }
656  void setSecond(const double second)
657  {
658  m_y = second;
659  }
660 
662  void set(const double first, const double second)
663  {
664  setX(first);
665  setY(second);
666  }
668  void set(const Vector2D& both)
669  {
670  m_x = both.x();
671  m_y = both.y();
672  }
673 
674  private:
676  double m_x;
677 
679  double m_y;
680  };
681 
683  std::ostream& operator<<(std::ostream& output, const Vector2D& vector2D);
684  }
686 }
A two dimensional vector which is equipped with functions for correct handeling of orientation relat...
Definition: Vector2D.h:35
void setSecond(const double second)
Setter for the second coordinate.
Definition: Vector2D.h:656
double normalize()
Normalizes the vector to unit length.
Definition: Vector2D.h:315
void swapCoordinates()
Swaps the coordinates in place.
Definition: Vector2D.h:563
double parallelComp(const Vector2D &relativTo) const
Calculates the component parallel to the given vector.
Definition: Vector2D.h:423
void flipSecond()
Flips the first coordinate inplace (no difference between active and passive)
Definition: Vector2D.h:363
Vector2D(const Vector2D &coordinateVec, const double parallelCoor, const double orthoCoor)
Constructs a vector from a unit coordinate system vector and the coordinates in that system.
Definition: Vector2D.h:61
std::string __str__() const
Output operator for python.
Definition: Vector2D.cc:42
Vector2D flippedSecond() const
Makes a copy of the vector with the second coordinate flipped (no difference between active and passi...
Definition: Vector2D.h:377
Vector2D & add(const Vector2D &rhs)
Adds a vector to this in place.
Definition: Vector2D.h:274
double normalizeTo(const double toLength)
Normalizes the vector to the given length.
Definition: Vector2D.h:325
Vector2D(const double x, const double y)
Constructor from two coordinates.
Definition: Vector2D.h:49
static Vector2D compose(const Vector2D &coordinateVec, const double parallelCoor, const double orthoCoor)
Constructs a vector from a unit coordinate system vector and the coordinates in that system.
Definition: Vector2D.h:83
Vector2D operator-(const Vector2D &rhs) const
Returns a new vector as differenc of this and rhs.
Definition: Vector2D.h:417
double dot(const Vector2D &rhs) const
Calculates the two dimensional dot product.
Definition: Vector2D.h:170
static Vector2D average(const Vector2D &one, const Vector2D &two)
Constructs the average of two vectors.
Definition: Vector2D.h:93
Vector2D reversed() const
Returns a vector pointing in the opposite direction.
Definition: Vector2D.h:346
void setXY(const double x, const double y)
Setter for both coordinate.
Definition: Vector2D.h:628
Vector2D & operator/=(const double denominator)
Same as divide()
Definition: Vector2D.h:257
static bool sameSign(float n1, float n2, float n3)
Check if three values have the same sign.
Definition: Vector2D.h:526
Vector2D scaled(const double factor) const
Returns a scaled copy of the vector.
Definition: Vector2D.h:237
void set(const double first, const double second)
Setter for both coordinate.
Definition: Vector2D.h:662
double distance(const Vector2D &rhs=Vector2D(0.0, 0.0)) const
Calculates the distance of this point to the rhs.
Definition: Vector2D.h:216
double cylindricalR() const
Gives the cylindrical radius of the vector. Same as norm()
Definition: Vector2D.h:569
double unnormalizedParallelComp(const Vector2D &relativTo) const
Same as parallelComp() but assumes the given vector to be of unit length.
Definition: Vector2D.h:437
double cosWith(const Vector2D &rhs) const
Definition: Vector2D.h:199
void flipFirst()
Flips the first coordinate inplace (no difference between active and passive)
Definition: Vector2D.h:357
void passiveMoveBy(const Vector2D &by)
Passivelly moves the vector inplace by the given vector.
Definition: Vector2D.h:587
Vector2D orthogonalVector(const Vector2D &relativTo) const
Calculates the part of this vector that is parallel to the given vector.
Definition: Vector2D.h:450
Vector2D operator-() const
Same as reversed()
Definition: Vector2D.h:351
EForwardBackward isForwardOrBackwardOf(const Vector2D &rhs) const
Indicates if the given vector is more coaligned or reverse if you looked in the direction of this vec...
Definition: Vector2D.h:505
ERotation isCCWOrCWOf(const Vector2D &rhs) const
Indicates if the given vector is more counterclockwise or more clockwise if you looked in the directi...
Definition: Vector2D.h:484
void set(const Vector2D &both)
Setter for both coordinate by an other vector.
Definition: Vector2D.h:668
Vector2D & subtract(const Vector2D &rhs)
Subtracts a vector from this in place.
Definition: Vector2D.h:288
Vector2D flippedFirst() const
Makes a copy of the vector with the first coordinate flipped (no difference between active and passiv...
Definition: Vector2D.h:370
friend Vector2D operator*(const Vector2D &vec2D, const double factor)
Same as scaled()
Definition: Vector2D.h:243
Vector2D operator+(const Vector2D &rhs) const
Returns a new vector as sum of this and rhs.
Definition: Vector2D.h:411
double cross(const Vector2D &rhs) const
Calculated the two dimensional cross product.
Definition: Vector2D.h:175
double m_x
Memory for the first coordinate.
Definition: Vector2D.h:676
Vector2D orthogonal(const ERotation ccwInfo) const
Orthogonal vector to the direction given by the counterclockwise info.
Definition: Vector2D.h:307
Vector2D()
Default constructor for ROOT compatibility.
Definition: Vector2D.h:39
ERightLeft isRightOrLeftOf(const Vector2D &rhs) const
Indicates if the given vector is more left or more right if you looked in the direction of this vecto...
Definition: Vector2D.h:465
Vector2D operator/(const double denominator) const
Same as divided()
Definition: Vector2D.h:268
Vector2D & operator-=(const Vector2D &rhs)
Same as subtract()
Definition: Vector2D.h:295
Vector2D & divide(const double denominator)
Divides all coordinates by a common denominator in place.
Definition: Vector2D.h:249
double x() const
Getter for the x coordinate.
Definition: Vector2D.h:607
double sinWith(const Vector2D &rhs) const
Sine of the angle between this and rhs.
Definition: Vector2D.h:204
Vector2D conformalTransformed() const
Returns a copy of the vector transformed in conformal space.
Definition: Vector2D.h:405
Vector2D & operator+=(const Vector2D &rhs)
Same as add()
Definition: Vector2D.h:282
bool isRightOf(const Vector2D &rhs) const
Indicates if the given vector is more right if you looked in the direction of this vector.
Definition: Vector2D.h:477
void conformalTransform()
Transforms the vector to conformal space inplace.
Definition: Vector2D.h:397
bool isCCWOf(const Vector2D &rhs) const
Indicates if the given vector is more counterclockwise if you looked in the direction of this vector.
Definition: Vector2D.h:491
double orthogonalComp(const Vector2D &relativTo) const
Calculates the component orthogonal to the given vector.
Definition: Vector2D.h:444
void setCylindricalR(const double cylindricalR)
Set the cylindrical radius while keeping the azimuth angle phi the same.
Definition: Vector2D.h:575
static Vector2D average(const Vector2D &one, const Vector2D &two, const Vector2D &three)
Constructs the average of three vectors.
Definition: Vector2D.h:110
bool isBetween(const Vector2D &lower, const Vector2D &upper) const
Checks if this vector is between two other vectors Between means here that when rotating the lower ve...
Definition: Vector2D.h:537
double phi() const
Gives the azimuth angle being the angle to the x axes ( range -M_PI to M_PI )
Definition: Vector2D.h:581
bool operator==(const Vector2D &rhs) const
Equality comparison with both coordinates.
Definition: Vector2D.h:129
Vector2D & operator=(const TVector2 &tvector)
Assignment translating from a TVector2 instance.
Definition: Vector2D.cc:24
static Vector2D getLowest()
Getter for the lowest possible vector.
Definition: Vector2D.h:149
Vector2D parallelVector(const Vector2D &relativTo) const
Calculates the part of this vector that is parallel to the given vector.
Definition: Vector2D.h:429
double second() const
Getter for the second coordinate.
Definition: Vector2D.h:651
void setXY(const Vector2D &xy)
Setter for both coordinate by an other vector.
Definition: Vector2D.h:634
double normSquared() const
Calculates .
Definition: Vector2D.h:181
Vector2D & scale(const double factor)
Scales the vector in place by the given factor.
Definition: Vector2D.h:224
bool isNull() const
Checks if the vector is the null vector.
Definition: Vector2D.h:155
Vector2D & operator*=(const double factor)
Same as scale()
Definition: Vector2D.h:231
Vector2D orthogonal() const
Orthogonal vector to the counterclockwise direction.
Definition: Vector2D.h:301
bool hasNAN() const
Checks if one of the coordinates is NAN.
Definition: Vector2D.h:161
Vector2D divided(const double denominator) const
Returns a copy where all coordinates got divided by a common denominator.
Definition: Vector2D.h:263
void setY(const double y)
Setter for the y coordinate.
Definition: Vector2D.h:622
double y() const
Getter for the y coordinate.
Definition: Vector2D.h:617
double first() const
Getter for the first coordinate.
Definition: Vector2D.h:641
Vector2D flippedOver(const Vector2D &reflectionLine) const
Reflects this vector over line designated by the given vector.
Definition: Vector2D.h:383
Vector2D & reverse()
Reverses the direction of the vector in place.
Definition: Vector2D.h:339
Vector2D flippedAlong(const Vector2D &flippingDirection) const
Reflects this vector along line designated by the given vector.
Definition: Vector2D.h:389
Vector2D unit() const
Returns a unit vector colaligned with this.
Definition: Vector2D.h:333
double angleWith(const Vector2D &rhs) const
The angle between this and rhs.
Definition: Vector2D.h:209
double norm() const
Calculates the length of the vector.
Definition: Vector2D.h:187
Vector2D passiveRotatedBy(const Vector2D &phiVec) const
Returns a transformed vector version rotated by the given vector.
Definition: Vector2D.h:601
double m_y
Memory for the second coordinate.
Definition: Vector2D.h:679
bool isLeftOf(const Vector2D &rhs) const
Indicates if the given vector is more left if you looked in the direction of this vector.
Definition: Vector2D.h:471
void setFirst(const double first)
Setter for the first coordinate.
Definition: Vector2D.h:646
bool isForwardOf(const Vector2D &rhs) const
Indicates if the given vector is more coaligned if you looked in the direction of this vector.
Definition: Vector2D.h:512
void setX(const double x)
Setter for the x coordinate.
Definition: Vector2D.h:612
bool isCWOf(const Vector2D &rhs) const
Indicates if the given vector is more clockwise if you looked in the direction of this vector.
Definition: Vector2D.h:498
bool isBackwardOf(const Vector2D &rhs) const
Indicates if the given vector is more Reverse if you looked in the direction of this vector.
Definition: Vector2D.h:519
double unnormalizedOrthogonalComp(const Vector2D &relativTo) const
Same as orthogonalComp() but assumes the given vector to be of unit length.
Definition: Vector2D.h:458
bool operator<(const Vector2D &rhs) const
Total ordering based on cylindrical radius first and azimuth angle second.
Definition: Vector2D.h:141
static Vector2D Phi(const double phi)
Constucts a unit vector with azimuth angle equal to phi.
Definition: Vector2D.h:71
Vector2D passiveMovedBy(const Vector2D &by) const
Returns a transformed vector passivelly moved by the given vector.
Definition: Vector2D.h:593
std::ostream & operator<<(std::ostream &output, const IntervalOfValidity &iov)
EForwardBackward
Enumeration to represent the distinct possibilities of the right left passage information.
ERightLeft
Enumeration to represent the distinct possibilities of the right left passage.
Definition: ERightLeft.h:25
ERotation
Enumeration to represent the distinct possibilities of the right left passage information.
Definition: ERotation.h:25
Abstract base class for different kinds of events.