Virtual Testbed
Ship dynamics simulator for extreme conditions
basis.hh
1 #ifndef VTESTBED_GEOMETRY_BASIS_HH
2 #define VTESTBED_GEOMETRY_BASIS_HH
3 
4 #include <array>
5 
6 #include <vtestbed/base/bstream.hh>
7 #include <vtestbed/geometry/types.hh>
8 
9 namespace vtb {
10 
11  namespace geometry {
12 
14 
15  template <class T, int N>
16  class Basis: public Matrix<T,N> {
17 
18  private:
19  using matrix_type = Matrix<T,N>;
20  using row_type = Vertex<T,N>;
21  using column_type = Vertex<T,N>;
23 
24  public:
25  using matrix_type::matrix_type;
26  using matrix_type::operator=;
27  using matrix_type::operator();
28 
29  inline Basis(): matrix_type(blitz::identity_matrix<T,N>()) {}
30  inline Basis(const matrix_type& rhs): matrix_type(rhs) {}
31  inline Basis(const array_type& rhs): matrix_type(blitz::const_matrix<T,N>(rhs)) {}
32 
33  inline Basis&
34  operator=(const array_type& rhs) {
35  *this = blitz::const_matrix<T,N>(rhs);
36  return *this;
37  }
38 
39  inline column_type
40  row(int n) const {
41  const auto& m = *this;
42  row_type r;
43  for (int i=0; i<N; ++i) { r(i) = m(n,i); }
44  return r;
45  }
46 
47  inline column_type
48  column(int n) const {
49  const auto& m = *this;
50  column_type c;
51  for (int i=0; i<N; ++i) { c(i) = m(i,n); }
52  return c;
53  }
54 
55  template <class ... Args>
56  inline Basis<T,N>
57  column_basis(Args ... cols) const {
58  const int columns[sizeof...(cols)] = {cols...};
59  const auto& m = *this;
60  Basis<T,N> b{T{}};
61  for (int i=0; i<N; ++i) { b(i,i) = 1; }
62  for (int i=0; i<N; ++i) {
63  for (const auto& j : columns) {
64  b(i,j) = m(i,j);
65  }
66  }
67  return b;
68  }
69 
70  inline void clear() { *this = blitz::identity_matrix<T,N>(); }
71 
72  };
73 
74  template <class T, int N>
75  inline void
76  transpose(Basis<T,N>& basis) {
77  blitz::transpose(basis);
78  }
79 
80  template <class T, int N>
81  inline Vertex<T,N>
82  to(const Basis<T,N>& b, const Vertex<T,N>& v) {
83  return product(b, v);
84  }
85 
137  template <class T, int N>
138  Basis<T,N>
139  rotation_matrix_zyx(const Vertex<T,N>& angle);
140 
141  template <class T, int N>
142  Basis<T,N>
143  rotation_matrix_xyz(const Vertex<T,N>& angle);
144 
145  template <class T, int N>
146  Basis<T,N>
147  inverse(const Basis<T,N>& basis);
148 
149  template <class T, int N>
150  bstream&
151  operator<<(bstream& out, const Rotation_matrix<T,N>& rhs);
152 
153  template <class T, int N>
154  bstream&
155  operator>>(bstream& in, Rotation_matrix<T,N>& rhs);
156 
157  template <class T, int N>
158  class Rotation_matrix: public Basis<T,N> {
159 
160  private:
161  using basis_type = Basis<T,N>;
162  using vertex_type = Vertex<T,N>;
163 
164  private:
165  basis_type _ibasis;
166 
167  public:
168  Rotation_matrix() = default;
169 
170  inline explicit
171  Rotation_matrix(const basis_type& basis, const basis_type& ibasis):
172  basis_type(basis), _ibasis(ibasis) {}
173 
174  inline explicit
175  Rotation_matrix(const basis_type& basis):
176  Rotation_matrix(basis, inverse(basis)) {}
177 
178  inline const basis_type& inverse() const { return this->_ibasis; }
179  inline void clear() { this->basis_type::clear(); this->_ibasis.clear(); }
180 
181  friend bstream& operator<< <T,N>(bstream& out, const Rotation_matrix<T,N>& rhs);
182  friend bstream& operator>> <T,N>(bstream& in, Rotation_matrix<T,N>& rhs);
183 
184  };
185 
186  template <class T, int N>
187  Basis<T,N>
188  inverse(const Rotation_matrix<T,N>& rot) {
189  return rot.inverse();
190  }
191 
192  template <class T, int N, class X>
193  inline auto
194  operator*(const Basis<T,N>& lhs, const X& rhs) -> decltype(product(lhs, rhs)) {
195  return product(lhs, rhs);
196  }
197 
198  template <class T, int N>
199  inline Vertex<T,N>
200  to(const Rotation_matrix<T,N>& rot, const Vertex<T,N>& v) {
201  return product(rot, v);
202  }
203 
204  template <class T, int N>
205  inline Vertex<T,N>
206  from(const Rotation_matrix<T,N>& rot, const Vertex<T,N>& v) {
207  return product(rot.inverse(), v);
208  }
209 
210  template <class T, int N>
211  inline Rotation_matrix<T,N>
212  make_rotation(const Basis<T,N>& basis, const Basis<T,N>& ibasis) {
213  return Rotation_matrix<T,N>(basis, ibasis);
214  }
215 
216  template <class T, int N>
217  inline Rotation_matrix<T,N>
218  make_rotation(const Basis<T,N>& basis) {
219  return Rotation_matrix<T,N>(basis);
220  }
221 
227  template <class T, int N>
228  Rotation_matrix<T,N>
229  make_rotation_zyx(const Vertex<T,N>& angles);
230 
231  template <class T, int N>
232  Rotation_matrix<T,N>
233  make_rotation_xyz(const Vertex<T,N>& angles);
234 
235  template <class T, int N>
236  bstream&
237  operator<<(bstream& out, const Coordinate_system<T,N>& rhs);
238 
239  template <class T, int N>
240  bstream&
241  operator>>(bstream& in, Coordinate_system<T,N>& rhs);
242 
243  template <class T, int N>
245 
246  private:
247  using basis_type = Basis<T,N>;
248  using vertex_type = Vertex<T,N>;
250 
251  private:
252  rotation_type _rotation;
253  vertex_type _origin{T{}};
254 
255  public:
256 
257  Coordinate_system() = default;
258 
259  inline
260  Coordinate_system(const basis_type& basis, const vertex_type& origin):
261  _rotation(basis, inverse(basis)), _origin(origin) {}
262 
263  inline
264  Coordinate_system(const basis_type& basis, const basis_type& ibasis,
265  const vertex_type& origin): _rotation(basis, ibasis), _origin(origin) {}
266 
267  inline
268  Coordinate_system(const rotation_type& rot, const vertex_type& origin):
269  _rotation(rot), _origin(origin) {}
270 
271  inline const rotation_type& rotation() const { return this->_rotation; }
272  inline void rotation(const rotation_type& rhs) { this->_rotation = rhs; }
273  inline const basis_type& basis() const { return this->_rotation; }
274  inline const basis_type& inverse_basis() const { return this->_rotation.inverse(); }
275  inline const vertex_type& origin() const { return this->_origin; }
276  inline void origin(const vertex_type& rhs) { this->_origin = rhs; }
277  inline void clear() { this->_rotation.clear(); this->_origin = T{}; }
278 
279  friend bstream& operator<< <T,N>(bstream& out, const Coordinate_system<T,N>& rhs);
280  friend bstream& operator>> <T,N>(bstream& in, Coordinate_system<T,N>& rhs);
281 
282  };
283 
284  template <class T, int N>
286  make_coordinate_system(const Basis<T, N>& basis, const Vertex<T, N>& origin) {
287  return Coordinate_system<T,N>(basis, origin);
288  }
289 
290  template <class T, int N>
291  inline Coordinate_system<T,N>
292  make_coordinate_system(
293  const Basis<T,N>& basis,
294  const Basis<T,N>& ibasis,
295  const Vertex<T,N>& origin
296  ) {
297  return Coordinate_system<T,N>(basis, ibasis, origin);
298  }
299 
300  template <class T, int N>
301  inline Coordinate_system<T,N>
302  make_coordinate_system(const Rotation_matrix<T,N>& rot, const Vertex<T,N>& origin) {
303  return Coordinate_system<T,N>(rot, origin);
304  }
305 
306  template <class T, int N>
307  inline Vertex<T,N>
308  to(const Coordinate_system<T,N>& cs, const Vertex<T,N>& v) {
309  Vertex<T,N> x = v-cs.origin();
310  return product(cs.basis(), x);
311  }
312 
313  template <class T, int N>
314  inline Vertex<T,N>
315  from(const Coordinate_system<T,N>& cs, const Vertex<T,N>& v) {
316  return product(cs.inverse_basis(), v) + cs.origin();
317  }
318 
319  template <class T, int N>
320  inline Vertex<T,N>
321  vector_to(const Rotation_matrix<T,N>& r, const Vertex<T,N>& v) {
322  return product(r, v);
323  }
324 
325  template <class T, int N>
326  inline Vertex<T,N>
327  vector_to(const Coordinate_system<T,N>& cs, const Vertex<T,N>& v) {
328  return product(cs.basis(), v);
329  }
330 
331  template <class T, int N>
332  inline Vertex<T,N>
333  vector_from(const Coordinate_system<T,N>& cs, const Vertex<T,N>& v) {
334  return product(cs.inverse_basis(), v);
335  }
336 
337  template <class T, int N>
338  inline Vertex<T,N>
339  from(
340  const Basis<T,N>& basis,
341  const Vertex<T,N>& origin,
342  const Vertex<T,N>& v
343  ) {
344  return product(inverse(basis), v) + origin;
345  }
346 
347  }
348 
349 }
350 
351 #endif // vim:filetype=cpp
Rotation_matrix< T, N > make_rotation_zyx(const Vertex< T, N > &angles)
Rotation_matrix matrix for Euler angles in order.
Main namespace.
Definition: convert.hh:9
Basis< T, N > rotation_matrix_zyx(const Vertex< T, N > &angle)
Return rotation matrix specified by Euler angles.