File indexing completed on 2024-05-04 04:04:19
0001 #ifndef GeometryVector_newBasic2DVector_h
0002 #define GeometryVector_newBasic2DVector_h
0003
0004 #include "DataFormats/GeometryVector/interface/Phi.h"
0005 #include "DataFormats/GeometryVector/interface/PreciseFloatType.h"
0006 #include "DataFormats/GeometryVector/interface/CoordinateSets.h"
0007 #include "DataFormats/Math/interface/ExtVec.h"
0008
0009 #include <cmath>
0010 #include <iosfwd>
0011
0012 template <class T>
0013 class Basic2DVector {
0014 public:
0015 typedef T ScalarType;
0016 typedef Vec2<T> VectorType;
0017 typedef Vec2<T> MathVector;
0018 typedef Geom::Polar2Cartesian<T> Polar;
0019
0020
0021
0022
0023
0024 Basic2DVector() : v{0, 0} {}
0025
0026
0027 Basic2DVector(const Basic2DVector& p) : v(p.v) {}
0028
0029
0030 Basic2DVector& operator=(const Basic2DVector&) = default;
0031
0032 template <typename U>
0033 Basic2DVector(const Basic2DVector<U>& p) : v{T(p.v[0]), T(p.v[1])} {}
0034
0035
0036
0037
0038
0039
0040
0041
0042 template <class Other>
0043 explicit Basic2DVector(const Other& p) : v{T(p.x()), T(p.y())} {}
0044
0045
0046 Basic2DVector(const T& x, const T& y) : v{x, y} {}
0047
0048
0049 Basic2DVector(MathVector const& iv) : v(iv) {}
0050 template <typename U>
0051 Basic2DVector(Vec2<U> const& iv) : v{iv[0], iv[1]} {}
0052 template <typename U>
0053 Basic2DVector(Vec4<U> const& iv) : v{iv[0], iv[1]} {}
0054
0055 MathVector const& mathVector() const { return v; }
0056 MathVector& mathVector() { return v; }
0057
0058 T operator[](int i) const { return v[i]; }
0059
0060
0061 T x() const { return v[0]; }
0062
0063
0064 T y() const { return v[1]; }
0065
0066
0067 T mag2() const { return ::dot(v, v); }
0068
0069
0070 T mag() const { return std::sqrt(mag2()); }
0071
0072
0073 T r() const { return mag(); }
0074
0075
0076
0077
0078
0079 T barePhi() const { return std::atan2(y(), x()); }
0080 Geom::Phi<T> phi() const { return Geom::Phi<T>(atan2(y(), x())); }
0081
0082
0083
0084
0085 Basic2DVector unit() const {
0086 T my_mag = mag();
0087 return my_mag == 0 ? *this : *this / my_mag;
0088 }
0089
0090
0091
0092 template <class U>
0093 Basic2DVector& operator+=(const Basic2DVector<U>& p) {
0094 v = v + p.v;
0095 return *this;
0096 }
0097
0098
0099
0100 template <class U>
0101 Basic2DVector& operator-=(const Basic2DVector<U>& p) {
0102 v = v - p.v;
0103 return *this;
0104 }
0105
0106
0107 Basic2DVector operator-() const { return Basic2DVector(-v); }
0108
0109
0110 Basic2DVector& operator*=(T t) {
0111 v = v * t;
0112 return *this;
0113 }
0114
0115
0116 Basic2DVector& operator/=(T t) {
0117 t = T(1) / t;
0118 v = v * t;
0119 return *this;
0120 }
0121
0122
0123 T dot(const Basic2DVector& lh) const { return ::dot(v, lh.v); }
0124
0125
0126
0127
0128
0129
0130 template <class U>
0131 typename PreciseFloatType<T, U>::Type dot(const Basic2DVector<U>& lh) const {
0132 return Basic2DVector<typename PreciseFloatType<T, U>::Type>(*this).dot(
0133 Basic2DVector<typename PreciseFloatType<T, U>::Type>(lh));
0134 }
0135
0136
0137 T cross(const Basic2DVector& lh) const { return ::cross2(v, lh.v); }
0138
0139
0140
0141
0142
0143
0144 template <class U>
0145 typename PreciseFloatType<T, U>::Type cross(const Basic2DVector<U>& lh) const {
0146 return Basic2DVector<typename PreciseFloatType<T, U>::Type>(*this).cross(
0147 Basic2DVector<typename PreciseFloatType<T, U>::Type>(lh));
0148 }
0149
0150 public:
0151 Vec2<T> v;
0152 };
0153
0154 namespace geometryDetails {
0155 std::ostream& print2D(std::ostream& s, double x, double y);
0156
0157 }
0158
0159
0160 template <class T>
0161 inline std::ostream& operator<<(std::ostream& s, const Basic2DVector<T>& v) {
0162 return geometryDetails::print2D(s, v.x(), v.y());
0163 }
0164
0165
0166 template <class T>
0167 inline Basic2DVector<T> operator+(const Basic2DVector<T>& a, const Basic2DVector<T>& b) {
0168 return a.v + b.v;
0169 }
0170 template <class T>
0171 inline Basic2DVector<T> operator-(const Basic2DVector<T>& a, const Basic2DVector<T>& b) {
0172 return a.v - b.v;
0173 }
0174
0175 template <class T, class U>
0176 inline Basic2DVector<typename PreciseFloatType<T, U>::Type> operator+(const Basic2DVector<T>& a,
0177 const Basic2DVector<U>& b) {
0178 typedef Basic2DVector<typename PreciseFloatType<T, U>::Type> RT;
0179 return RT(a) + RT(b);
0180 }
0181
0182 template <class T, class U>
0183 inline Basic2DVector<typename PreciseFloatType<T, U>::Type> operator-(const Basic2DVector<T>& a,
0184 const Basic2DVector<U>& b) {
0185 typedef Basic2DVector<typename PreciseFloatType<T, U>::Type> RT;
0186 return RT(a) - RT(b);
0187 }
0188
0189
0190 template <class T>
0191 inline T operator*(const Basic2DVector<T>& v1, const Basic2DVector<T>& v2) {
0192 return v1.dot(v2);
0193 }
0194
0195
0196 template <class T, class U>
0197 inline typename PreciseFloatType<T, U>::Type operator*(const Basic2DVector<T>& v1, const Basic2DVector<U>& v2) {
0198 return v1.dot(v2);
0199 }
0200
0201
0202
0203
0204 template <class T>
0205 inline Basic2DVector<T> operator*(const Basic2DVector<T>& v, T t) {
0206 return v.v * t;
0207 }
0208
0209
0210 template <class T>
0211 inline Basic2DVector<T> operator*(T t, const Basic2DVector<T>& v) {
0212 return v.v * t;
0213 }
0214
0215 template <class T, class Scalar>
0216 inline Basic2DVector<T> operator*(const Basic2DVector<T>& v, const Scalar& s) {
0217 T t = static_cast<T>(s);
0218 return v * t;
0219 }
0220
0221
0222 template <class T, class Scalar>
0223 inline Basic2DVector<T> operator*(const Scalar& s, const Basic2DVector<T>& v) {
0224 T t = static_cast<T>(s);
0225 return v * t;
0226 }
0227
0228
0229
0230
0231 template <class T>
0232 inline Basic2DVector<T> operator/(const Basic2DVector<T>& v, T t) {
0233 return v.v / t;
0234 }
0235
0236 template <class T, class Scalar>
0237 inline Basic2DVector<T> operator/(const Basic2DVector<T>& v, const Scalar& s) {
0238
0239 T t = static_cast<T>(s);
0240 return v / t;
0241 }
0242
0243 typedef Basic2DVector<float> Basic2DVectorF;
0244 typedef Basic2DVector<double> Basic2DVectorD;
0245
0246 #endif