1 /**
2  *  \file RMF/internal/Transform.h
3  *  \brief Handle read/write of Model data from/to files.
4  *
5  *  Copyright 2007-2021 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef RMF_INTERNAL_TRANSFORM_H
10 #define RMF_INTERNAL_TRANSFORM_H
11 
12 #include <ostream>
13 
14 #include "RMF/Vector.h"
15 #include "RMF/config.h"
16 #include "RMF/infrastructure_macros.h"
17 #include "RMF/types.h"
18 
19 RMF_ENABLE_WARNINGS namespace RMF {
20   namespace internal {
21 
22   class Rotation {
23     Vector4 v_;
24     double matrix_[3][3];
25     void fill_matrix();
26     template <class A, class B>
get_dotprod(const A & a,const B & b)27     static double get_dotprod(const A& a, const B& b) {
28       return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
29     }
30 
31    public:
32     Rotation(Rotation a, Rotation b);
Rotation()33     Rotation() {
34       v_[0] = 1;
35       v_[1] = 0;
36       v_[2] = 0;
37       v_[3] = 0;
38       fill_matrix();
39     }
Rotation(const Vector4 & r)40     Rotation(const Vector4& r) : v_(r) {
41       fill_matrix();
42     }
43 
44     //! Rotate a vector around the origin
get_rotated(const Vector3 & o)45     Vector3 get_rotated(const Vector3& o) const {
46       Vector3 ret;
47       ret[0] = get_dotprod(o, matrix_[0]);
48       ret[1] = get_dotprod(o, matrix_[1]);
49       ret[2] = get_dotprod(o, matrix_[2]);
50       return ret;
51     }
get_quaternion()52     const Vector4& get_quaternion() const { return v_; }
53     RMF_SHOWABLE(Rotation, v_);
54   };
55 
56   class Transform {
57     Rotation rot_;
58     Vector3 trans_;
59 
60    public:
Transform()61     Transform() {
62       trans_[0] = 0;
63       trans_[1] = 0;
64       trans_[2] = 0;
65     }
Transform(const Transform & a,const Transform & b)66     Transform(const Transform& a, const Transform& b) : rot_(a.rot_, b.rot_) {
67       trans_ = a.get_transformed(b.get_translation());
68     }
Transform(const Rotation & r,const Vector3 & t)69     Transform(const Rotation& r, const Vector3& t) : rot_(r), trans_(t) {}
get_transformed(const Vector3 & o)70     Vector3 get_transformed(const Vector3& o) const {
71       Vector3 ret = rot_.get_rotated(o);
72       ret[0] += trans_[0];
73       ret[1] += trans_[1];
74       ret[2] += trans_[2];
75       return ret;
76     }
get_translation()77     const Vector3& get_translation() const { return trans_; }
get_rotation()78     const Vector4& get_rotation() const { return rot_.get_quaternion(); }
79     RMF_SHOWABLE(Transform, "Rotation: " << rot_
80                                          << " and translation: " << trans_);
81   };
82 
83   }  // namespace internal
84 } /* namespace RMF */
85 RMF_DISABLE_WARNINGS
86 
87 #endif /* RMF_INTERNAL_TRANSFORM_H */
88