thepeg is hosted by Hepforge, IPPP Durham
ThePEG  2.2.1
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"
20 #include "ThePEG/Config/ThePEG.h"
21 #include "ThePEG/Utilities/UnitIO.h"
22 #include <cassert>
23 #include <cmath>
24 
25 namespace ThePEG {
26 
33 template <typename Value>
35 {
36 private:
38  using Value2 = decltype(sqr(std::declval<Value>()));
39 
40 public:
43  ThreeVector()
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>
51  : theX(v.x()), theY(v.y()), theZ(v.z()) {}
53 
54 public:
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 
69 public:
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  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>
177  ThreeVector<Value> & rotate(double angle, const ThreeVector<U> & axis) {
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 
206  ThreeVector<Value> & rotateUz (const Axis & axis) {
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 
276 public:
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 
325 private:
327 
328  Value theX;
329  Value theY;
330  Value theZ;
332 };
333 
335 inline ostream &
336 operator<< (ostream & os, const ThreeVector<double> & v)
337 {
338  return os << '(' << v.x() << ',' << v.y() << ',' << v.z() << ')';
339 }
340 
342 
343 template <typename Value>
344 inline ThreeVector<Value>
345 operator+(ThreeVector<Value> a,
346  const ThreeVector<Value> & b)
347 {
348  return a += b;
349 }
350 
351 template <typename Value>
352 inline ThreeVector<Value>
353 operator-(ThreeVector<Value> a,
354  const ThreeVector<Value> & b)
355 {
356  return a -= b;
357 }
358 
359 template <typename Value>
360 inline ThreeVector<Value> operator-(const ThreeVector<Value> & v) {
361  return {-v.x(),-v.y(),-v.z()};
362 }
363 
364 template <typename Value>
365 inline ThreeVector<Value> operator*(ThreeVector<Value> v, double a) {
366  return v *= a;
367 }
368 
369 template <typename Value>
370 inline ThreeVector<Value> operator*(double a, ThreeVector<Value> v) {
371  return v *= a;
372 }
373 
374 template <typename ValueA, typename ValueB>
375 inline 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 
381 template <typename ValueA, typename ValueB>
382 inline 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 
390 template <typename ValueA, typename ValueB>
391 inline 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 
399 template <typename Value>
401  return v.unit();
402 }
403 
404 
406 template <typename OStream, typename UT, typename Value>
407 void 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 
412 template <typename IStream, typename UT, typename Value>
413 void 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 */
decltype(sqr(std::declval< Value >())) Value2
Value squared.
Definition: ThreeVector.h:38
ThreeVector< Value > & rotateUzBack(const Axis &axis)
Rotate from a reference frame to the z-axis.
Definition: ThreeVector.h:229
Value mag() const
Magnitude .
Definition: ThreeVector.h:74
ThreeVector< Value > & rotate(double angle, const ThreeVector< U > &axis)
Apply a rotation.
Definition: ThreeVector.h:177
Value2 perp2() const
Squared transverse component .
Definition: ThreeVector.h:77
auto dot(const ThreeVector< U > &a) const -> decltype(this->x() *a.x())
Dot product.
Definition: ThreeVector.h:84
void ounitstream(OStream &os, const vector< T, Alloc > &v, UT &u)
Ouput a vector of objects with the specified unit.
Definition: Containers.h:275
double deltaPhi(const ThreeVector< U > &v2) const
Azimuthal angle difference, brought into the range .
Definition: ThreeVector.h:161
A 3-component vector.
Definition: ThreeVector.h:34
Value2 mag2() const
Squared magnitude .
Definition: ThreeVector.h:71
constexpr double pi
Good old .
Definition: Constants.h:54
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
Value perp() const
Transverse component .
Definition: ThreeVector.h:80
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
This is the main config header file for ThePEG.
void setPhi(double ph)
Set the azimuthal angle.
Definition: ThreeVector.h:131
void iunitstream(IStream &is, vector< T, Alloc > &v, UT &u)
Input a vector of objects with the specified unit.
Definition: Containers.h:289
double theta() const
Polar angle.
Definition: ThreeVector.h:111
double angle(const ThreeVector< U > &v) const
Angle between two vectors.
Definition: ThreeVector.h:321
auto cross(const ThreeVector< U > &a) const -> ThreeVector< decltype(this->y() *a.z())>
Vector cross-product.
Definition: ThreeVector.h:251
constexpr double twopi
Good old .
Definition: Constants.h:57
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
double cosTheta(const ThreeVector< U > &q) const
Cosine of the azimuthal angle between two vectors.
Definition: ThreeVector.h:310
ThreeVector< double > unit() const
Parallel vector with unit length.
Definition: ThreeVector.h:139
ThreeVector< Value > orthogonal() const
Orthogonal vector.
Definition: ThreeVector.h:147
ThreeVector< Value > & rotateUz(const Axis &axis)
Rotate the reference frame to a new z-axis.
Definition: ThreeVector.h:206
Value perp(const ThreeVector< U > &p) const
Transverse component with respect to the given axis.
Definition: ThreeVector.h:104
double phi() const
Azimuthal angle.
Definition: ThreeVector.h:117
Value2 perp2(const ThreeVector< U > &p) const
Squared transverse component with respect to the given axis.
Definition: ThreeVector.h:92
void setTheta(double th)
Set the polar angle.
Definition: ThreeVector.h:122
constexpr ZeroUnit ZERO
ZERO can be used as zero for any unitful quantity.
Definition: PhysicalQty.h:35
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