Vector3.hh
Go to the documentation of this file.
00001 #ifndef RIVET_MATH_VECTOR3 00002 #define RIVET_MATH_VECTOR3 00003 00004 #include "Rivet/Math/MathHeader.hh" 00005 #include "Rivet/Math/MathUtils.hh" 00006 #include "Rivet/Math/VectorN.hh" 00007 #include <cfloat> 00008 00009 namespace Rivet { 00010 00011 00012 class Vector3; 00013 typedef Vector3 ThreeVector; 00014 class Matrix3; 00015 00016 Vector3 multiply(const double, const Vector3&); 00017 Vector3 multiply(const Vector3&, const double); 00018 Vector3 add(const Vector3&, const Vector3&); 00019 Vector3 operator*(const double, const Vector3&); 00020 Vector3 operator*(const Vector3&, const double); 00021 Vector3 operator/(const Vector3&, const double); 00022 Vector3 operator+(const Vector3&, const Vector3&); 00023 Vector3 operator-(const Vector3&, const Vector3&); 00024 00025 00026 /// @brief Three-dimensional specialisation of Vector. 00027 class Vector3 : public Vector<3> { 00028 00029 friend class Matrix3; 00030 friend Vector3 multiply(const double, const Vector3&); 00031 friend Vector3 multiply(const Vector3&, const double); 00032 friend Vector3 add(const Vector3&, const Vector3&); 00033 friend Vector3 subtract(const Vector3&, const Vector3&); 00034 00035 public: 00036 Vector3() : Vector<3>() { } 00037 00038 template<typename V3> 00039 Vector3(const V3& other) { 00040 this->setX(other.x()); 00041 this->setY(other.y()); 00042 this->setZ(other.z()); 00043 } 00044 00045 Vector3(const Vector<3>& other) { 00046 this->setX(other.get(0)); 00047 this->setY(other.get(1)); 00048 this->setZ(other.get(2)); 00049 } 00050 00051 Vector3(double x, double y, double z) { 00052 this->setX(x); 00053 this->setY(y); 00054 this->setZ(z); 00055 } 00056 00057 ~Vector3() { } 00058 00059 public: 00060 static Vector3 mkX() { return Vector3(1,0,0); } 00061 static Vector3 mkY() { return Vector3(0,1,0); } 00062 static Vector3 mkZ() { return Vector3(0,0,1); } 00063 00064 public: 00065 double x() const { return get(0); } 00066 double y() const { return get(1); } 00067 double z() const { return get(2); } 00068 Vector3& setX(double x) { set(0, x); return *this; } 00069 Vector3& setY(double y) { set(1, y); return *this; } 00070 Vector3& setZ(double z) { set(2, z); return *this; } 00071 00072 double dot(const Vector3& v) const { 00073 return _vec.dot(v._vec); 00074 } 00075 00076 Vector3 cross(const Vector3& v) const { 00077 Vector3 result; 00078 result._vec = _vec.cross(v._vec); 00079 return result; 00080 } 00081 00082 double angle(const Vector3& v) const { 00083 const double localDotOther = unit().dot(v.unit()); 00084 if (localDotOther > 1.0) return 0.0; 00085 if (localDotOther < -1.0) return M_PI; 00086 return acos(localDotOther); 00087 } 00088 00089 Vector3 unit() const { 00090 /// @todo What to do in this situation? 00091 if (isZero()) return *this; 00092 else return *this * 1.0/this->mod(); 00093 } 00094 00095 double polarRadius2() const { 00096 return x()*x() + y()*y(); 00097 } 00098 00099 /// Synonym for polarRadius2 00100 double perp2() const { 00101 return polarRadius2(); 00102 } 00103 00104 /// Synonym for polarRadius2 00105 double rho2() const { 00106 return polarRadius2(); 00107 } 00108 00109 double polarRadius() const { 00110 return sqrt(polarRadius2()); 00111 } 00112 00113 /// Synonym for polarRadius 00114 double perp() const { 00115 return polarRadius(); 00116 } 00117 00118 /// Synonym for polarRadius 00119 double rho() const { 00120 return polarRadius(); 00121 } 00122 00123 /// Angle subtended by the vector's projection in x-y and the x-axis. 00124 double azimuthalAngle(const PhiMapping mapping = ZERO_2PI) const { 00125 // If this is a null vector, return zero rather than let atan2 set an error state 00126 if (Rivet::isZero(mod2())) return 0.0; 00127 00128 // Calculate the arctan and return in the requested range 00129 const double value = atan2( y(), x() ); 00130 return mapAngle(value, mapping); 00131 } 00132 00133 /// Synonym for azimuthalAngle. 00134 double phi(const PhiMapping mapping = ZERO_2PI) const { 00135 return azimuthalAngle(mapping); 00136 } 00137 00138 /// Angle subtended by the vector and the z-axis. 00139 double polarAngle() const { 00140 // Get number beween [0,PI] 00141 const double polarangle = atan2(polarRadius(), z()); 00142 return mapAngle0ToPi(polarangle); 00143 } 00144 00145 /// Synonym for polarAngle 00146 double theta() const { 00147 return polarAngle(); 00148 } 00149 00150 /// Purely geometric approximation to rapidity; exact for massless particles 00151 /// and in the central region. 00152 // cut-off such that |eta| < log(2/DBL_EPSILON) 00153 double pseudorapidity() const { 00154 const double epsilon = DBL_EPSILON; 00155 double m = mod(); 00156 if ( m == 0.0 ) return 0.0; 00157 double pt = max(epsilon*m, perp()); 00158 double rap = std::log((m + fabs(z()))/pt); 00159 return z() > 0.0 ? rap: -rap; 00160 } 00161 00162 /// Synonym for pseudorapidity. 00163 double eta() const { 00164 return pseudorapidity(); 00165 } 00166 00167 public: 00168 Vector3& operator*=(const double a) { 00169 _vec = multiply(a, *this)._vec; 00170 return *this; 00171 } 00172 00173 Vector3& operator/=(const double a) { 00174 _vec = multiply(1.0/a, *this)._vec; 00175 return *this; 00176 } 00177 00178 Vector3& operator+=(const Vector3& v) { 00179 _vec = add(*this, v)._vec; 00180 return *this; 00181 } 00182 00183 Vector3& operator-=(const Vector3& v) { 00184 _vec = subtract(*this, v)._vec; 00185 return *this; 00186 } 00187 00188 Vector3 operator-() const { 00189 Vector3 rtn; 00190 rtn._vec = -_vec; 00191 return rtn; 00192 } 00193 00194 }; 00195 00196 00197 00198 inline double dot(const Vector3& a, const Vector3& b) { 00199 return a.dot(b); 00200 } 00201 00202 inline Vector3 cross(const Vector3& a, const Vector3& b) { 00203 return a.cross(b); 00204 } 00205 00206 inline Vector3 multiply(const double a, const Vector3& v) { 00207 Vector3 result; 00208 result._vec = a * v._vec; 00209 return result; 00210 } 00211 00212 inline Vector3 multiply(const Vector3& v, const double a) { 00213 return multiply(a, v); 00214 } 00215 00216 inline Vector3 operator*(const double a, const Vector3& v) { 00217 return multiply(a, v); 00218 } 00219 00220 inline Vector3 operator*(const Vector3& v, const double a) { 00221 return multiply(a, v); 00222 } 00223 00224 inline Vector3 operator/(const Vector3& v, const double a) { 00225 return multiply(1.0/a, v); 00226 } 00227 00228 inline Vector3 add(const Vector3& a, const Vector3& b) { 00229 Vector3 result; 00230 result._vec = a._vec + b._vec; 00231 return result; 00232 } 00233 00234 inline Vector3 subtract(const Vector3& a, const Vector3& b) { 00235 Vector3 result; 00236 result._vec = a._vec - b._vec; 00237 return result; 00238 } 00239 00240 inline Vector3 operator+(const Vector3& a, const Vector3& b) { 00241 return add(a, b); 00242 } 00243 00244 inline Vector3 operator-(const Vector3& a, const Vector3& b) { 00245 return subtract(a, b); 00246 } 00247 00248 // More physicsy coordinates etc. 00249 00250 /// Angle (in radians) between two 3-vectors. 00251 inline double angle(const Vector3& a, const Vector3& b) { 00252 return a.angle(b); 00253 } 00254 00255 ///////////////////////////////////////////////////// 00256 00257 /// @name \f$ |\Delta eta| \f$ calculations from 3-vectors 00258 //@{ 00259 00260 /// Calculate the difference in pseudorapidity between two spatial vectors. 00261 inline double deltaEta(const Vector3& a, const Vector3& b) { 00262 return deltaEta(a.pseudorapidity(), b.pseudorapidity()); 00263 } 00264 00265 /// Calculate the difference in pseudorapidity between two spatial vectors. 00266 inline double deltaEta(const Vector3& v, double eta2) { 00267 return deltaEta(v.pseudorapidity(), eta2); 00268 } 00269 00270 /// Calculate the difference in pseudorapidity between two spatial vectors. 00271 inline double deltaEta(double eta1, const Vector3& v) { 00272 return deltaEta(eta1, v.pseudorapidity()); 00273 } 00274 00275 //@} 00276 00277 00278 /// @name \f$ \Delta phi \f$ calculations from 3-vectors 00279 //@{ 00280 00281 /// Calculate the difference in azimuthal angle between two spatial vectors. 00282 inline double deltaPhi(const Vector3& a, const Vector3& b) { 00283 return deltaPhi(a.azimuthalAngle(), b.azimuthalAngle()); 00284 } 00285 00286 /// Calculate the difference in azimuthal angle between two spatial vectors. 00287 inline double deltaPhi(const Vector3& v, double phi2) { 00288 return deltaPhi(v.azimuthalAngle(), phi2); 00289 } 00290 00291 /// Calculate the difference in azimuthal angle between two spatial vectors. 00292 inline double deltaPhi(double phi1, const Vector3& v) { 00293 return deltaPhi(phi1, v.azimuthalAngle()); 00294 } 00295 00296 //@} 00297 00298 00299 /// @name \f$ \Delta R \f$ calculations from 3-vectors 00300 //@{ 00301 00302 /// Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two spatial vectors. 00303 inline double deltaR(const Vector3& a, const Vector3& b) { 00304 return deltaR(a.pseudorapidity(), a.azimuthalAngle(), 00305 b.pseudorapidity(), b.azimuthalAngle()); 00306 } 00307 00308 /// Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two spatial vectors. 00309 inline double deltaR(const Vector3& v, double eta2, double phi2) { 00310 return deltaR(v.pseudorapidity(), v.azimuthalAngle(), eta2, phi2); 00311 } 00312 00313 /// Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two spatial vectors. 00314 inline double deltaR(double eta1, double phi1, const Vector3& v) { 00315 return deltaR(eta1, phi1, v.pseudorapidity(), v.azimuthalAngle()); 00316 } 00317 00318 //@} 00319 00320 } 00321 00322 #endif Generated on Thu Mar 10 2016 08:29:53 for The Rivet MC analysis system by ![]() |