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