IMP logo
IMP Reference Guide  2.17.0
The Integrative Modeling Platform
Transformation3D.h
Go to the documentation of this file.
1 /**
2  * \file IMP/algebra/Transformation3D.h
3  * \brief Simple 3D transformation class.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPALGEBRA_TRANSFORMATION_3D_H
10 #define IMPALGEBRA_TRANSFORMATION_3D_H
11 
12 #include <IMP/algebra/algebra_config.h>
13 #include "Vector3D.h"
14 #include "Line3D.h"
15 #include "Rotation3D.h"
16 #include "BoundingBoxD.h"
17 #include "GeometricPrimitiveD.h"
18 
19 IMPALGEBRA_BEGIN_NAMESPACE
20 
21 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
22 class Transformation3D;
23 Transformation3D compose(const Transformation3D &a, const Transformation3D &b);
24 #endif
25 
26 typedef std::pair<Vector4D, Vector3D> Transformation3DAdjoint;
27 typedef std::pair<Vector3D, Transformation3DAdjoint> TransformedVector3DAdjoint;
28 typedef std::pair<Transformation3DAdjoint, Transformation3DAdjoint>
29  ComposeTransformation3DAdjoint;
30 
31 //! Simple 3D transformation class
32 /** The rotation is applied first, and then the point is translated.
33  \see IMP::core::Transform
34  \geometry
35 */
36 class IMPALGEBRAEXPORT Transformation3D : public GeometricPrimitiveD<3> {
37  public:
38  IMP_CXX11_DEFAULT_COPY_CONSTRUCTOR(Transformation3D);
39  //! Default construct (makes an invalid transformation)
41  //! Basic constructor
42  Transformation3D(const Rotation3D &r, const Vector3D &t = Vector3D(0, 0, 0))
43  : trans_(t), rot_(r) {}
44  //! Construct a transformation with an identity rotation.
46  : trans_(t), rot_(get_identity_rotation_3d()) {}
48  //! Transform
49  Vector3D get_transformed(const Vector3D &o) const {
50  return rot_.get_rotated(o) + trans_;
51  }
52 
53 #ifndef SWIG
54  //! Get adjoint of inputs to `get_transformed` from adjoint of output
55  /** Compute the adjoint (reverse-mode sensitivity) of input vector
56  to `get_transformed` and this transformation from the adjoint of the
57  output vector.
58  */
59  void get_transformed_adjoint(const Vector3D &v, const Vector3D &Dw,
60  Vector3D *Dv, Transformation3DAdjoint *DT) const;
61 #endif
62 
63  //! Get adjoint of inputs to `get_transformed` from adjoint of output
64  /** Compute the adjoint (reverse-mode sensitivity) of input vector
65  to `get_transformed` and this transformation from the adjoint of the
66  output vector.
67  */
68  TransformedVector3DAdjoint
69  get_transformed_adjoint(const Vector3D &v, const Vector3D &Dw) const;
70 
71  //! Apply transformation (rotate and then translate)
72  Vector3D operator*(const Vector3D &v) const { return get_transformed(v); }
73  /** Compose two rigid transformation such that for any vector v
74  (rt1*rt2)*v = rt1*(rt2*v) */
76  return compose(*this, tr);
77  }
78  const Transformation3D &operator*=(const Transformation3D &o) {
79  *this = compose(*this, o);
80  return *this;
81  }
82  //! Compute the transformation which, when composed with b, gives *this.
83  /** That is a(x)== d(b(x)) for all x.
84 
85  For consistency, this should probably have a nice name, but
86  I don't know what name to give it.
87  */
89  Transformation3D ret = compose(*this, b.get_inverse());
90  return ret;
91  }
92  const Transformation3D &operator/=(const Transformation3D &o) {
93  *this = *this / o;
94  return *this;
95  }
96 
97  //! Return the rotation associated with this transformation
98  const Rotation3D &get_rotation() const { return rot_; }
99 
100  //! Return the translation vector associated with this transformation
101  const Vector3D &get_translation() const { return trans_; }
102 
104  rot_.show(out);
105  out << " || " << trans_;
106  });
107  Transformation3D get_inverse() const;
108 
109  /** @return true if the 3D transformation is valid; false if the
110  transformation was initialized only with the empty constructor,
111  or it was initialized with an invalid rotation.
112  */
113  bool get_is_valid() const {
114  return rot_.get_is_valid();
115  }
116 
117  private:
118  Vector3D trans_; // translation
119  Rotation3D rot_; // rotation
120 };
121 
123 
124 //! Return a transformation that does not do anything
125 /** \see Transformation3D */
127  return Transformation3D(get_identity_rotation_3d(), Vector3D(0.0, 0.0, 0.0));
128 }
129 
130 //! Generate a Transformation3D object from a rotation around a point
131 /** Rotate about a point rather than the origin.
132  \param[in] point Center to rotate about
133  \param[in] rotation The rotation to perform
134 
135  \see Transformation3D
136 */
138  const Rotation3D &rotation) {
139  return Transformation3D(rotation, (rotation * (-point) + point));
140 }
141 
142 //! Compose two transformations
143 /** For any vector v (a*b)*v = a*(b*v).
144  \see Transformation3D
145  */
147  const Transformation3D &b) {
149  "composing an invalid transformation");
152 }
153 
154 #ifndef SWIG
155 //! Get adjoint of inputs to `compose` from adjoint of output
156 /** Compute the adjoint (reverse-mode sensitivity) of input transformations
157  to `compose` from the adjoint of the output transformation.
158  */
159 IMPALGEBRAEXPORT void
160 compose_adjoint(const Transformation3D &TA, const Transformation3D &TB,
161  const Transformation3DAdjoint &DTC,
162  Transformation3DAdjoint *DTA, Transformation3DAdjoint *DTB);
163 #endif
164 
165 //! Get adjoint of inputs to `compose` from adjoint of output
166 /** Compute the adjoint (reverse-mode sensitivity) of input transformations
167  to `compose` from the adjoint of the output transformation.
168  */
169 IMPALGEBRAEXPORT ComposeTransformation3DAdjoint
170 compose_adjoint(const Transformation3D &TA, const Transformation3D &TB,
171  const Transformation3DAdjoint &DTC);
172 
173 class Transformation2D;
174 
175 //! Build a 3D transformation from a 2D one.
176 /**
177  \note The 3D transformation is built with the 2D rotation becoming a rotation
178  around the z axis.
179  **/
180 IMPALGEBRAEXPORT Transformation3D
181  get_transformation_3d(const Transformation2D &t2d);
182 
183 //! Get a local transformation
184 /**
185  \note randomly select an axis that passes through the input point
186  and rotate around it
187  \param[in] origin the origin of the rotation
188  \param[in] max_translation default value is 5
189  \param[in] max_angle_in_rad default value is 15 degree in radians
190  **/
191 IMPALGEBRAEXPORT Transformation3D
193  double max_translation = 5.,
194  double max_angle_in_rad = 0.26);
195 
196 //! Return a bounding box containing the transformed box
198  const Transformation3D &tr) {
199  BoundingBoxD<3> nbb;
200  for (unsigned int i = 0; i < 2; ++i) {
201  for (unsigned int j = 0; j < 2; ++j) {
202  for (unsigned int k = 0; k < 2; ++k) {
203  algebra::Vector3D v(bb.get_corner(i)[0], bb.get_corner(j)[1],
204  bb.get_corner(k)[2]);
205  nbb += tr.get_transformed(v);
206  }
207  }
208  }
209  return nbb;
210 }
211 
213  const Transformation3D &tr) {
214  return Line3D(tr.get_rotation().get_rotated(l.get_direction()),
215  tr.get_transformed(l.get_point_on_line()));
216 }
217 
218 IMPALGEBRA_END_NAMESPACE
219 
220 #endif /* IMPALGEBRA_TRANSFORMATION_3D_H */
Base class for geometric types.
Simple 3D transformation class.
Simple implementation of lines in 3D.
Definition: Line3D.h:28
#define IMP_SHOWABLE_INLINE(Name, how_to_show)
Declare the methods needed by an object that can be printed.
const VectorD< D > & get_corner(unsigned int i) const
For 0 return lower corner and for 1, the upper corner.
Definition: BoundingBoxD.h:139
Simple implementation of lines in 3D.
Rotation2D compose(const Rotation2D &a, const Rotation2D &b)
Compose two rotations a and b.
Definition: Rotation2D.h:108
Vector3D get_point_on_line() const
Get the point on the line closest to the origin.
Definition: Line3D.h:41
Transformation3D get_rotation_about_point(const Vector3D &point, const Rotation3D &rotation)
Generate a Transformation3D object from a rotation around a point.
Transformation3D()
Default construct (makes an invalid transformation)
const Rotation3D & get_rotation() const
Return the rotation associated with this transformation.
#define IMP_VALUES(Name, PluralName)
Define the type for storing sets of values.
Definition: value_macros.h:23
Base class for geometric types.
A bounding box in D dimensions.
Transformation3D operator/(const Transformation3D &b) const
Compute the transformation which, when composed with b, gives *this.
Vector3D get_transformed(const Vector3D &o) const
Transform.
Transformation3D compose(const Transformation3D &a, const Transformation3D &b)
Compose two transformations.
Simple 3D rotation class.
3D rotation class.
Definition: Rotation3D.h:51
Transformation3D get_identity_transformation_3d()
Return a transformation that does not do anything.
Transformation3D operator*(const Transformation3D &tr) const
Transformation3D get_transformation_3d(const Transformation2D &t2d)
Build a 3D transformation from a 2D one.
Vector3D operator*(const Vector3D &v) const
Apply transformation (rotate and then translate)
Transformation3D(const Vector3D &t)
Construct a transformation with an identity rotation.
const Vector3D & get_direction() const
Get the unit vector in the direction of the line.
Definition: Line3D.h:38
VectorD< 3 > Vector3D
Definition: VectorD.h:421
Rotation3D get_identity_rotation_3d()
Return a rotation that does not do anything.
Definition: Rotation3D.h:356
Simple 3D vector class.
ComposeTransformation3DAdjoint compose_adjoint(const Transformation3D &TA, const Transformation3D &TB, const Transformation3DAdjoint &DTC)
Get adjoint of inputs to compose from adjoint of output.
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:168
Transformation3D(const Rotation3D &r, const Vector3D &t=Vector3D(0, 0, 0))
Basic constructor.
DensityMap * get_transformed(const DensityMap *input, const algebra::Transformation3D &tr, double threshold)
Return a new density map containing a rotated version of the old one.
const Vector3D & get_translation() const
Return the translation vector associated with this transformation.
Transformation3D get_random_local_transformation(Vector3D origin, double max_translation=5., double max_angle_in_rad=0.26)
Get a local transformation.