Version: SMASH-1.5
threevector.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2018
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #ifndef SRC_INCLUDE_THREEVECTOR_H_
11 #define SRC_INCLUDE_THREEVECTOR_H_
12 
13 #include <array>
14 #include <cmath>
15 
16 #include "constants.h"
17 
18 namespace smash {
19 
30 class ThreeVector {
31  public:
33  ThreeVector() : x_({0., 0., 0.}) {}
34 
36  ThreeVector(double y1, double y2, double y3) : x_({y1, y2, y3}) {}
37 
39  double &operator[](std::size_t i) { return x_[i]; }
41  double operator[](std::size_t i) const { return x_[i]; }
42 
44  double inline x1() const;
46  void inline set_x1(double x);
48  double inline x2() const;
50  void inline set_x2(double y);
52  double inline x3() const;
54  void inline set_x3(double z);
56  double inline sqr() const;
58  double inline abs() const;
60  double inline get_phi() const;
62  double inline get_theta() const;
81  void inline rotate(double phi, double theta, double psi);
86  void inline rotate_around_y(double theta);
91  void inline rotate_around_z(double theta);
96  void inline rotate_z_axis_to(ThreeVector &r);
98  ThreeVector inline operator-() const;
100  ThreeVector inline operator+=(const ThreeVector &v);
102  ThreeVector inline operator-=(const ThreeVector &v);
104  ThreeVector inline operator*=(const double &a);
106  ThreeVector inline operator/=(const double &a);
107 
109  bool operator==(const ThreeVector &rhs) const { return x_ == rhs.x_; }
111  bool operator!=(const ThreeVector &rhs) const { return x_ != rhs.x_; }
112 
117  ThreeVector inline CrossProduct(const ThreeVector &b) const;
119  using iterator = std::array<double, 3>::iterator;
121  using const_iterator = std::array<double, 3>::const_iterator;
122 
129  iterator begin() { return x_.begin(); }
130 
132  iterator end() { return x_.end(); }
133 
135  const_iterator begin() const { return x_.begin(); }
137  const_iterator end() const { return x_.end(); }
138 
140  const_iterator cbegin() const { return x_.cbegin(); }
142  const_iterator cend() const { return x_.cend(); }
143 
144  private:
146  std::array<double, 3> x_;
147 };
148 
153 std::ostream &operator<<(std::ostream &, const ThreeVector &);
154 
155 double inline ThreeVector::x1() const { return x_[0]; }
156 
157 void inline ThreeVector::set_x1(const double x) { x_[0] = x; }
158 
159 double inline ThreeVector::x2() const { return x_[1]; }
160 
161 void inline ThreeVector::set_x2(const double y) { x_[1] = y; }
162 
163 double inline ThreeVector::x3() const { return x_[2]; }
164 
165 void inline ThreeVector::set_x3(const double z) { x_[2] = z; }
166 
168  ThreeVector neg(-x_[0], -x_[1], -x_[2]);
169  return neg;
170 }
171 
173  x_[0] += v.x_[0];
174  x_[1] += v.x_[1];
175  x_[2] += v.x_[2];
176  return *this;
177 }
178 
181  a += b;
182  return a;
183 }
184 
186  x_[0] -= v.x_[0];
187  x_[1] -= v.x_[1];
188  x_[2] -= v.x_[2];
189  return *this;
190 }
191 
194  a -= b;
195  return a;
196 }
197 
198 ThreeVector inline ThreeVector::operator*=(const double &a) {
199  x_[0] *= a;
200  x_[1] *= a;
201  x_[2] *= a;
202  return *this;
203 }
204 
206 inline ThreeVector operator*(ThreeVector a, const double &b) {
207  a *= b;
208  return a;
209 }
210 
212 inline ThreeVector operator*(const double &a, ThreeVector b) {
213  b *= a;
214  return b;
215 }
216 
221 inline double operator*(ThreeVector a, const ThreeVector &b) {
222  return a.x1() * b.x1() + a.x2() * b.x2() + a.x3() * b.x3();
223 }
224 
230  return ThreeVector(x_[1] * b.x3() - x_[2] * b.x2(),
231  x_[2] * b.x1() - x_[0] * b.x3(),
232  x_[0] * b.x2() - x_[1] * b.x1());
233 }
234 
235 ThreeVector inline ThreeVector::operator/=(const double &a) {
236  const double a_inv = 1.0 / a;
237  x_[0] *= a_inv;
238  x_[1] *= a_inv;
239  x_[2] *= a_inv;
240  return *this;
241 }
242 
244 ThreeVector inline operator/(ThreeVector a, const double &b) {
245  a /= b;
246  return a;
247 }
248 
249 double inline ThreeVector::sqr() const { return (*this) * (*this); }
250 
251 double inline ThreeVector::abs() const { return std::sqrt((*this) * (*this)); }
252 
253 double inline ThreeVector::get_phi() const {
254  if (std::abs(x1()) < really_small && std::abs(x2()) < really_small) {
255  return 0.;
256  } else {
257  return std::atan2(x2(), x1());
258  }
259 }
260 
261 double inline ThreeVector::get_theta() const {
262  double r = abs();
263  return (r > 0.) ? std::acos(x3() / r) : 0.;
264 }
265 
266 void inline ThreeVector::rotate(double phi, double theta, double psi) {
267  // Compute the cosine and sine for each angle.
268  const double cos_phi = std::cos(phi);
269  const double sin_phi = std::sin(phi);
270  const double cos_theta = std::cos(theta);
271  const double sin_theta = std::sin(theta);
272  const double cos_psi = std::cos(psi);
273  const double sin_psi = std::sin(psi);
274  // Get original coordinates.
275  std::array<double, 3> x_old = x_;
276  // Compute new coordinates.
277  x_[0] = (cos_phi * cos_psi - sin_phi * cos_theta * sin_psi) * x_old[0] +
278  (sin_phi * cos_psi + cos_phi * cos_theta * sin_psi) * x_old[1] +
279  sin_theta * sin_psi * x_old[2];
280  x_[1] = (-cos_phi * sin_psi - sin_phi * cos_theta * cos_psi) * x_old[0] +
281  (-sin_phi * sin_psi + cos_phi * cos_theta * cos_psi) * x_old[1] +
282  sin_theta * cos_psi * x_old[2];
283  x_[2] = sin_phi * sin_theta * x_old[0] - cos_phi * sin_theta * x_old[1] +
284  cos_theta * x_old[2];
285 }
286 
287 void inline ThreeVector::rotate_around_y(double theta) {
288  const double cost = std::cos(theta);
289  const double sint = std::sin(theta);
290  // Get original coordinates.
291  std::array<double, 3> x_old = x_;
292  // Compute new coordinates.
293  x_[0] = cost * x_old[0] + sint * x_old[2];
294  // x_[1] is unchanged
295  x_[2] = -sint * x_old[0] + cost * x_old[2];
296 }
297 
298 void inline ThreeVector::rotate_around_z(double theta) {
299  const double cost = std::cos(theta);
300  const double sint = std::sin(theta);
301  // Get original coordinates.
302  std::array<double, 3> x_old = x_;
303  // Compute new coordinates.
304  x_[0] = cost * x_old[0] - sint * x_old[1];
305  x_[1] = sint * x_old[0] + cost * x_old[1];
306  // x_[2] is unchanged
307 }
308 
312 }
313 
314 } // namespace smash
315 
316 #endif // SRC_INCLUDE_THREEVECTOR_H_
ThreeVector operator/=(const double &a)
divide this vector by
Definition: threevector.h:235
double & operator[](std::size_t i)
access the component at offset i.
Definition: threevector.h:39
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:30
double x3() const
Definition: threevector.h:163
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:34
const_iterator cbegin() const
Definition: threevector.h:140
EnergyMomentumTensor operator/(EnergyMomentumTensor a, const double b)
Direct division operator.
const_iterator begin() const
const overload of the above
Definition: threevector.h:135
ThreeVector operator+=(const ThreeVector &v)
increase this vector by
Definition: threevector.h:172
Collection of useful constants that are known at compile time.
EnergyMomentumTensor operator+(EnergyMomentumTensor a, const EnergyMomentumTensor &b)
Direct addition operator.
double x1() const
Definition: threevector.h:155
std::array< double, 3 > x_
the internal storage of the components.
Definition: threevector.h:146
ThreeVector operator*=(const double &a)
scale this vector by
Definition: threevector.h:198
ThreeVector()
default constructor (nulls all components)
Definition: threevector.h:33
EnergyMomentumTensor operator-(EnergyMomentumTensor a, const EnergyMomentumTensor &b)
Direct subtraction operator.
void rotate_around_y(double theta)
Rotate the vector around the y axis by the given angle theta.
Definition: threevector.h:287
double abs() const
Definition: threevector.h:251
void set_x1(double x)
set first component
Definition: threevector.h:157
double get_phi() const
Definition: threevector.h:253
bool operator!=(const ThreeVector &rhs) const
Definition: threevector.h:111
void rotate_z_axis_to(ThreeVector &r)
Rotate the z-axis onto the vector r.
Definition: threevector.h:309
double operator[](std::size_t i) const
const overload of the above.
Definition: threevector.h:41
std::array< double, 3 >::const_iterator const_iterator
iterates over the components
Definition: threevector.h:121
const_iterator cend() const
Definition: threevector.h:142
void rotate_around_z(double theta)
Rotate the vector around the z axis by the given angle theta.
Definition: threevector.h:298
const_iterator end() const
const overload of the above
Definition: threevector.h:137
bool operator==(const ThreeVector &rhs) const
Definition: threevector.h:109
double sqr() const
Definition: threevector.h:249
ThreeVector operator-=(const ThreeVector &v)
decrease this vector by
Definition: threevector.h:185
EnergyMomentumTensor operator*(EnergyMomentumTensor a, const double b)
Direct multiplication operator.
double get_theta() const
Definition: threevector.h:261
ThreeVector CrossProduct(const ThreeVector &b) const
Definition: threevector.h:229
std::array< double, 3 >::iterator iterator
iterates over the components
Definition: threevector.h:119
void set_x3(double z)
set third component
Definition: threevector.h:165
ThreeVector operator-() const
negation: Returns
Definition: threevector.h:167
iterator begin()
Definition: threevector.h:129
ThreeVector(double y1, double y2, double y3)
copy constructor
Definition: threevector.h:36
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
Definition: action.h:457
void set_x2(double y)
set second component
Definition: threevector.h:161
double x2() const
Definition: threevector.h:159
void rotate(double phi, double theta, double psi)
Rotate vector by the given Euler angles phi, theta, psi.
Definition: threevector.h:266
Definition: action.h:24