Version: SMASH-3.1
threevector.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2015,2017-2020,2022
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #ifndef SRC_INCLUDE_SMASH_THREEVECTOR_H_
11 #define SRC_INCLUDE_SMASH_THREEVECTOR_H_
12 
13 #include <array>
14 #include <cmath>
15 #include <ostream>
16 
17 #include "constants.h"
18 
19 namespace smash {
20 
31 class ThreeVector {
32  public:
34  ThreeVector() : x_({0., 0., 0.}) {}
35 
44  ThreeVector(double y1, double y2, double y3) : x_({y1, y2, y3}) {}
45 
47  double &operator[](std::size_t i) { return x_[i]; }
49  double operator[](std::size_t i) const { return x_[i]; }
50 
52  double inline x1() const;
54  void inline set_x1(double x);
56  double inline x2() const;
58  void inline set_x2(double y);
60  double inline x3() const;
62  void inline set_x3(double z);
64  double inline sqr() const;
66  double inline abs() const;
68  double inline get_phi() const;
70  double inline get_theta() const;
91  void inline rotate(double phi, double theta, double psi);
96  void inline rotate_around_y(double theta);
101  void inline rotate_around_z(double theta);
106  void inline rotate_z_axis_to(ThreeVector &r);
108  ThreeVector inline operator-() const;
113  ThreeVector inline operator+=(const ThreeVector &v);
118  ThreeVector inline operator-=(const ThreeVector &v);
123  ThreeVector inline operator*=(const double &a);
128  ThreeVector inline operator/=(const double &a);
129 
131  bool operator==(const ThreeVector &rhs) const { return x_ == rhs.x_; }
133  bool operator!=(const ThreeVector &rhs) const { return x_ != rhs.x_; }
134 
139  ThreeVector inline cross_product(const ThreeVector &b) const;
141  using iterator = std::array<double, 3>::iterator;
143  using const_iterator = std::array<double, 3>::const_iterator;
144 
151  iterator begin() { return x_.begin(); }
152 
154  iterator end() { return x_.end(); }
155 
157  const_iterator begin() const { return x_.begin(); }
159  const_iterator end() const { return x_.end(); }
160 
162  const_iterator cbegin() const { return x_.cbegin(); }
164  const_iterator cend() const { return x_.cend(); }
165 
166  private:
168  std::array<double, 3> x_;
169 };
170 
175 std::ostream &operator<<(std::ostream &, const ThreeVector &);
176 
177 double inline ThreeVector::x1() const { return x_[0]; }
178 
179 void inline ThreeVector::set_x1(const double x) { x_[0] = x; }
180 
181 double inline ThreeVector::x2() const { return x_[1]; }
182 
183 void inline ThreeVector::set_x2(const double y) { x_[1] = y; }
184 
185 double inline ThreeVector::x3() const { return x_[2]; }
186 
187 void inline ThreeVector::set_x3(const double z) { x_[2] = z; }
188 
190  ThreeVector neg(-x_[0], -x_[1], -x_[2]);
191  return neg;
192 }
193 
195  x_[0] += v.x_[0];
196  x_[1] += v.x_[1];
197  x_[2] += v.x_[2];
198  return *this;
199 }
200 
203  a += b;
204  return a;
205 }
206 
208  x_[0] -= v.x_[0];
209  x_[1] -= v.x_[1];
210  x_[2] -= v.x_[2];
211  return *this;
212 }
213 
216  a -= b;
217  return a;
218 }
219 
220 ThreeVector inline ThreeVector::operator*=(const double &a) {
221  x_[0] *= a;
222  x_[1] *= a;
223  x_[2] *= a;
224  return *this;
225 }
226 
228 inline ThreeVector operator*(ThreeVector a, const double &b) {
229  a *= b;
230  return a;
231 }
232 
234 inline ThreeVector operator*(const double &a, ThreeVector b) {
235  b *= a;
236  return b;
237 }
238 
242 inline double operator*(ThreeVector a, const ThreeVector &b) {
243  return a.x1() * b.x1() + a.x2() * b.x2() + a.x3() * b.x3();
244 }
245 
247  return ThreeVector(x_[1] * b.x3() - x_[2] * b.x2(),
248  x_[2] * b.x1() - x_[0] * b.x3(),
249  x_[0] * b.x2() - x_[1] * b.x1());
250 }
251 
252 ThreeVector inline ThreeVector::operator/=(const double &a) {
253  const double a_inv = 1.0 / a;
254  x_[0] *= a_inv;
255  x_[1] *= a_inv;
256  x_[2] *= a_inv;
257  return *this;
258 }
259 
261 ThreeVector inline operator/(ThreeVector a, const double &b) {
262  a /= b;
263  return a;
264 }
265 
266 double inline ThreeVector::sqr() const { return (*this) * (*this); }
267 
268 double inline ThreeVector::abs() const { return std::sqrt((*this) * (*this)); }
269 
270 double inline ThreeVector::get_phi() const {
271  if (std::abs(x1()) < really_small && std::abs(x2()) < really_small) {
272  return 0.;
273  } else {
274  return std::atan2(x2(), x1());
275  }
276 }
277 
278 double inline ThreeVector::get_theta() const {
279  double r = abs();
280  return (r > 0.) ? std::acos(x3() / r) : 0.;
281 }
282 
283 void inline ThreeVector::rotate(double phi, double theta, double psi) {
284  // Compute the cosine and sine for each angle.
285  const double cos_phi = std::cos(phi);
286  const double sin_phi = std::sin(phi);
287  const double cos_theta = std::cos(theta);
288  const double sin_theta = std::sin(theta);
289  const double cos_psi = std::cos(psi);
290  const double sin_psi = std::sin(psi);
291  // Get original coordinates.
292  std::array<double, 3> x_old = x_;
293  // Compute new coordinates.
294  x_[0] = (cos_phi * cos_psi - sin_phi * cos_theta * sin_psi) * x_old[0] +
295  (-cos_phi * sin_psi - sin_phi * cos_theta * cos_psi) * x_old[1] +
296  (sin_phi * sin_theta) * x_old[2];
297  x_[1] = (sin_phi * cos_psi + cos_phi * cos_theta * sin_psi) * x_old[0] +
298  (-sin_phi * sin_psi + cos_phi * cos_theta * cos_psi) * x_old[1] +
299  (-cos_phi * sin_theta) * x_old[2];
300  x_[2] = (sin_theta * sin_psi) * x_old[0] + (sin_theta * cos_psi) * x_old[1] +
301  (cos_theta)*x_old[2];
302 }
303 
304 void inline ThreeVector::rotate_around_y(double theta) {
305  const double cost = std::cos(theta);
306  const double sint = std::sin(theta);
307  // Get original coordinates.
308  std::array<double, 3> x_old = x_;
309  // Compute new coordinates.
310  x_[0] = cost * x_old[0] + sint * x_old[2];
311  // x_[1] is unchanged
312  x_[2] = -sint * x_old[0] + cost * x_old[2];
313 }
314 
315 void inline ThreeVector::rotate_around_z(double theta) {
316  const double cost = std::cos(theta);
317  const double sint = std::sin(theta);
318  // Get original coordinates.
319  std::array<double, 3> x_old = x_;
320  // Compute new coordinates.
321  x_[0] = cost * x_old[0] - sint * x_old[1];
322  x_[1] = sint * x_old[0] + cost * x_old[1];
323  // x_[2] is unchanged
324 }
325 
329 }
330 
331 } // namespace smash
332 
333 #endif // SRC_INCLUDE_SMASH_THREEVECTOR_H_
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
std::array< double, 3 > x_
the internal storage of the components.
Definition: threevector.h:168
double get_phi() const
Definition: threevector.h:270
ThreeVector operator-=(const ThreeVector &v)
Decrease this vector by : .
Definition: threevector.h:207
void set_x1(double x)
set first component
Definition: threevector.h:179
ThreeVector(double y1, double y2, double y3)
Constructor for ThreeVector that takes 3 doubles to set up a ThreeVector with desired values for the ...
Definition: threevector.h:44
double abs() const
Definition: threevector.h:268
double sqr() const
Definition: threevector.h:266
std::array< double, 3 >::iterator iterator
iterates over the components
Definition: threevector.h:141
iterator begin()
Definition: threevector.h:151
void rotate_around_y(double theta)
Rotate the vector around the y axis by the given angle theta.
Definition: threevector.h:304
double x3() const
Definition: threevector.h:185
const_iterator begin() const
const overload of the above
Definition: threevector.h:157
bool operator!=(const ThreeVector &rhs) const
Definition: threevector.h:133
const_iterator cbegin() const
Definition: threevector.h:162
void rotate_around_z(double theta)
Rotate the vector around the z axis by the given angle theta.
Definition: threevector.h:315
void set_x3(double z)
set third component
Definition: threevector.h:187
void rotate(double phi, double theta, double psi)
Rotate vector by the given Euler angles phi, theta, psi.
Definition: threevector.h:283
ThreeVector operator*=(const double &a)
Scale this vector by : .
Definition: threevector.h:220
double x2() const
Definition: threevector.h:181
double get_theta() const
Definition: threevector.h:278
void set_x2(double y)
set second component
Definition: threevector.h:183
bool operator==(const ThreeVector &rhs) const
Definition: threevector.h:131
void rotate_z_axis_to(ThreeVector &r)
Rotate the z-axis onto the vector r.
Definition: threevector.h:326
double x1() const
Definition: threevector.h:177
double & operator[](std::size_t i)
access the component at offset i.
Definition: threevector.h:47
ThreeVector operator+=(const ThreeVector &v)
Increase this vector by : .
Definition: threevector.h:194
ThreeVector operator/=(const double &a)
Divide this vector by : .
Definition: threevector.h:252
const_iterator cend() const
Definition: threevector.h:164
ThreeVector cross_product(const ThreeVector &b) const
Definition: threevector.h:246
double operator[](std::size_t i) const
const overload of the above.
Definition: threevector.h:49
ThreeVector()
default constructor (nulls all components)
Definition: threevector.h:34
const_iterator end() const
const overload of the above
Definition: threevector.h:159
ThreeVector operator-() const
Negation: Returns .
Definition: threevector.h:189
std::array< double, 3 >::const_iterator const_iterator
iterates over the components
Definition: threevector.h:143
Collection of useful constants that are known at compile time.
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
Definition: action.h:547
Definition: action.h:24
EnergyMomentumTensor operator-(EnergyMomentumTensor a, const EnergyMomentumTensor &b)
Direct subtraction operator.
EnergyMomentumTensor operator*(EnergyMomentumTensor a, const double b)
Direct multiplication operator.
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
EnergyMomentumTensor operator+(EnergyMomentumTensor a, const EnergyMomentumTensor &b)
Direct addition operator.
EnergyMomentumTensor operator/(EnergyMomentumTensor a, const double b)
Direct division operator.