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