BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
Transform3D.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Base/Vector/Transform3D.cpp
6 //! @brief Implements template class Transform3D.
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 
16 #include <Eigen/LU>
17 
19 {
20  m_matrix.setIdentity();
21  m_inverse_matrix.setIdentity();
22 }
23 
24 Transform3D::Transform3D(const Eigen::Matrix3d& matrix) : m_matrix(matrix)
25 {
26  m_inverse_matrix = m_matrix.inverse();
27 }
28 
30 {
31  double cosine = std::cos(phi);
32  double sine = std::sin(phi);
33  Eigen::Matrix3d matrix;
34  matrix.setIdentity();
35  matrix(1, 1) = cosine;
36  matrix(1, 2) = -sine;
37  matrix(2, 1) = sine;
38  matrix(2, 2) = cosine;
39  return Transform3D(matrix);
40 }
41 
43 {
44  double cosine = std::cos(phi);
45  double sine = std::sin(phi);
46  Eigen::Matrix3d matrix;
47  matrix.setIdentity();
48  matrix(0, 0) = cosine;
49  matrix(0, 2) = sine;
50  matrix(2, 0) = -sine;
51  matrix(2, 2) = cosine;
52  return Transform3D(matrix);
53 }
54 
56 {
57  double cosine = std::cos(phi);
58  double sine = std::sin(phi);
59  Eigen::Matrix3d matrix;
60  matrix.setIdentity();
61  matrix(0, 0) = cosine;
62  matrix(0, 1) = -sine;
63  matrix(1, 0) = sine;
64  matrix(1, 1) = cosine;
65  return Transform3D(matrix);
66 }
67 
68 Transform3D Transform3D::createRotateEuler(double alpha, double beta, double gamma)
69 {
70  Transform3D zrot = createRotateZ(alpha);
71  Transform3D xrot = createRotateX(beta);
72  Transform3D zrot2 = createRotateZ(gamma);
73  return zrot * xrot * zrot2;
74 }
75 
76 void Transform3D::calculateEulerAngles(double* p_alpha, double* p_beta, double* p_gamma) const
77 {
78  *p_beta = std::acos(m_matrix(2, 2));
79  // First check if second angle is zero or pi
80  if (std::abs(m_matrix(2, 2)) == 1.0) {
81  *p_alpha = std::atan2(m_matrix(1, 0), m_matrix(0, 0));
82  *p_gamma = 0.0;
83  } else {
84  *p_alpha = std::atan2(m_matrix(0, 2), -m_matrix(1, 2));
85  *p_gamma = std::atan2(m_matrix(2, 0), m_matrix(2, 1));
86  }
87 }
88 
90 {
91  return std::atan2(m_matrix(2, 1), m_matrix(1, 1));
92 }
93 
95 {
96  return std::atan2(m_matrix(0, 2), m_matrix(2, 2));
97 }
98 
100 {
101  return std::atan2(m_matrix(1, 0), m_matrix(0, 0));
102 }
103 
105 {
107  return result;
108 }
109 
110 template <class ivector_t> ivector_t Transform3D::transformed(const ivector_t& v) const
111 {
112  auto x = m_matrix(0, 0) * v.x() + m_matrix(0, 1) * v.y() + m_matrix(0, 2) * v.z();
113  auto y = m_matrix(1, 0) * v.x() + m_matrix(1, 1) * v.y() + m_matrix(1, 2) * v.z();
114  auto z = m_matrix(2, 0) * v.x() + m_matrix(2, 1) * v.y() + m_matrix(2, 2) * v.z();
115  return ivector_t(x, y, z);
116 }
117 
118 template kvector_t Transform3D::transformed<kvector_t>(const kvector_t& v) const;
119 template cvector_t Transform3D::transformed<cvector_t>(const cvector_t& v) const;
120 
121 template <class ivector_t> ivector_t Transform3D::transformedInverse(const ivector_t& v) const
122 {
123  auto x = m_inverse_matrix(0, 0) * v.x() + m_inverse_matrix(0, 1) * v.y()
124  + m_inverse_matrix(0, 2) * v.z();
125  auto y = m_inverse_matrix(1, 0) * v.x() + m_inverse_matrix(1, 1) * v.y()
126  + m_inverse_matrix(1, 2) * v.z();
127  auto z = m_inverse_matrix(2, 0) * v.x() + m_inverse_matrix(2, 1) * v.y()
128  + m_inverse_matrix(2, 2) * v.z();
129  return ivector_t(x, y, z);
130 }
131 
132 template kvector_t Transform3D::transformedInverse<kvector_t>(const kvector_t& v) const;
133 template cvector_t Transform3D::transformedInverse<cvector_t>(const cvector_t& v) const;
134 
136 {
137  return new Transform3D(m_matrix);
138 }
139 
141 {
142  Eigen::Matrix3d product_matrix = this->m_matrix * other.m_matrix;
143  return Transform3D(product_matrix);
144 }
145 
146 bool Transform3D::operator==(const Transform3D& other) const
147 {
148  return this->m_matrix == other.m_matrix;
149 }
150 
152 {
153  if (isXRotation())
154  return XAXIS;
155  if (isYRotation())
156  return YAXIS;
157  if (isZRotation())
158  return ZAXIS;
159  return EULER;
160 }
161 
163 {
164  double alpha, beta, gamma;
165  calculateEulerAngles(&alpha, &beta, &gamma);
166  return (alpha == 0.0 && beta == 0.0 && gamma == 0.0);
167 }
168 
169 void Transform3D::print(std::ostream& ostr) const
170 {
171  ostr << "Transform3D: " << m_matrix;
172 }
173 
175 {
176  if (m_matrix(0, 0) != 1.0)
177  return false;
178  if (m_matrix(0, 1) != 0.0)
179  return false;
180  if (m_matrix(0, 2) != 0.0)
181  return false;
182  if (m_matrix(1, 0) != 0.0)
183  return false;
184  if (m_matrix(2, 0) != 0.0)
185  return false;
186  return true;
187 }
188 
190 {
191  if (m_matrix(1, 1) != 1.0)
192  return false;
193  if (m_matrix(0, 1) != 0.0)
194  return false;
195  if (m_matrix(1, 0) != 0.0)
196  return false;
197  if (m_matrix(1, 2) != 0.0)
198  return false;
199  if (m_matrix(2, 1) != 0.0)
200  return false;
201  return true;
202 }
203 
205 {
206  if (m_matrix(2, 2) != 1.0)
207  return false;
208  if (m_matrix(0, 2) != 0.0)
209  return false;
210  if (m_matrix(1, 2) != 0.0)
211  return false;
212  if (m_matrix(2, 0) != 0.0)
213  return false;
214  if (m_matrix(2, 1) != 0.0)
215  return false;
216  return true;
217 }
Declares class Transform3D.
BasicVector3D< int > ivector_t
Definition: Vectors3D.h:20
Three-dimensional vector template, for use with integer, double, or complex components.
Definition: BasicVector3D.h:27
T z() const
Returns z-component in cartesian coordinate system.
Definition: BasicVector3D.h:67
T y() const
Returns y-component in cartesian coordinate system.
Definition: BasicVector3D.h:65
T x() const
Returns x-component in cartesian coordinate system.
Definition: BasicVector3D.h:63
Vector transformations in three dimensions.
Definition: Transform3D.h:26
static Transform3D createRotateX(double phi)
Creates rotation around x-axis.
Definition: Transform3D.cpp:29
bool isIdentity() const
Determine if the transformation is trivial (identity)
bool isYRotation() const
Transform3D()
Constructs unit transformation.
Definition: Transform3D.cpp:18
bool isXRotation() const
double calculateRotateYAngle() const
Calculates the rotation angle for a rotation around the y-axis alone Only meaningfull if the actual r...
Definition: Transform3D.cpp:94
ivector_t transformed(const ivector_t &v) const
Return transformed vector v.
void calculateEulerAngles(double *p_alpha, double *p_beta, double *p_gamma) const
Calculates the Euler angles corresponding to the rotation.
Definition: Transform3D.cpp:76
static Transform3D createRotateEuler(double alpha, double beta, double gamma)
Creates rotation defined by Euler angles.
Definition: Transform3D.cpp:68
bool operator==(const Transform3D &other) const
Provides equality operator.
Transform3D * clone() const
Clones the transformation.
Transform3D getInverse() const
Returns the inverse transformation.
void print(std::ostream &ostr) const
Eigen::Matrix3d m_inverse_matrix
Definition: Transform3D.h:107
bool isZRotation() const
ERotationType getRotationType() const
Retrieve the rotation type (general, around x, y or z-axis)
ivector_t transformedInverse(const ivector_t &v) const
Return transformed vector v.
Eigen::Matrix3d m_matrix
Definition: Transform3D.h:106
double calculateRotateXAngle() const
Calculates the rotation angle for a rotation around the x-axis alone Only meaningfull if the actual r...
Definition: Transform3D.cpp:89
Transform3D operator*(const Transform3D &other) const
Composes two transformations.
static Transform3D createRotateZ(double phi)
Creates rotation around z-axis.
Definition: Transform3D.cpp:55
double calculateRotateZAngle() const
Calculates the rotation angle for a rotation around the z-axis alone Only meaningfull if the actual r...
Definition: Transform3D.cpp:99
static Transform3D createRotateY(double phi)
Creates rotation around y-axis.
Definition: Transform3D.cpp:42