BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
RotMatrix.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Base/Vector/RotMatrix.cpp
6 //! @brief Implements class RotMatrix.
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 #include "Base/Vector/RotMatrix.h"
16 
17 RotMatrix::RotMatrix(double x_, double y_, double z_, double s_)
18  : x(x_)
19  , y(y_)
20  , z(z_)
21  , s(s_)
22 {
23 }
24 
26  : RotMatrix(0, 0, 0, 1)
27 {
28 }
29 
31 {
32  return {sin(phi / 2), 0, 0, cos(phi / 2)};
33 }
34 
36 {
37  return {0, sin(phi / 2), 0, cos(phi / 2)};
38 }
39 
41 {
42  return {0, 0, sin(phi / 2), cos(phi / 2)};
43 }
44 
45 RotMatrix RotMatrix::EulerZXZ(double alpha, double beta, double gamma)
46 {
47  RotMatrix zrot = AroundZ(alpha);
48  RotMatrix xrot = AroundX(beta);
49  RotMatrix zrot2 = AroundZ(gamma);
50  return zrot * xrot * zrot2;
51 }
52 
53 std::array<double, 3> RotMatrix::zxzEulerAngles() const
54 {
55  double m00 = (-1 + 2 * x * x + 2 * s * s);
56  double m02 = 2 * (x * z + y * s);
57  double m10 = 2 * (y * x + z * s);
58  double m12 = 2 * (y * z - x * s);
59  double m20 = 2 * (z * x - y * s);
60  double m21 = 2 * (z * y + x * s);
61  double m22 = (-1 + 2 * z * z + 2 * s * s);
62 
63  const double beta = std::acos(m22);
64 
65  if (std::abs(m22) == 1.0) // second z angle is zero or pi
66  return {std::atan2(m10, m00), beta, 0.};
67  return {std::atan2(m02, -m12), beta, std::atan2(m20, m21)};
68 }
69 
71 {
72  return {-x, -y, -z, s};
73 }
74 
75 template <class T>
76 T RotMatrix::transformed(const T& v) const
77 {
78  auto xf = (-1 + 2 * x * x + 2 * s * s) * v.x() + 2 * (x * y - z * s) * v.y()
79  + 2 * (x * z + y * s) * v.z();
80  auto yf = (-1 + 2 * y * y + 2 * s * s) * v.y() + 2 * (y * z - x * s) * v.z()
81  + 2 * (y * x + z * s) * v.x();
82  auto zf = (-1 + 2 * z * z + 2 * s * s) * v.z() + 2 * (z * x - y * s) * v.x()
83  + 2 * (z * y + x * s) * v.y();
84 
85  return T(xf, yf, zf);
86 }
87 
88 template R3 RotMatrix::transformed<R3>(const R3& v) const;
89 template C3 RotMatrix::transformed<C3>(const C3& v) const;
90 
91 template <class T>
92 T RotMatrix::counterTransformed(const T& v) const
93 {
94  return Inverse().transformed(v);
95 }
96 
97 template R3 RotMatrix::counterTransformed<R3>(const R3& v) const;
98 template C3 RotMatrix::counterTransformed<C3>(const C3& v) const;
99 
101 {
102  return {s * o.x + x * o.s + y * o.z - z * o.y, s * o.y + y * o.s + z * o.x - x * o.z,
103  s * o.z + z * o.s + x * o.y - y * o.x, s * o.s - x * o.x - y * o.y - z * o.z};
104 }
105 
106 bool RotMatrix::operator==(const RotMatrix& o) const
107 {
108  return x == o.x && y == o.y && z == o.z && s == o.s;
109 }
110 
112 {
113  return x == 0 && y == 0 && z == 0;
114 }
115 
117 {
118  return y == 0 && z == 0;
119 }
120 
122 {
123  return z == 0 && x == 0;
124 }
125 
127 {
128  return x == 0 && y == 0;
129 }
130 
131 std::optional<double> RotMatrix::angleAroundCoordAxis(int iAxis) const
132 {
133  if (iAxis == 0 && isXRotation())
134  return 2 * atan2(x, s);
135  if (iAxis == 1 && isYRotation())
136  return 2 * atan2(y, s);
137  if (iAxis == 2 && isZRotation())
138  return 2 * atan2(z, s);
139  return {};
140 }
Declares class RotMatrix.
Rotation matrix in three dimensions. Represents group SO(3). Internal parameterization based on quate...
Definition: RotMatrix.h:25
double y
Definition: RotMatrix.h:77
T counterTransformed(const T &v) const
Return transformed vector v.
Definition: RotMatrix.cpp:92
RotMatrix()
Constructs unit transformation.
Definition: RotMatrix.cpp:25
static RotMatrix EulerZXZ(double alpha, double beta, double gamma)
Creates rotation defined by Euler angles.
Definition: RotMatrix.cpp:45
static RotMatrix AroundZ(double phi)
Creates rotation around z-axis.
Definition: RotMatrix.cpp:40
static RotMatrix AroundY(double phi)
Creates rotation around y-axis.
Definition: RotMatrix.cpp:35
RotMatrix operator*(const RotMatrix &) const
Composes two transformations.
Definition: RotMatrix.cpp:100
static RotMatrix AroundX(double phi)
Creates rotation around x-axis.
Definition: RotMatrix.cpp:30
bool isIdentity() const
Determine if the transformation is trivial (identity)
Definition: RotMatrix.cpp:111
RotMatrix Inverse() const
Returns the inverse transformation.
Definition: RotMatrix.cpp:70
bool isZRotation() const
Definition: RotMatrix.cpp:126
std::optional< double > angleAroundCoordAxis(int iAxis) const
Definition: RotMatrix.cpp:131
bool isXRotation() const
Definition: RotMatrix.cpp:116
double x
Definition: RotMatrix.h:77
double s
Definition: RotMatrix.h:77
double z
Definition: RotMatrix.h:77
std::array< double, 3 > zxzEulerAngles() const
Calculates the Euler angles corresponding to the rotation.
Definition: RotMatrix.cpp:53
T transformed(const T &v) const
Return transformed vector v.
Definition: RotMatrix.cpp:76
bool operator==(const RotMatrix &) const
Provides equality operator.
Definition: RotMatrix.cpp:106
bool isYRotation() const
Definition: RotMatrix.cpp:121
double beta(double z, double w)
double gamma(double x)