thepeg is hosted by Hepforge, IPPP Durham
ThePEG 2.3.0
ThreeVector.h
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// ThreeVector.h is a part of ThePEG - Toolkit for HEP Event Generation
4// Copyright (C) 2006-2019 David Grellscheid, Leif Lonnblad
5//
6// ThePEG is licenced under version 3 of the GPL, see COPYING for details.
7// Please respect the MCnet academic guidelines, see GUIDELINES for details.
8//
9#ifndef ThePEG_ThreeVector_H
10#define ThePEG_ThreeVector_H
11
19#include "ThreeVector.fh"
21#include "ThePEG/Utilities/UnitIO.h"
22#include <cassert>
23#include <cmath>
24
25namespace ThePEG {
26
33template <typename Value>
35{
36private:
38 using Value2 = decltype(sqr(std::declval<Value>()));
39
40public:
44 : theX(), theY(), theZ() {}
45
46 ThreeVector(Value x, Value y, Value z)
47 : theX(x), theY(y), theZ(z) {}
48
49 template<typename ValueB>
50 ThreeVector(const ThreeVector<ValueB> & v)
51 : theX(v.x()), theY(v.y()), theZ(v.z()) {}
53
54public:
56
57 Value x() const { return theX; }
58 Value y() const { return theY; }
59 Value z() const { return theZ; }
61
63
64 void setX(Value x) { theX = x; }
65 void setY(Value y) { theY = y; }
66 void setZ(Value z) { theZ = z; }
68
69public:
71 Value2 mag2() const { return sqr(x()) + sqr(y()) + sqr(z()); }
72
74 Value mag() const { return sqrt(mag2()); }
75
77 Value2 perp2() const { return sqr(x()) + sqr(y()); }
78
80 Value perp() const { return sqrt(perp2()); }
81
83 template <typename U>
84 auto dot(const ThreeVector<U> & a) const
85 -> decltype(this->x()*a.x())
86 {
87 return x()*a.x() + y()*a.y() + z()*a.z();
88 }
89
91 template <typename U>
92 Value2 perp2(const ThreeVector<U> & p) const {
93 const auto pMag2 = p.mag2();
94 assert( pMag2 > ZERO );
95 auto ss = this->dot(p);
96 Value2 ret = mag2() - sqr(ss)/pMag2;
97 if ( ret <= ZERO )
98 ret = ZERO;
99 return ret;
100 }
101
103 template <typename U>
104 Value perp(const ThreeVector<U> & p) const {
105 return sqrt(perp2(p));
106 }
107
109
110
111 double theta() const {
112 assert(!(x() == ZERO && y() == ZERO && z() == ZERO));
113 return atan2(perp(),z());
114 }
115
117 double phi() const {
118 return atan2(y(),x());
119 }
120
122 void setTheta(double th) {
123 double ma = mag();
124 double ph = phi();
125 setX(ma*sin(th)*cos(ph));
126 setY(ma*sin(th)*sin(ph));
127 setZ(ma*cos(th));
128 }
129
131 void setPhi(double ph) {
132 double xy = perp();
133 setX(xy*cos(ph));
134 setY(xy*sin(ph));
135 }
137
140 Value2 mg2 = mag2();
141 assert(mg2 > ZERO);
142 Value mg = sqrt(mg2);
143 return {x()/mg, y()/mg, z()/mg};
144 }
145
148 Value xx = abs(x());
149 Value yy = abs(y());
150 Value zz = abs(z());
151 using TVec = ThreeVector<Value>;
152 if (xx < yy) {
153 return xx < zz ? TVec{ZERO,z(),-y()} : TVec{y(),-x(),ZERO};
154 } else {
155 return yy < zz ? TVec{-z(),ZERO,x()} : TVec{y(),-x(),ZERO};
156 }
157 }
158
160 template <typename U>
161 double deltaPhi (const ThreeVector<U> & v2) const {
162 double dphi = v2.phi() - phi();
163 if ( dphi > Constants::pi ) {
164 dphi -= Constants::twopi;
165 } else if ( dphi <= -Constants::pi ) {
166 dphi += Constants::twopi;
167 }
168 return dphi;
169 }
170
176 template <typename U>
178 if (angle == 0.0)
179 return *this;
180 const U ll = axis.mag();
181 assert( ll > ZERO );
182
183 const double sa = sin(angle), ca = cos(angle);
184 const double dx = axis.x()/ll, dy = axis.y()/ll, dz = axis.z()/ll;
185 const Value xx = x(), yy = y(), zz = z();
186
187 setX((ca+(1-ca)*dx*dx) * xx
188 +((1-ca)*dx*dy-sa*dz) * yy
189 +((1-ca)*dx*dz+sa*dy) * zz
190 );
191 setY(((1-ca)*dy*dx+sa*dz) * xx
192 +(ca+(1-ca)*dy*dy) * yy
193 +((1-ca)*dy*dz-sa*dx) * zz
194 );
195 setZ(((1-ca)*dz*dx-sa*dy) * xx
196 +((1-ca)*dz*dy+sa*dx) * yy
197 +(ca+(1-ca)*dz*dz) * zz
198 );
199 return *this;
200 }
201
202
207 Axis ax = axis.unit();
208 double u1 = ax.x();
209 double u2 = ax.y();
210 double u3 = ax.z();
211 double up = u1*u1 + u2*u2;
212 if (up>0) {
213 up = sqrt(up);
214 Value px = x(), py = y(), pz = z();
215 setX( (u1*u3*px - u2*py)/up + u1*pz );
216 setY( (u2*u3*px + u1*py)/up + u2*pz );
217 setZ( -up*px + u3*pz );
218 }
219 else if (u3 < 0.) {
220 setX(-x());
221 setZ(-z());
222 }
223 return *this;
224 }
225
230 Axis ax = axis.unit();
231 double u1 = ax.x();
232 double u2 = ax.y();
233 double u3 = ax.z();
234 double up = u1*u1 + u2*u2;
235 if (up>0) {
236 up = sqrt(up);
237 Value px = x(), py = y(), pz = z();
238 setX( ( u1*u3*px + u2*u3*py)/up - up*pz );
239 setY( (-u2*px + u1*py)/up );
240 setZ( u1*px + u2*py + u3*pz );
241 }
242 else if (u3 < 0.) {
243 setX(-x());
244 setZ(-z());
245 }
246 return *this;
247 }
248
250 template <typename U>
251 auto cross(const ThreeVector<U> & a) const
252 -> ThreeVector<decltype(this->y()*a.z())>
253 {
254 return { y()*a.z()-z()*a.y(),
255 -x()*a.z()+z()*a.x(),
256 x()*a.y()-y()*a.x() };
257 }
258
259 public:
261
262 bool operator==(const ThreeVector<Value> & a) const {
263 return (theX == a.x() && theY == a.y() && theZ == a.z());
264 }
265 bool operator!=(const ThreeVector<Value> & a) const {
266 return !(*this == a);
267 }
268 bool almostEqual(const ThreeVector<Value> & a, double threshold = 1e-04) const {
269 return ((std::abs(theX - a.x()) < threshold) && (std::abs(theY - a.y()) < threshold) && (std::abs(theZ - a.z()) < threshold));
270 }
271 bool almostUnequal(const ThreeVector<Value> & a, double threshold = 1e-04) const {
272 return ! this->almostEqual(a, threshold);
273 }
275
276public:
278
279 ThreeVector<Value> & operator+=(const ThreeVector<Value> & a) {
280 theX += a.x();
281 theY += a.y();
282 theZ += a.z();
283 return *this;
284 }
285
286 ThreeVector<Value> & operator-=(const ThreeVector<Value> & a) {
287 theX -= a.x();
288 theY -= a.y();
289 theZ -= a.z();
290 return *this;
291 }
292
293 ThreeVector<Value> & operator*=(double a) {
294 theX *= a;
295 theY *= a;
296 theZ *= a;
297 return *this;
298 }
299
300 ThreeVector<Value> & operator/=(double a) {
301 theX /= a;
302 theY /= a;
303 theZ /= a;
304 return *this;
305 }
307
309 template <typename U>
310 double cosTheta(const ThreeVector<U> & q) const {
311 auto ptot = mag()*q.mag();
312 assert( ptot > ZERO );
313 double arg = dot(q)/ptot;
314 if (arg > 1.0) arg = 1.0;
315 else if(arg < -1.0) arg = -1.0;
316 return arg;
317 }
318
320 template <typename U>
321 double angle(const ThreeVector<U> & v) const {
322 return acos(cosTheta(v));
323 }
324
325private:
327
328 Value theX;
329 Value theY;
330 Value theZ;
332};
333
335inline ostream &
336operator<< (ostream & os, const ThreeVector<double> & v)
337{
338 return os << '(' << v.x() << ',' << v.y() << ',' << v.z() << ')';
339}
340
342
343template <typename Value>
344inline ThreeVector<Value>
345operator+(ThreeVector<Value> a,
346 const ThreeVector<Value> & b)
347{
348 return a += b;
349}
350
351template <typename Value>
352inline ThreeVector<Value>
353operator-(ThreeVector<Value> a,
354 const ThreeVector<Value> & b)
355{
356 return a -= b;
357}
358
359template <typename Value>
360inline ThreeVector<Value> operator-(const ThreeVector<Value> & v) {
361 return {-v.x(),-v.y(),-v.z()};
362}
363
364template <typename Value>
365inline ThreeVector<Value> operator*(ThreeVector<Value> v, double a) {
366 return v *= a;
367}
368
369template <typename Value>
370inline ThreeVector<Value> operator*(double a, ThreeVector<Value> v) {
371 return v *= a;
372}
373
374template <typename ValueA, typename ValueB>
375inline auto operator*(ValueB a, ThreeVector<ValueA> v)
376-> ThreeVector<decltype(a*v.x())>
377{
378 return {a*v.x(), a*v.y(), a*v.z()};
379}
380
381template <typename ValueA, typename ValueB>
382inline auto operator*(ThreeVector<ValueA> v, ValueB a)
383-> ThreeVector<decltype(v.x()*a)>
384{
385 return {v.x()*a, v.y()*a, v.z()*a};
386}
388
390template <typename ValueA, typename ValueB>
391inline auto operator*(const ThreeVector<ValueA> & a,
392 const ThreeVector<ValueB> & b)
393-> decltype(a.x()*b.x())
394{
395 return a.dot(b);
396}
397
399template <typename Value>
401 return v.unit();
402}
403
404
406template <typename OStream, typename UT, typename Value>
407void ounitstream(OStream & os, const ThreeVector<Value> & p, UT & u) {
408 os << ounit(p.x(), u) << ounit(p.y(), u) << ounit(p.z(), u);
409}
410
412template <typename IStream, typename UT, typename Value>
413void iunitstream(IStream & is, ThreeVector<Value> & p, UT & u) {
414 Value x, y, z;
415 is >> iunit(x, u) >> iunit(y, u) >> iunit(z, u);
416 p = ThreeVector<Value>(x, y, z);
417}
418
419}
420
421#endif /* ThePEG_ThreeVector_H */
This is the main config header file for ThePEG.
A 3-component vector.
Definition: ThreeVector.h:35
ThreeVector< Value > & rotate(double angle, const ThreeVector< U > &axis)
Apply a rotation.
Definition: ThreeVector.h:177
double angle(const ThreeVector< U > &v) const
Angle between two vectors.
Definition: ThreeVector.h:321
Value2 perp2() const
Squared transverse component .
Definition: ThreeVector.h:77
Value mag() const
Magnitude .
Definition: ThreeVector.h:74
ThreeVector< double > unit() const
Parallel vector with unit length.
Definition: ThreeVector.h:139
ThreeVector< Value > orthogonal() const
Orthogonal vector.
Definition: ThreeVector.h:147
Value perp() const
Transverse component .
Definition: ThreeVector.h:80
auto dot(const ThreeVector< U > &a) const -> decltype(this->x() *a.x())
Dot product.
Definition: ThreeVector.h:84
double phi() const
Azimuthal angle.
Definition: ThreeVector.h:117
void setTheta(double th)
Set the polar angle.
Definition: ThreeVector.h:122
void setPhi(double ph)
Set the azimuthal angle.
Definition: ThreeVector.h:131
Value2 perp2(const ThreeVector< U > &p) const
Squared transverse component with respect to the given axis.
Definition: ThreeVector.h:92
auto cross(const ThreeVector< U > &a) const -> ThreeVector< decltype(this->y() *a.z())>
Vector cross-product.
Definition: ThreeVector.h:251
double theta() const
Polar angle.
Definition: ThreeVector.h:111
double cosTheta(const ThreeVector< U > &q) const
Cosine of the azimuthal angle between two vectors.
Definition: ThreeVector.h:310
ThreeVector< Value > & rotateUzBack(const Axis &axis)
Rotate from a reference frame to the z-axis.
Definition: ThreeVector.h:229
Value2 mag2() const
Squared magnitude .
Definition: ThreeVector.h:71
double deltaPhi(const ThreeVector< U > &v2) const
Azimuthal angle difference, brought into the range .
Definition: ThreeVector.h:161
decltype(sqr(std::declval< Value >())) Value2
Value squared.
Definition: ThreeVector.h:38
Value perp(const ThreeVector< U > &p) const
Transverse component with respect to the given axis.
Definition: ThreeVector.h:104
ThreeVector< Value > & rotateUz(const Axis &axis)
Rotate the reference frame to a new z-axis.
Definition: ThreeVector.h:206
constexpr double twopi
Good old .
Definition: Constants.h:57
constexpr double pi
Good old .
Definition: Constants.h:54
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
ThreeVector< double > unitVector(const ThreeVector< Value > &v)
A parallel vector with unit length.
Definition: ThreeVector.h:400
IUnit< T, UT > iunit(T &t, const UT &ut)
Helper function creating a IUnit object given an object and a unit.
Definition: UnitIO.h:91
void iunitstream(IStream &is, vector< T, Alloc > &v, UT &u)
Input a vector of objects with the specified unit.
Definition: Containers.h:289
vector< T > & operator<<(vector< T > &tv, const U &u)
Overload the left shift operator for vector to push_back objects to a vector.
Definition: Containers.h:179
void ounitstream(OStream &os, const vector< T, Alloc > &v, UT &u)
Ouput a vector of objects with the specified unit.
Definition: Containers.h:275
constexpr ZeroUnit ZERO
ZERO can be used as zero for any unitful quantity.
Definition: PhysicalQty.h:35
constexpr auto sqr(const T &x) -> decltype(x *x)
The square function should really have been included in the standard C++ library.
Definition: ThePEG.h:117
OUnit< T, UT > ounit(const T &t, const UT &ut)
Helper function creating a OUnit object given an object and a unit.
Definition: UnitIO.h:84