BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
BasicVector3D.h
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Base/Vector/BasicVector3D.h
6 //! @brief Declares and partly implements template class BasicVector3D.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //!
13 //! Forked from CLHEP/Geometry by E. Chernyaev <Evgueni.Tcherniaev@cern.ch>,
14 //! then reworked beyond recognition. Removed split of point and vector semantics.
15 //! Transforms are relegated to a separate class Transform3D.
16 //
17 // ************************************************************************************************
18 
19 #ifndef BORNAGAIN_BASE_VECTOR_BASICVECTOR3D_H
20 #define BORNAGAIN_BASE_VECTOR_BASICVECTOR3D_H
21 
22 #include "Base/Types/Complex.h"
23 
24 //! Three-dimensional vector template, for use with integer, double, or complex components.
25 //! @ingroup tools_internal
26 
27 template <class T> class BasicVector3D {
28 private:
29  T v_[3];
30 
31 public:
32  // -------------------------------------------------------------------------
33  // Constructors and other set functions
34  // -------------------------------------------------------------------------
35 
36  //! Constructs the null vector.
38  {
39  v_[0] = 0.0;
40  v_[1] = 0.0;
41  v_[2] = 0.0;
42  }
43 
44  //! Constructs a vector from cartesian components.
45  BasicVector3D(const T x1, const T y1, const T z1)
46  {
47  v_[0] = x1;
48  v_[1] = y1;
49  v_[2] = z1;
50  }
51 
52  // -------------------------------------------------------------------------
53  // Component access
54  // -------------------------------------------------------------------------
55 
56  //! Returns components by index.
57  T operator[](int i) const { return v_[i]; }
58 
59  //! Sets components by index.
60  T& operator[](int i) { return v_[i]; }
61 
62  //! Returns x-component in cartesian coordinate system.
63  T x() const { return v_[0]; }
64  //! Returns y-component in cartesian coordinate system.
65  T y() const { return v_[1]; }
66  //! Returns z-component in cartesian coordinate system.
67  T z() const { return v_[2]; }
68 
69  //! Sets x-component in cartesian coordinate system.
70  void setX(const T& a) { v_[0] = a; }
71  //! Sets y-component in cartesian coordinate system.
72  void setY(const T& a) { v_[1] = a; }
73  //! Sets z-component in cartesian coordinate system.
74  void setZ(const T& a) { v_[2] = a; }
75 
76  // -------------------------------------------------------------------------
77  // In-place operations
78  // -------------------------------------------------------------------------
79 
80  //! Adds other vector to this, and returns result.
82  {
83  v_[0] += v.v_[0];
84  v_[1] += v.v_[1];
85  v_[2] += v.v_[2];
86  return *this;
87  }
88 
89  //! Subtracts other vector from this, and returns result.
91  {
92  v_[0] -= v.v_[0];
93  v_[1] -= v.v_[1];
94  v_[2] -= v.v_[2];
95  return *this;
96  }
97 
98  //! Multiplies this with a scalar, and returns result.
99 #ifndef SWIG
100  template <class U> auto operator*=(U a)
101  {
102  v_[0] *= a;
103  v_[1] *= a;
104  v_[2] *= a;
105  return *this;
106  }
107 #endif // USER_API
108 
109  //! Divides this by a scalar, and returns result.
110 #ifndef SWIG
111  template <class U> auto operator/=(U a)
112  {
113  v_[0] /= a;
114  v_[1] /= a;
115  v_[2] /= a;
116  return *this;
117  }
118 #endif // USER_API
119 
120  // -------------------------------------------------------------------------
121  // Functions of this (with no further argument)
122  // -------------------------------------------------------------------------
123 
124  //! Returns complex conjugate vector
126 
127  //! Returns magnitude squared of the vector.
128  double mag2() const { return std::norm(v_[0]) + std::norm(v_[1]) + std::norm(v_[2]); }
129 
130  //! Returns magnitude of the vector.
131  double mag() const { return sqrt(mag2()); }
132 
133  //! Returns squared distance from z axis.
134  double magxy2() const { return std::norm(v_[0]) + std::norm(v_[1]); }
135 
136  //! Returns distance from z axis.
137  double magxy() const { return sqrt(magxy2()); }
138 
139  //! Returns azimuth angle.
140  double phi() const;
141 
142  //! Returns polar angle.
143  double theta() const;
144 
145  //! Returns cosine of polar angle.
146  double cosTheta() const;
147 
148  //! Returns squared sine of polar angle.
149  double sin2Theta() const;
150 
151  //! Returns unit vector in direction of this. Throws for null vector.
153 
154  //! Returns this, trivially converted to complex type.
156 
157  //! Returns real parts.
159 
160  // -------------------------------------------------------------------------
161  // Functions of this and another vector
162  // -------------------------------------------------------------------------
163 
164  //! Returns dot product of vectors (antilinear in the first [=self] argument).
165 #ifndef SWIG
166  template <class U> auto dot(const BasicVector3D<U>& v) const;
167 #endif // USER_API
168 
169  //! Returns cross product of vectors (linear in both arguments).
170 #ifndef SWIG
171  template <class U> auto cross(const BasicVector3D<U>& v) const;
172 #endif // USER_API
173 
174  //! Returns angle with respect to another vector.
175  double angle(const BasicVector3D<T>& v) const;
176 
177  //! Returns projection of this onto other vector: (this*v)*v/|v|^2.
179  {
180  return dot(v) * v / v.mag2();
181  }
182 
183  // -------------------------------------------------------------------------
184  // Rotations
185  // -------------------------------------------------------------------------
186 
187  //! Returns result of rotation around x-axis.
188  BasicVector3D<T> rotatedX(double a) const;
189  //! Returns result of rotation around y-axis.
190  BasicVector3D<T> rotatedY(double a) const;
191  //! Returns result of rotation around z-axis.
192  BasicVector3D<T> rotatedZ(double a) const
193  {
194  return BasicVector3D<T>(cos(a) * x() + sin(a) * y(), -sin(a) * x() + cos(a) * y(), z());
195  }
196  //! Returns result of rotation around the axis specified by another vector.
197  BasicVector3D<T> rotated(double a, const BasicVector3D<T>& v) const;
198 };
199 
200 // =============================================================================
201 // Non-member functions
202 // =============================================================================
203 
204 //! Output to stream.
205 //! @relates BasicVector3D
206 template <class T> std::ostream& operator<<(std::ostream& os, const BasicVector3D<T>& a)
207 {
208  return os << "(" << a.x() << "," << a.y() << "," << a.z() << ")";
209 }
210 
211 // -----------------------------------------------------------------------------
212 // Unary operators
213 // -----------------------------------------------------------------------------
214 
215 //! Unary plus.
216 //! @relates BasicVector3D
217 template <class T> inline BasicVector3D<T> operator+(const BasicVector3D<T>& v)
218 {
219  return v;
220 }
221 
222 //! Unary minus.
223 //! @relates BasicVector3D
224 template <class T> inline BasicVector3D<T> operator-(const BasicVector3D<T>& v)
225 {
226  return BasicVector3D<T>(-v.x(), -v.y(), -v.z());
227 }
228 
229 // -----------------------------------------------------------------------------
230 // Binary operators
231 // -----------------------------------------------------------------------------
232 
233 //! Addition of two vectors.
234 //! @relates BasicVector3D
235 template <class T>
237 {
238  return BasicVector3D<T>(a.x() + b.x(), a.y() + b.y(), a.z() + b.z());
239 }
240 
241 //! Subtraction of two vectors.
242 //! @relates BasicVector3D
243 template <class T>
245 {
246  return BasicVector3D<T>(a.x() - b.x(), a.y() - b.y(), a.z() - b.z());
247 }
248 
249 //! Multiplication vector by scalar.
250 //! @relates BasicVector3D
251 #ifndef SWIG
252 template <class T, class U> inline auto operator*(const BasicVector3D<T>& v, const U a)
253 {
254  return BasicVector3D<decltype(v.x() * a)>(v.x() * a, v.y() * a, v.z() * a);
255 }
256 #endif // USER_API
257 
258 //! Multiplication scalar by vector.
259 //! @relates BasicVector3D
260 #ifndef SWIG
261 template <class T, class U> inline auto operator*(const U a, const BasicVector3D<T>& v)
262 {
263  return BasicVector3D<decltype(a * v.x())>(a * v.x(), a * v.y(), a * v.z());
264 }
265 #endif // USER_API
266 
267 // vector*vector not supported
268 // (We do not provide the operator form a*b of the dot product:
269 // Though nice to write, and in some cases perfectly justified,
270 // in general it tends to make expressions more difficult to read.)
271 
272 //! Division vector by scalar.
273 //! @relates BasicVector3D
274 template <class T, class U> inline BasicVector3D<T> operator/(const BasicVector3D<T>& v, U a)
275 {
276  return BasicVector3D<T>(v.x() / a, v.y() / a, v.z() / a);
277 }
278 
279 //! Comparison of two vectors for equality.
280 //! @relates BasicVector3D
281 template <class T> inline bool operator==(const BasicVector3D<T>& a, const BasicVector3D<T>& b)
282 {
283  return (a.x() == b.x() && a.y() == b.y() && a.z() == b.z());
284 }
285 
286 //! Comparison of two vectors for inequality.
287 //! @relates BasicVector3D
288 template <class T> inline bool operator!=(const BasicVector3D<T>& a, const BasicVector3D<T>& b)
289 {
290  return (a.x() != b.x() || a.y() != b.y() || a.z() != b.z());
291 }
292 
293 // =============================================================================
294 // ?? for API generation ??
295 // =============================================================================
296 
297 //! Returns dot product of (complex) vectors (antilinear in the first [=self] argument).
298 #ifndef SWIG
299 template <class T>
300 template <class U>
301 inline auto BasicVector3D<T>::dot(const BasicVector3D<U>& v) const
302 {
303  BasicVector3D<T> left_star = this->conj();
304  return left_star.x() * v.x() + left_star.y() * v.y() + left_star.z() * v.z();
305 }
306 #endif // USER_API
307 
308 //! Returns cross product of (complex) vectors.
309 #ifndef SWIG
310 template <class T>
311 template <class U>
312 inline auto BasicVector3D<T>::cross(const BasicVector3D<U>& v) const
313 {
314  return BasicVector3D<decltype(this->x() * v.x())>(
315  y() * v.z() - v.y() * z(), z() * v.x() - v.z() * x(), x() * v.y() - v.x() * y());
316 }
317 #endif // USER_API
318 
320 
322 
323 template <> double BasicVector3D<double>::phi() const;
324 
325 template <> double BasicVector3D<double>::theta() const;
326 
327 template <> double BasicVector3D<double>::cosTheta() const;
328 
329 template <> double BasicVector3D<double>::sin2Theta() const;
330 
332 
334 
336 
338 
340 
341 template <> double BasicVector3D<double>::angle(const BasicVector3D<double>& v) const;
342 
343 #endif // BORNAGAIN_BASE_VECTOR_BASICVECTOR3D_H
Defines complex_t, and a few elementary functions.
Three-dimensional vector template, for use with integer, double, or complex components.
Definition: BasicVector3D.h:27
auto operator*=(U a)
Multiplies this with a scalar, and returns result.
double mag2() const
Returns magnitude squared of the vector.
bool operator!=(const BasicVector3D< T > &a, const BasicVector3D< T > &b)
Comparison of two vectors for inequality.
BasicVector3D< T > conj() const
Returns complex conjugate vector.
BasicVector3D(const T x1, const T y1, const T z1)
Constructs a vector from cartesian components.
Definition: BasicVector3D.h:45
auto dot(const BasicVector3D< U > &v) const
Returns dot product of vectors (antilinear in the first [=self] argument).
double sin2Theta() const
Returns squared sine of polar angle.
BasicVector3D< T > rotated(double a, const BasicVector3D< T > &v) const
Returns result of rotation around the axis specified by another vector.
BasicVector3D< T > rotatedY(double a) const
Returns result of rotation around y-axis.
BasicVector3D< T > project(const BasicVector3D< T > &v) const
Returns projection of this onto other vector: (this*v)*v/|v|^2.
BasicVector3D< T > unit() const
Returns unit vector in direction of this. Throws for null vector.
double magxy2() const
Returns squared distance from z axis.
BasicVector3D< T > operator+(const BasicVector3D< T > &v)
Unary plus.
auto operator*(const BasicVector3D< T > &v, const U a)
Multiplication vector by scalar.
double mag() const
Returns magnitude of the vector.
double theta() const
Returns polar angle.
BasicVector3D< complex_t > complex() const
Returns this, trivially converted to complex type.
BasicVector3D()
Constructs the null vector.
Definition: BasicVector3D.h:37
BasicVector3D< double > real() const
Returns real parts.
void setX(const T &a)
Sets x-component in cartesian coordinate system.
Definition: BasicVector3D.h:70
auto operator*(const U a, const BasicVector3D< T > &v)
Multiplication scalar by vector.
BasicVector3D< T > rotatedZ(double a) const
Returns result of rotation around z-axis.
T z() const
Returns z-component in cartesian coordinate system.
Definition: BasicVector3D.h:67
BasicVector3D< T > & operator+=(const BasicVector3D< T > &v)
Adds other vector to this, and returns result.
Definition: BasicVector3D.h:81
BasicVector3D< T > operator/(const BasicVector3D< T > &v, U a)
Division vector by scalar.
void setY(const T &a)
Sets y-component in cartesian coordinate system.
Definition: BasicVector3D.h:72
BasicVector3D< T > rotatedX(double a) const
Returns result of rotation around x-axis.
BasicVector3D< T > & operator-=(const BasicVector3D< T > &v)
Subtracts other vector from this, and returns result.
Definition: BasicVector3D.h:90
T operator[](int i) const
Returns components by index.
Definition: BasicVector3D.h:57
T & operator[](int i)
Sets components by index.
Definition: BasicVector3D.h:60
T y() const
Returns y-component in cartesian coordinate system.
Definition: BasicVector3D.h:65
BasicVector3D< T > operator-(const BasicVector3D< T > &a, const BasicVector3D< T > &b)
Subtraction of two vectors.
bool operator==(const BasicVector3D< T > &a, const BasicVector3D< T > &b)
Comparison of two vectors for equality.
auto operator/=(U a)
Divides this by a scalar, and returns result.
double phi() const
Returns azimuth angle.
std::ostream & operator<<(std::ostream &os, const BasicVector3D< T > &a)
Output to stream.
T x() const
Returns x-component in cartesian coordinate system.
Definition: BasicVector3D.h:63
void setZ(const T &a)
Sets z-component in cartesian coordinate system.
Definition: BasicVector3D.h:74
double magxy() const
Returns distance from z axis.
double angle(const BasicVector3D< T > &v) const
Returns angle with respect to another vector.
auto cross(const BasicVector3D< U > &v) const
Returns cross product of vectors (linear in both arguments).
BasicVector3D< T > operator+(const BasicVector3D< T > &a, const BasicVector3D< T > &b)
Addition of two vectors.
double cosTheta() const
Returns cosine of polar angle.
BasicVector3D< T > operator-(const BasicVector3D< T > &v)
Unary minus.