BornAgain  1.18.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 scattering at grazing incidence
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  return Transform3D();
32 }
33 
35 {
36  double cosine = std::cos(phi);
37  double sine = std::sin(phi);
38  Eigen::Matrix3d matrix;
39  matrix.setIdentity();
40  matrix(1, 1) = cosine;
41  matrix(1, 2) = -sine;
42  matrix(2, 1) = sine;
43  matrix(2, 2) = cosine;
44  return Transform3D(matrix);
45 }
46 
48 {
49  double cosine = std::cos(phi);
50  double sine = std::sin(phi);
51  Eigen::Matrix3d matrix;
52  matrix.setIdentity();
53  matrix(0, 0) = cosine;
54  matrix(0, 2) = sine;
55  matrix(2, 0) = -sine;
56  matrix(2, 2) = cosine;
57  return Transform3D(matrix);
58 }
59 
61 {
62  double cosine = std::cos(phi);
63  double sine = std::sin(phi);
64  Eigen::Matrix3d matrix;
65  matrix.setIdentity();
66  matrix(0, 0) = cosine;
67  matrix(0, 1) = -sine;
68  matrix(1, 0) = sine;
69  matrix(1, 1) = cosine;
70  return Transform3D(matrix);
71 }
72 
73 Transform3D Transform3D::createRotateEuler(double alpha, double beta, double gamma)
74 {
75  Transform3D zrot = createRotateZ(alpha);
76  Transform3D xrot = createRotateX(beta);
77  Transform3D zrot2 = createRotateZ(gamma);
78  return zrot * xrot * zrot2;
79 }
80 
81 void Transform3D::calculateEulerAngles(double* p_alpha, double* p_beta, double* p_gamma) const
82 {
83  *p_beta = std::acos(m_matrix(2, 2));
84  // First check if second angle is zero or pi
85  if (std::abs(m_matrix(2, 2)) == 1.0) {
86  *p_alpha = std::atan2(m_matrix(1, 0), m_matrix(0, 0));
87  *p_gamma = 0.0;
88  } else {
89  *p_alpha = std::atan2(m_matrix(0, 2), -m_matrix(1, 2));
90  *p_gamma = std::atan2(m_matrix(2, 0), m_matrix(2, 1));
91  }
92 }
93 
95 {
96  return std::atan2(m_matrix(2, 1), m_matrix(1, 1));
97 }
98 
100 {
101  return std::atan2(m_matrix(0, 2), m_matrix(2, 2));
102 }
103 
105 {
106  return std::atan2(m_matrix(1, 0), m_matrix(0, 0));
107 }
108 
110 {
112  return result;
113 }
114 
115 template <class ivector_t> ivector_t Transform3D::transformed(const ivector_t& v) const
116 {
117  auto x = m_matrix(0, 0) * v.x() + m_matrix(0, 1) * v.y() + m_matrix(0, 2) * v.z();
118  auto y = m_matrix(1, 0) * v.x() + m_matrix(1, 1) * v.y() + m_matrix(1, 2) * v.z();
119  auto z = m_matrix(2, 0) * v.x() + m_matrix(2, 1) * v.y() + m_matrix(2, 2) * v.z();
120  return ivector_t(x, y, z);
121 }
122 
123 template kvector_t Transform3D::transformed<kvector_t>(const kvector_t& v) const;
124 template cvector_t Transform3D::transformed<cvector_t>(const cvector_t& v) const;
125 
126 template <class ivector_t> ivector_t Transform3D::transformedInverse(const ivector_t& v) const
127 {
128  auto x = m_inverse_matrix(0, 0) * v.x() + m_inverse_matrix(0, 1) * v.y()
129  + m_inverse_matrix(0, 2) * v.z();
130  auto y = m_inverse_matrix(1, 0) * v.x() + m_inverse_matrix(1, 1) * v.y()
131  + m_inverse_matrix(1, 2) * v.z();
132  auto z = m_inverse_matrix(2, 0) * v.x() + m_inverse_matrix(2, 1) * v.y()
133  + m_inverse_matrix(2, 2) * v.z();
134  return ivector_t(x, y, z);
135 }
136 
137 template kvector_t Transform3D::transformedInverse<kvector_t>(const kvector_t& v) const;
138 template cvector_t Transform3D::transformedInverse<cvector_t>(const cvector_t& v) const;
139 
141 {
142  return new Transform3D(m_matrix);
143 }
144 
146 {
147  Eigen::Matrix3d product_matrix = this->m_matrix * other.m_matrix;
148  return Transform3D(product_matrix);
149 }
150 
151 bool Transform3D::operator==(const Transform3D& other) const
152 {
153  return this->m_matrix == other.m_matrix;
154 }
155 
157 {
158  if (isXRotation())
159  return XAXIS;
160  if (isYRotation())
161  return YAXIS;
162  if (isZRotation())
163  return ZAXIS;
164  return EULER;
165 }
166 
168 {
169  double alpha, beta, gamma;
170  calculateEulerAngles(&alpha, &beta, &gamma);
171  return (alpha == 0.0 && beta == 0.0 && gamma == 0.0);
172 }
173 
174 void Transform3D::print(std::ostream& ostr) const
175 {
176  ostr << "Transform3D: " << m_matrix;
177 }
178 
180 {
181  if (m_matrix(0, 0) != 1.0)
182  return false;
183  if (m_matrix(0, 1) != 0.0)
184  return false;
185  if (m_matrix(0, 2) != 0.0)
186  return false;
187  if (m_matrix(1, 0) != 0.0)
188  return false;
189  if (m_matrix(2, 0) != 0.0)
190  return false;
191  return true;
192 }
193 
195 {
196  if (m_matrix(1, 1) != 1.0)
197  return false;
198  if (m_matrix(0, 1) != 0.0)
199  return false;
200  if (m_matrix(1, 0) != 0.0)
201  return false;
202  if (m_matrix(1, 2) != 0.0)
203  return false;
204  if (m_matrix(2, 1) != 0.0)
205  return false;
206  return true;
207 }
208 
210 {
211  if (m_matrix(2, 2) != 1.0)
212  return false;
213  if (m_matrix(0, 2) != 0.0)
214  return false;
215  if (m_matrix(1, 2) != 0.0)
216  return false;
217  if (m_matrix(2, 0) != 0.0)
218  return false;
219  if (m_matrix(2, 1) != 0.0)
220  return false;
221  return true;
222 }
Declares class Transform3D.
BasicVector3D< int > ivector_t
Definition: Vectors3D.h:20
Forked from CLHEP/Geometry by E.
Definition: BasicVector3D.h:28
T z() const
Returns z-component in cartesian coordinate system.
Definition: BasicVector3D.h:68
T y() const
Returns y-component in cartesian coordinate system.
Definition: BasicVector3D.h:66
T x() const
Returns x-component in cartesian coordinate system.
Definition: BasicVector3D.h:64
Vector transformations in three dimensions.
Definition: Transform3D.h:28
static Transform3D createRotateX(double phi)
Creates rotation around x-axis.
Definition: Transform3D.cpp:34
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:99
static Transform3D createIdentity()
Creates identity transformation (default)
Definition: Transform3D.cpp:29
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:81
static Transform3D createRotateEuler(double alpha, double beta, double gamma)
Creates rotation defined by Euler angles.
Definition: Transform3D.cpp:73
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:112
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:111
double calculateRotateXAngle() const
Calculates the rotation angle for a rotation around the x-axis alone Only meaningfull if the actual r...
Definition: Transform3D.cpp:94
Transform3D operator*(const Transform3D &other) const
Composes two transformations.
static Transform3D createRotateZ(double phi)
Creates rotation around z-axis.
Definition: Transform3D.cpp:60
double calculateRotateZAngle() const
Calculates the rotation angle for a rotation around the z-axis alone Only meaningfull if the actual r...
static Transform3D createRotateY(double phi)
Creates rotation around y-axis.
Definition: Transform3D.cpp:47