// // matrix_helpers.hpp // math // // Created by Sam Jaffe on 8/20/16. // #pragma once #include "matrix.hpp" namespace math { namespace matrix { template matrix identity() { matrix rval; VECTOR_FOR_EACH(i) { rval.at(i,i) = 1; } return rval; } template matrix diagonal(vector::vector const & vec) { matrix rval = identity(); VECTOR_FOR_EACH(i) { rval.at(i,i) = vec[i]; } return rval; } template matrix translation(vector::vector const & vec) { matrix rval = identity(); VECTOR_FOR_EACH(i) { rval.at(i,N) = vec[i]; } return rval; } template matrix scalar(vector::vector const & vec) { matrix rval = identity(); VECTOR_FOR_EACH(i) { rval.at(i,i) = vec[i]; } return rval; } template struct rotation_t { constexpr rotation_t(size_t f, size_t s) : first(f), second(s) {} size_t first, second; }; namespace rotate { constexpr rotation_t<3> const X_AXIS{1,2}; constexpr rotation_t<3> const Y_AXIS{2,0}; constexpr rotation_t<3> const Z_AXIS{0,1}; constexpr rotation_t<3> const ROLL{1,2}; constexpr rotation_t<3> const PITCH{2,0}; constexpr rotation_t<3> const YAW{0,1}; constexpr rotation_t<2> const ROT_2D{0,1}; } template auto rotation(T theta, rotation_t r) -> matrix { static_assert(D >= 2, "cannot rotate with 1D matrix"); using G = decltype(sin(theta)); using std::sin; using std::cos; matrix rval = identity(); G const vsin = sin(theta); G const vcos = cos(theta); rval.at(r.first, r.first) = vcos; rval.at(r.second, r.second) = vcos; rval.at(r.first, r.second) = -vsin; rval.at(r.second, r.first) = vsin; return rval; } template auto rotation(T theta, rotation_t r) -> matrix { static_assert(D > RD, "rotation has to increase the number of dimensions"); using G = decltype(sin(theta)); return rotation(theta, r).concat(identity(), concat_strategy::diagonal); } template vector::vector operator*(matrix const & lhs, vector::vector const & rhs) { vector::vector tmp(rhs); tmp[N] = 1; return vector::vector(lhs * tmp); } } }