1 #ifndef VTESTBED_GEOMETRY_BASIS_HH 2 #define VTESTBED_GEOMETRY_BASIS_HH 6 #include <vtestbed/base/bstream.hh> 7 #include <vtestbed/geometry/types.hh> 15 template <
class T,
int N>
16 class Basis:
public Matrix<T,N> {
19 using matrix_type = Matrix<T,N>;
20 using row_type = Vertex<T,N>;
21 using column_type = Vertex<T,N>;
25 using matrix_type::matrix_type;
26 using matrix_type::operator=;
27 using matrix_type::operator();
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)) {}
35 *
this = blitz::const_matrix<T,N>(rhs);
41 const auto& m = *
this;
43 for (
int i=0; i<N; ++i) { r(i) = m(n,i); }
49 const auto& m = *
this;
51 for (
int i=0; i<N; ++i) { c(i) = m(i,n); }
55 template <
class ... Args>
57 column_basis(Args ... cols)
const {
58 const int columns[
sizeof...(cols)] = {cols...};
59 const auto& m = *
this;
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) {
70 inline void clear() { *
this = blitz::identity_matrix<T,N>(); }
74 template <
class T,
int N>
77 blitz::transpose(basis);
80 template <
class T,
int N>
82 to(
const Basis<T,N>& b,
const Vertex<T,N>& v) {
137 template <
class T,
int N>
141 template <
class T,
int N>
143 rotation_matrix_xyz(
const Vertex<T,N>& angle);
145 template <
class T,
int N>
147 inverse(
const Basis<T,N>& basis);
149 template <
class T,
int N>
151 operator<<(bstream& out,
const Rotation_matrix<T,N>& rhs);
153 template <
class T,
int N>
155 operator>>(bstream& in, Rotation_matrix<T,N>& rhs);
157 template <
class T,
int N>
162 using vertex_type = Vertex<T,N>;
178 inline const basis_type& inverse()
const {
return this->_ibasis; }
179 inline void clear() { this->basis_type::clear(); this->_ibasis.clear(); }
186 template <
class T,
int N>
189 return rot.inverse();
192 template <
class T,
int N,
class X>
194 operator*(
const Basis<T,N>& lhs,
const X& rhs) -> decltype(product(lhs, rhs)) {
195 return product(lhs, rhs);
198 template <
class T,
int N>
200 to(
const Rotation_matrix<T,N>& rot,
const Vertex<T,N>& v) {
201 return product(rot, v);
204 template <
class T,
int N>
206 from(
const Rotation_matrix<T,N>& rot,
const Vertex<T,N>& v) {
207 return product(rot.inverse(), v);
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);
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);
227 template <
class T,
int N>
231 template <
class T,
int N>
233 make_rotation_xyz(
const Vertex<T,N>& angles);
235 template <
class T,
int N>
237 operator<<(bstream& out,
const Coordinate_system<T,N>& rhs);
239 template <
class T,
int N>
241 operator>>(bstream& in, Coordinate_system<T,N>& rhs);
243 template <
class T,
int N>
248 using vertex_type = Vertex<T,N>;
253 vertex_type _origin{T{}};
261 _rotation(basis, inverse(basis)), _origin(origin) {}
265 const vertex_type& origin): _rotation(basis, ibasis), _origin(origin) {}
269 _rotation(rot), _origin(origin) {}
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{}; }
284 template <
class T,
int N>
286 make_coordinate_system(
const Basis<T, N>& basis,
const Vertex<T, N>& origin) {
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
297 return Coordinate_system<T,N>(basis, ibasis, origin);
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);
306 template <
class T,
int 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);
313 template <
class T,
int N>
315 from(
const Coordinate_system<T,N>& cs,
const Vertex<T,N>& v) {
316 return product(cs.inverse_basis(), v) + cs.origin();
319 template <
class T,
int N>
321 vector_to(
const Rotation_matrix<T,N>& r,
const Vertex<T,N>& v) {
322 return product(r, v);
325 template <
class T,
int N>
327 vector_to(
const Coordinate_system<T,N>& cs,
const Vertex<T,N>& v) {
328 return product(cs.basis(), v);
331 template <
class T,
int N>
333 vector_from(
const Coordinate_system<T,N>& cs,
const Vertex<T,N>& v) {
334 return product(cs.inverse_basis(), v);
337 template <
class T,
int N>
340 const Basis<T,N>& basis,
341 const Vertex<T,N>& origin,
344 return product(inverse(basis), v) + origin;
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.
Basis< T, N > rotation_matrix_zyx(const Vertex< T, N > &angle)
Return rotation matrix specified by Euler angles.