IMP  2.0.1
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-2013 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 "Rotation3D.h"
15 #include "BoundingBoxD.h"
16 #include "GeometricPrimitiveD.h"
17 
18 IMPALGEBRA_BEGIN_NAMESPACE
19 
20 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
21 class Transformation3D;
22 Transformation3D compose(const Transformation3D &a,
23  const Transformation3D &b);
24 #endif
25 
26 //! Simple 3D transformation class
27 /** The rotation is applied first, and then the point is translated.
28  \see IMP::core::Transform
29  \geometry
30 */
31 class IMPALGEBRAEXPORT Transformation3D: public GeometricPrimitiveD<3>
32 {
33 public:
34  //! construct an invalid transformation
36  /** basic constructor*/
38  const Vector3D& t=Vector3D(0,0,0)):
39  trans_(t), rot_(r){}
40  /** Construct a transformation with an identity rotation.*/
42  trans_(t), rot_(get_identity_rotation_3d()){}
44  //! transform
45  Vector3D get_transformed(const Vector3D &o) const {
46  return rot_.get_rotated(o) + trans_;
47  }
48  //! apply transformation (rotate and then translate)
49  Vector3D operator*(const Vector3D &v) const {
50  return get_transformed(v);
51  }
52  /** compose two rigid transformation such that for any vector v
53  (rt1*rt2)*v = rt1*(rt2*v) */
55  return compose(*this, tr);
56  }
57  const Transformation3D& operator*=(const Transformation3D &o) {
58  *this=compose(*this, o);
59  return *this;
60  }
61  /** Compute the transformation which, when composed with b, gives *this.
62  That is a(x)== d(b(x)) for all x.
63 
64  For consistency, this should probably have a nice name, but
65  I don't know what name to give it.
66  */
68  Transformation3D ret= compose(*this, b.get_inverse());
69  return ret;
70  }
71  const Transformation3D& operator/=(const Transformation3D &o) {
72  *this= *this/o;
73  return *this;
74  }
75  const Rotation3D& get_rotation() const {
76  return rot_;
77  }
78  const Vector3D& get_translation()const{return trans_;}
79 
80  IMP_SHOWABLE_INLINE(Transformation3D, {
81  rot_.show(out);
82  out<<" || "<<trans_;
83  }
84  );
85  Transformation3D get_inverse() const;
86 private:
87  Vector3D trans_; //translation
88  Rotation3D rot_; //rotation
89 };
90 
92 
93 
94 //! Return a transformation that does not do anything
95 /** \relatesalso Transformation3D */
97  return Transformation3D(get_identity_rotation_3d(),Vector3D(0.0,0.0,0.0));
98 }
99 
100 //! Generate a Transformation3D object from a rotation around a point
101 /** Rotate about a point rather than the origin.
102  \param[in] point Center to rotate about
103  \param[in] rotation The rotation to perform
104 
105  \relatesalso Transformation3D
106 */
107 inline Transformation3D
109  const Rotation3D &rotation) {
110  return Transformation3D(rotation, (rotation*(-point)+point));
111 }
112 
113 //! compose two transformations
114  /** For any vector v (a*b)*v = a*(b*v).
115  \relatesalso Transformation3D
116  */
118  const Transformation3D &b){
119  return Transformation3D(compose(a.get_rotation(), b.get_rotation()),
120  a.get_transformed(b.get_translation()));
121 }
122 
123 class Transformation2D;
124 
125 //! Builds a 3D transformation from a 2D one.
126 /**
127  \note The 3D transformation is built with the 2D rotation becoming a rotation
128  around the z axis.
129  **/
130 IMPALGEBRAEXPORT Transformation3D get_transformation_3d(
131  const Transformation2D &t2d);
132 
133 //! Get a local transformation
134 /**
135  \note randomly select an axis that passes to the input point
136  and rotate around it
137  \param[in] origin the origin of the rotation
138  \param[in] max_translation detault value is 5
139  \param[in] max_angle_in_rad default value is 15 degree in radians
140  **/
141 IMPALGEBRAEXPORT Transformation3D get_random_local_transformation(
142  Vector3D origin,
143  double max_translation=5.,
144  double max_angle_in_rad=0.26);
145 
146 
147 
148 
149 //! Return a bounding box containing the transformed box
151  const Transformation3D &tr) {
152  BoundingBoxD<3> nbb;
153  for (unsigned int i=0; i< 2; ++i) {
154  for (unsigned int j=0; j< 2; ++j) {
155  for (unsigned int k=0; k< 2; ++k) {
156  algebra::Vector3D v(bb.get_corner(i)[0],
157  bb.get_corner(j)[1],
158  bb.get_corner(k)[2]);
159  nbb+= tr.get_transformed(v);
160  }
161  }
162  }
163  return nbb;
164 }
165 
166 IMPALGEBRA_END_NAMESPACE
167 
168 #endif /* IMPALGEBRA_TRANSFORMATION_3D_H */