File indexing completed on 2024-04-06 12:04:16
0001 #ifndef GeometryVector_Geom_Phi_h
0002 #define GeometryVector_Geom_Phi_h
0003
0004 #include "DataFormats/GeometryVector/interface/Pi.h"
0005 #include "DataFormats/Math/interface/deltaPhi.h"
0006 #include "DataFormats/Math/interface/angle_units.h"
0007 #include <cmath>
0008
0009 namespace Geom {
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 using angle_units::operators::operator""_deg;
0023 using angle_units::operators::convertRadToDeg;
0024
0025 struct MinusPiToPi {};
0026 struct ZeroTo2pi {};
0027
0028 template <typename T1, typename Range>
0029 class NormalizeWrapper {};
0030
0031 template <typename T1>
0032 class NormalizeWrapper<T1, MinusPiToPi> {
0033 public:
0034 static void normalize(T1& value) {
0035 if (value > twoPi() || value < -twoPi()) {
0036 value = std::fmod(value, static_cast<T1>(twoPi()));
0037 }
0038 if (value <= -pi())
0039 value += twoPi();
0040 if (value > pi())
0041 value -= twoPi();
0042 }
0043 };
0044
0045 template <typename T1>
0046 class NormalizeWrapper<T1, ZeroTo2pi> {
0047 public:
0048 static void normalize(T1& value) { value = angle0to2pi::make0To2pi(value); }
0049 };
0050
0051 template <typename T1, typename Range = MinusPiToPi>
0052 class Phi {
0053 public:
0054
0055 Phi() {}
0056
0057
0058
0059
0060
0061
0062
0063 Phi(const T1& val) : theValue(val) { normalize(theValue); }
0064
0065
0066 operator T1() const { return theValue; }
0067
0068
0069 template <typename T2, typename Range1>
0070 operator Phi<T2, Range1>() {
0071 return Phi<T2, Range1>(theValue);
0072 }
0073
0074
0075 T1 value() const { return theValue; }
0076
0077
0078 T1 phi() const { return theValue; }
0079
0080
0081 Phi& operator+=(const T1& a) {
0082 theValue += a;
0083 normalize(theValue);
0084 return *this;
0085 }
0086 Phi& operator+=(const Phi& a) { return operator+=(a.value()); }
0087
0088 Phi& operator-=(const T1& a) {
0089 theValue -= a;
0090 normalize(theValue);
0091 return *this;
0092 }
0093 Phi& operator-=(const Phi& a) { return operator-=(a.value()); }
0094
0095 Phi& operator*=(const T1& a) {
0096 theValue *= a;
0097 normalize(theValue);
0098 return *this;
0099 }
0100
0101 Phi& operator/=(const T1& a) {
0102 theValue /= a;
0103 normalize(theValue);
0104 return *this;
0105 }
0106
0107 T1 degrees() const { return convertRadToDeg(theValue); }
0108
0109
0110
0111 inline bool nearZero(float tolerance = 1.0_deg) const { return (std::abs(theValue) - tolerance <= 0.0); }
0112
0113
0114
0115 inline bool nearEqual(const Phi<T1, Range>& angle, float tolerance = 0.001) const {
0116 return (std::abs(theValue - angle) - tolerance <= 0.0);
0117 }
0118
0119 private:
0120 T1 theValue;
0121
0122 void normalize(T1& value) { NormalizeWrapper<T1, Range>::normalize(value); }
0123 };
0124
0125
0126 template <typename T1, typename Range>
0127 inline Phi<T1, Range> operator-(const Phi<T1, Range>& a) {
0128 return Phi<T1, Range>(-a.value());
0129 }
0130
0131
0132 template <typename T1, typename Range>
0133 inline Phi<T1, Range> operator+(const Phi<T1, Range>& a, const Phi<T1, Range>& b) {
0134 return Phi<T1, Range>(a) += b;
0135 }
0136
0137 template <typename T1, typename Range, typename Scalar>
0138 inline Phi<T1, Range> operator+(const Phi<T1, Range>& a, const Scalar& b) {
0139 return Phi<T1, Range>(a) += b;
0140 }
0141
0142 template <typename T1, typename Range, typename Scalar>
0143 inline Phi<T1, Range> operator+(const Scalar& a, const Phi<T1, Range>& b) {
0144 return Phi<T1, Range>(b) += a;
0145 }
0146
0147
0148 template <typename T1, typename Range>
0149 inline Phi<T1, Range> operator-(const Phi<T1, Range>& a, const Phi<T1, Range>& b) {
0150 return Phi<T1, Range>(a) -= b;
0151 }
0152
0153 template <typename T1, typename Range, typename Scalar>
0154 inline Phi<T1, Range> operator-(const Phi<T1, Range>& a, const Scalar& b) {
0155 return Phi<T1, Range>(a) -= b;
0156 }
0157
0158 template <typename T1, typename Range, typename Scalar>
0159 inline Phi<T1, Range> operator-(const Scalar& a, const Phi<T1, Range>& b) {
0160 return Phi<T1, Range>(a - b.value());
0161 }
0162
0163
0164 template <typename T1, typename Range, typename Scalar>
0165 inline Phi<T1, Range> operator*(const Phi<T1, Range>& a, const Scalar& b) {
0166 return Phi<T1, Range>(a) *= b;
0167 }
0168
0169 template <typename T1, typename Range>
0170 inline Phi<T1, Range> operator*(double a, const Phi<T1, Range>& b) {
0171 return Phi<T1, Range>(b) *= a;
0172 }
0173
0174
0175 template <typename T1, typename Range>
0176 inline T1 operator/(const Phi<T1, Range>& a, const Phi<T1, Range>& b) {
0177 return a.value() / b.value();
0178 }
0179
0180 template <typename T1, typename Range>
0181 inline Phi<T1, Range> operator/(const Phi<T1, Range>& a, double b) {
0182 return Phi<T1, Range>(a) /= b;
0183 }
0184
0185
0186 template <typename T>
0187 using Phi0To2pi = Phi<T, ZeroTo2pi>;
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 #endif