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 00008 namespace Rivet { 00009 00010 00011 class Vector3; 00012 typedef Vector3 ThreeVector; 00013 class Matrix3; 00014 00015 Vector3 multiply(const double, const Vector3&); 00016 Vector3 multiply(const Vector3&, const double); 00017 Vector3 add(const Vector3&, const Vector3&); 00018 Vector3 operator*(const double, const Vector3&); 00019 Vector3 operator*(const Vector3&, const double); 00020 Vector3 operator/(const Vector3&, const double); 00021 Vector3 operator+(const Vector3&, const Vector3&); 00022 Vector3 operator-(const Vector3&, const Vector3&); 00023 00024 00025 /// @brief Three-dimensional specialisation of Vector. 00026 class Vector3 : public Vector<3> { 00027 00028 friend class Matrix3; 00029 friend Vector3 multiply(const double, const Vector3&); 00030 friend Vector3 multiply(const Vector3&, const double); 00031 friend Vector3 add(const Vector3&, const Vector3&); 00032 friend Vector3 subtract(const Vector3&, const Vector3&); 00033 00034 public: 00035 Vector3() : Vector<3>() { } 00036 00037 template<typename V3> 00038 Vector3(const V3& other) { 00039 this->setX(other.x()); 00040 this->setY(other.y()); 00041 this->setZ(other.z()); 00042 } 00043 00044 Vector3(const Vector<3>& other) { 00045 this->setX(other.get(0)); 00046 this->setY(other.get(1)); 00047 this->setZ(other.get(2)); 00048 } 00049 00050 Vector3(double x, double y, double z) { 00051 this->setX(x); 00052 this->setY(y); 00053 this->setZ(z); 00054 } 00055 00056 ~Vector3() { } 00057 00058 public: 00059 static Vector3 mkX() { return Vector3(1,0,0); } 00060 static Vector3 mkY() { return Vector3(0,1,0); } 00061 static Vector3 mkZ() { return Vector3(0,0,1); } 00062 00063 public: 00064 double x() const { return get(0); } 00065 double y() const { return get(1); } 00066 double z() const { return get(2); } 00067 Vector3& setX(double x) { set(0, x); return *this; } 00068 Vector3& setY(double y) { set(1, y); return *this; } 00069 Vector3& setZ(double z) { set(2, z); return *this; } 00070 00071 double dot(const Vector3& v) const { 00072 return _vec.dot(v._vec); 00073 } 00074 00075 Vector3 cross(const Vector3& v) const { 00076 Vector3 result; 00077 result._vec = _vec.cross(v._vec); 00078 return result; 00079 } 00080 00081 double angle(const Vector3& v) const { 00082 const double localDotOther = unit().dot(v.unit()); 00083 if (fuzzyEquals(localDotOther, 1.0)) return 0.0; 00084 else if (fuzzyEquals(localDotOther, -1.0)) return M_PI; 00085 return acos(localDotOther); 00086 } 00087 00088 Vector3 unit() const { 00089 /// @todo What to do in this situation? 00090 if (isZero()) return *this; 00091 else return *this * 1.0/this->mod(); 00092 } 00093 00094 double polarRadius2() const { 00095 return x()*x() + y()*y(); 00096 } 00097 00098 /// Synonym for polarRadius2 00099 double perp2() const { 00100 return polarRadius2(); 00101 } 00102 00103 /// Synonym for polarRadius2 00104 double rho2() const { 00105 return polarRadius2(); 00106 } 00107 00108 double polarRadius() const { 00109 return sqrt(polarRadius2()); 00110 } 00111 00112 /// Synonym for polarRadius 00113 double perp() const { 00114 return polarRadius(); 00115 } 00116 00117 /// Synonym for polarRadius 00118 double rho() const { 00119 return polarRadius(); 00120 } 00121 00122 /// Angle subtended by the vector's projection in x-y and the x-axis. 00123 double azimuthalAngle(const PhiMapping mapping = ZERO_2PI) const { 00124 // If this is a null vector, return zero rather than let atan2 set an error state 00125 if (Rivet::isZero(mod2())) return 0.0; 00126 00127 // Calculate the arctan and correct for numerical boundary cases 00128 double value = atan2( y(), x() ); 00129 if (value > 2*PI || value < -2*PI){ 00130 value = fmod(value, 2*PI); 00131 } 00132 if (value <= -PI) value += 2*PI; 00133 if (value > PI) value -= 2*PI; 00134 00135 // Return in the requested range 00136 switch (mapping) { 00137 case MINUSPI_PLUSPI: 00138 assert(value > -PI && value <= PI); 00139 return value; 00140 case ZERO_2PI: 00141 if (value >= 0) { 00142 assert(value >= 0 && value < 2*PI); 00143 return value; 00144 } else if (Rivet::isZero(value)) { 00145 value = 0.0; 00146 return value; 00147 } else { 00148 value = 2*PI + value; 00149 assert(value >= 0 && value < 2*PI); 00150 return value; 00151 } 00152 default: 00153 throw std::runtime_error("The specified phi mapping scheme is not yet implemented"); 00154 } 00155 } 00156 00157 /// Synonym for azimuthalAngle. 00158 double phi(const PhiMapping mapping = ZERO_2PI) const { 00159 return azimuthalAngle(mapping); 00160 } 00161 00162 /// Angle subtended by the vector and the z-axis. 00163 double polarAngle() const { 00164 // Get number beween [0,PI] 00165 double polarangle = atan2(polarRadius(), z()); 00166 assert(polarangle >= -PI && polarangle <= PI); 00167 return polarangle; 00168 } 00169 00170 /// Synonym for polarAngle 00171 double theta() const { 00172 return polarAngle(); 00173 } 00174 00175 /// Purely geometric approximation to rapidity; exact for massless particles 00176 /// and in the central region. 00177 double pseudorapidity() const { 00178 return -std::log(tan( 0.5 * polarAngle() )); 00179 } 00180 00181 /// Synonym for pseudorapidity. 00182 double eta() const { 00183 return pseudorapidity(); 00184 } 00185 00186 public: 00187 Vector3& operator*=(const double a) { 00188 _vec = multiply(a, *this)._vec; 00189 return *this; 00190 } 00191 00192 Vector3& operator/=(const double a) { 00193 _vec = multiply(1.0/a, *this)._vec; 00194 return *this; 00195 } 00196 00197 Vector3& operator+=(const Vector3& v) { 00198 _vec = add(*this, v)._vec; 00199 return *this; 00200 } 00201 00202 Vector3& operator-=(const Vector3& v) { 00203 _vec = subtract(*this, v)._vec; 00204 return *this; 00205 } 00206 00207 Vector3 operator-() const { 00208 Vector3 rtn; 00209 rtn._vec = -_vec; 00210 return rtn; 00211 } 00212 00213 }; 00214 00215 00216 00217 inline double dot(const Vector3& a, const Vector3& b) { 00218 return a.dot(b); 00219 } 00220 00221 inline Vector3 cross(const Vector3& a, const Vector3& b) { 00222 return a.cross(b); 00223 } 00224 00225 inline Vector3 multiply(const double a, const Vector3& v) { 00226 Vector3 result; 00227 result._vec = a * v._vec; 00228 return result; 00229 } 00230 00231 inline Vector3 multiply(const Vector3& v, const double a) { 00232 return multiply(a, v); 00233 } 00234 00235 inline Vector3 operator*(const double a, const Vector3& v) { 00236 return multiply(a, v); 00237 } 00238 00239 inline Vector3 operator*(const Vector3& v, const double a) { 00240 return multiply(a, v); 00241 } 00242 00243 inline Vector3 operator/(const Vector3& v, const double a) { 00244 return multiply(1.0/a, v); 00245 } 00246 00247 inline Vector3 add(const Vector3& a, const Vector3& b) { 00248 Vector3 result; 00249 result._vec = a._vec + b._vec; 00250 return result; 00251 } 00252 00253 inline Vector3 subtract(const Vector3& a, const Vector3& b) { 00254 Vector3 result; 00255 result._vec = a._vec - b._vec; 00256 return result; 00257 } 00258 00259 inline Vector3 operator+(const Vector3& a, const Vector3& b) { 00260 return add(a, b); 00261 } 00262 00263 inline Vector3 operator-(const Vector3& a, const Vector3& b) { 00264 return subtract(a, b); 00265 } 00266 00267 // More physicsy coordinates etc. 00268 00269 /// Angle (in radians) between two 3-vectors. 00270 inline double angle(const Vector3& a, const Vector3& b) { 00271 return a.angle(b); 00272 } 00273 00274 /// Calculate transverse length sq. \f$ \rho^2 \f$ of a 3-vector. 00275 inline double polarRadius2(const Vector3& v) { 00276 return v.polarRadius2(); 00277 } 00278 /// Synonym for polarRadius2. 00279 inline double perp2(const Vector3& v) { 00280 return v.perp2(); 00281 } 00282 /// Synonym for polarRadius2. 00283 inline double rho2(const Vector3& v) { 00284 return v.rho2(); 00285 } 00286 00287 /// Calculate transverse length \f$ \rho \f$ of a 3-vector. 00288 inline double polarRadius(const Vector3& v) { 00289 return v.polarRadius(); 00290 } 00291 /// Synonym for polarRadius. 00292 inline double perp(const Vector3& v) { 00293 return v.perp(); 00294 } 00295 /// Synonym for polarRadius. 00296 inline double rho(const Vector3& v) { 00297 return v.rho(); 00298 } 00299 00300 00301 /// @brief Calculate azimuthal angle of a 3-vector. 00302 /// Returns a number in (-pi, pi] or in [0, 2pi) according to the mapping scheme selected 00303 inline double azimuthalAngle(const Vector3& v, const PhiMapping mapping = ZERO_2PI) { 00304 return v.azimuthalAngle(mapping); 00305 } 00306 /// Synonym for azimuthalAngle. 00307 inline double phi(const Vector3& v, const PhiMapping mapping = ZERO_2PI) { 00308 return v.phi(mapping); 00309 } 00310 00311 /// Calculate polar angle of a 3-vector. 00312 inline double polarAngle(const Vector3& v) { 00313 return v.polarAngle(); 00314 } 00315 /// Synonym for polarAngle. 00316 inline double theta(const Vector3& v) { 00317 return v.theta(); 00318 } 00319 00320 /// Calculate pseudorapidity of a 3-vector. 00321 inline double pseudorapidity(const Vector3& v) { 00322 return v.pseudorapidity(); 00323 } 00324 /// Synonym for pseudorapidity. 00325 inline double eta(const Vector3& v) { 00326 return v.eta(); 00327 } 00328 00329 00330 ///////////////////////////////////////////////////// 00331 00332 /// @name \f$ |\Delta eta| \f$ calculations from 3-vectors 00333 //@{ 00334 00335 /// Calculate the difference in pseudorapidity between two spatial vectors. 00336 inline double deltaEta(const Vector3& a, const Vector3& b) { 00337 return deltaEta(a.pseudorapidity(), b.pseudorapidity()); 00338 } 00339 00340 /// Calculate the difference in pseudorapidity between two spatial vectors. 00341 inline double deltaEta(const Vector3& v, double eta2) { 00342 return deltaEta(v.pseudorapidity(), eta2); 00343 } 00344 00345 /// Calculate the difference in pseudorapidity between two spatial vectors. 00346 inline double deltaEta(double eta1, const Vector3& v) { 00347 return deltaEta(eta1, v.pseudorapidity()); 00348 } 00349 00350 //@} 00351 00352 00353 /// @name \f$ \Delta phi \f$ calculations from 3-vectors 00354 //@{ 00355 00356 /// Calculate the difference in azimuthal angle between two spatial vectors. 00357 inline double deltaPhi(const Vector3& a, const Vector3& b) { 00358 return deltaPhi(a.azimuthalAngle(), b.azimuthalAngle()); 00359 } 00360 00361 /// Calculate the difference in azimuthal angle between two spatial vectors. 00362 inline double deltaPhi(const Vector3& v, double phi2) { 00363 return deltaPhi(v.azimuthalAngle(), phi2); 00364 } 00365 00366 /// Calculate the difference in azimuthal angle between two spatial vectors. 00367 inline double deltaPhi(double phi1, const Vector3& v) { 00368 return deltaPhi(phi1, v.azimuthalAngle()); 00369 } 00370 00371 //@} 00372 00373 00374 /// @name \f$ \Delta R \f$ calculations from 3-vectors 00375 //@{ 00376 00377 /// Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two spatial vectors. 00378 inline double deltaR(const Vector3& a, const Vector3& b) { 00379 return deltaR(a.pseudorapidity(), a.azimuthalAngle(), 00380 b.pseudorapidity(), b.azimuthalAngle()); 00381 } 00382 00383 /// Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two spatial vectors. 00384 inline double deltaR(const Vector3& v, double eta2, double phi2) { 00385 return deltaR(v.pseudorapidity(), v.azimuthalAngle(), eta2, phi2); 00386 } 00387 00388 /// Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two spatial vectors. 00389 inline double deltaR(double eta1, double phi1, const Vector3& v) { 00390 return deltaR(eta1, phi1, v.pseudorapidity(), v.azimuthalAngle()); 00391 } 00392 00393 //@} 00394 00395 } 00396 00397 #endif Generated on Fri Dec 21 2012 15:03:42 for The Rivet MC analysis system by ![]() |