CMS 3D CMS Logo

Phi.h
Go to the documentation of this file.
1 #ifndef GeometryVector_Geom_Phi_h
2 #define GeometryVector_Geom_Phi_h
3 
7 #include <cmath>
8 
9 namespace Geom {
10 
24 
25  struct MinusPiToPi {}; // Dummy struct to indicate -pi to pi range
26  struct ZeroTo2pi {}; // Dummy struct to indicate 0 to 2pi range
27 
28  template <typename T1, typename Range>
29  class NormalizeWrapper {};
30 
31  template <typename T1>
33  public:
34  static void normalize(T1& value) { // Reduce range to -pi to pi
35  if (value > twoPi() || value < -twoPi()) {
36  value = std::fmod(value, static_cast<T1>(twoPi()));
37  }
38  if (value <= -pi())
39  value += twoPi();
40  if (value > pi())
41  value -= twoPi();
42  }
43  };
44 
45  template <typename T1>
46  class NormalizeWrapper<T1, ZeroTo2pi> { // Reduce range to 0 to 2pi
47  public:
48  static void normalize(T1& value) { value = angle0to2pi::make0To2pi(value); }
49  };
50 
51  template <typename T1, typename Range = MinusPiToPi>
52  class Phi {
53  public:
55  Phi() {}
56 
57  // Constructor from T1.
58  // Not "explicit" to enable convenient conversions.
59  // There may be cases of ambiguities because of multiple possible
60  // conversions, in which case explicit casts must be used.
61  // The constructor provides range checking and normalization,
62  // e.g. the value of Phi(2*pi()+1) is 1
63  Phi(const T1& val) : theValue(val) { normalize(theValue); }
64 
66  operator T1() const { return theValue; }
67 
69  template <typename T2, typename Range1>
70  operator Phi<T2, Range1>() {
71  return Phi<T2, Range1>(theValue);
72  }
73 
75  T1 value() const { return theValue; }
76 
77  // so that template classes expecting phi() works! (deltaPhi)
78  T1 phi() const { return theValue; }
79 
81  Phi& operator+=(const T1& a) {
82  theValue += a;
83  normalize(theValue);
84  return *this;
85  }
86  Phi& operator+=(const Phi& a) { return operator+=(a.value()); }
87 
88  Phi& operator-=(const T1& a) {
89  theValue -= a;
90  normalize(theValue);
91  return *this;
92  }
93  Phi& operator-=(const Phi& a) { return operator-=(a.value()); }
94 
95  Phi& operator*=(const T1& a) {
96  theValue *= a;
97  normalize(theValue);
98  return *this;
99  }
100 
101  Phi& operator/=(const T1& a) {
102  theValue /= a;
103  normalize(theValue);
104  return *this;
105  }
106 
107  T1 degrees() const { return convertRadToDeg(theValue); }
108 
109  // nearZero() tells whether the angle is close enough to 0 to be considered 0.
110  // The default tolerance is 1 degree.
111  inline bool nearZero(float tolerance = 1.0_deg) const { return (std::abs(theValue) - tolerance <= 0.0); }
112 
113  // nearEqual() tells whether two angles are close enough to be considered equal.
114  // The default tolerance is 0.001 radian.
115  inline bool nearEqual(const Phi<T1, Range>& angle, float tolerance = 0.001) const {
116  return (std::abs(theValue - angle) - tolerance <= 0.0);
117  }
118 
119  private:
121 
123  };
124 
126  template <typename T1, typename Range>
128  return Phi<T1, Range>(-a.value());
129  }
130 
132  template <typename T1, typename Range>
134  return Phi<T1, Range>(a) += b;
135  }
137  template <typename T1, typename Range, typename Scalar>
138  inline Phi<T1, Range> operator+(const Phi<T1, Range>& a, const Scalar& b) {
139  return Phi<T1, Range>(a) += b;
140  }
142  template <typename T1, typename Range, typename Scalar>
143  inline Phi<T1, Range> operator+(const Scalar& a, const Phi<T1, Range>& b) {
144  return Phi<T1, Range>(b) += a;
145  }
146 
148  template <typename T1, typename Range>
150  return Phi<T1, Range>(a) -= b;
151  }
153  template <typename T1, typename Range, typename Scalar>
154  inline Phi<T1, Range> operator-(const Phi<T1, Range>& a, const Scalar& b) {
155  return Phi<T1, Range>(a) -= b;
156  }
158  template <typename T1, typename Range, typename Scalar>
159  inline Phi<T1, Range> operator-(const Scalar& a, const Phi<T1, Range>& b) {
160  return Phi<T1, Range>(a - b.value());
161  }
162 
164  template <typename T1, typename Range, typename Scalar>
165  inline Phi<T1, Range> operator*(const Phi<T1, Range>& a, const Scalar& b) {
166  return Phi<T1, Range>(a) *= b;
167  }
169  template <typename T1, typename Range>
170  inline Phi<T1, Range> operator*(double a, const Phi<T1, Range>& b) {
171  return Phi<T1, Range>(b) *= a;
172  }
173 
175  template <typename T1, typename Range>
176  inline T1 operator/(const Phi<T1, Range>& a, const Phi<T1, Range>& b) {
177  return a.value() / b.value();
178  }
180  template <typename T1, typename Range>
181  inline Phi<T1, Range> operator/(const Phi<T1, Range>& a, double b) {
182  return Phi<T1, Range>(a) /= b;
183  }
184 
185  // For convenience
186  template <typename T>
188 } // namespace Geom
189 
190 /*
191 // this a full mess with the above that is a mess in itself
192 #include "DataFormats/Math/interface/deltaPhi.h"
193 namespace reco {
194  template <class T1,class T2>
195  inline double deltaPhi(const Geom::Phi<T1> phi1, const Geom::Phi<T2> phi2) {
196  return deltaPhi(static_cast<double>(phi1.value()), static_cast<double>(phi2.value()));
197  }
198 
199  template <class T>
200  inline double deltaPhi(const Geom::Phi<T> phi1, double phi2) {
201  return deltaPhi(static_cast<double>(phi1.value()), phi2);
202  }
203  template <class T>
204  inline double deltaPhi(const Geom::Phi<T> phi1, float phi2) {
205  return deltaPhi(static_cast<double>(phi1.value()), static_cast<double>(phi2));
206  }
207  template <class T>
208  inline double deltaPhi(double phi1, const Geom::Phi<T> phi2) {
209  return deltaPhi(phi1, static_cast<double>(phi2.value()) );
210  }
211  template <class T>
212  inline double deltaPhi(float phi1, const Geom::Phi<T> phi2) {
213  return deltaPhi(static_cast<double>(phi1),static_cast<double>(phi2.value()) );
214  }
215 }
216 */
217 
218 #endif
T operator/(const OnePiRange< T > &a, const OnePiRange< T > &b)
Division.
Definition: OnePiRange.h:122
bool nearEqual(const Phi< T1, Range > &angle, float tolerance=0.001) const
Definition: Phi.h:115
OnePiRange< T > operator-(const OnePiRange< T > &a)
Definition: OnePiRange.h:71
bool nearZero(float tolerance=1.0_deg) const
Definition: Phi.h:111
double Scalar
Definition: Definitions.h:25
void normalize(T1 &value)
Definition: Phi.h:122
static void normalize(T1 &value)
Definition: Phi.h:48
const double tolerance
constexpr NumType convertRadToDeg(NumType radians)
Definition: angle_units.h:21
T1 value() const
Explicit access to value in case implicit conversion not OK.
Definition: Phi.h:75
T1 phi() const
Definition: Phi.h:78
Phi & operator/=(const T1 &a)
Definition: Phi.h:101
T1 degrees() const
Definition: Phi.h:107
Phi & operator+=(const Phi &a)
Definition: Phi.h:86
Phi & operator+=(const T1 &a)
Standard arithmetics.
Definition: Phi.h:81
OnePiRange< T > operator+(const OnePiRange< T > &a, const OnePiRange< T > &b)
Addition.
Definition: OnePiRange.h:76
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Definition: value.py:1
Phi & operator-=(const T1 &a)
Definition: Phi.h:88
OnePiRange< T > operator*(const OnePiRange< T > &a, const Scalar &b)
Multiplication with scalar, does not change the precision.
Definition: OnePiRange.h:110
Phi()
Default constructor does not initialise - just as double.
Definition: Phi.h:55
Phi & operator-=(const Phi &a)
Definition: Phi.h:93
double b
Definition: hdecay.h:118
constexpr valType make0To2pi(valType angle)
Definition: deltaPhi.h:67
static void normalize(T1 &value)
Definition: Phi.h:34
T1 theValue
Definition: Phi.h:120
double a
Definition: hdecay.h:119
Phi & operator*=(const T1 &a)
Definition: Phi.h:95
constexpr double pi()
Definition: Pi.h:31
constexpr double twoPi()
Definition: Pi.h:32
Definition: Phi.h:52
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11
Phi(const T1 &val)
Definition: Phi.h:63