matrix_helpers.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. //
  2. // matrix_helpers.hpp
  3. // math
  4. //
  5. // Created by Sam Jaffe on 8/20/16.
  6. //
  7. #pragma once
  8. #include "matrix.hpp"
  9. namespace math { namespace matrix {
  10. template <typename T, std::size_t N>
  11. matrix<T, N, N> identity() {
  12. matrix<T, N, N> rval;
  13. VECTOR_FOR_EACH(i) { rval.at(i,i) = 1; }
  14. return rval;
  15. }
  16. template <typename T, std::size_t N>
  17. matrix<T, N, N> diagonal(vector::vector<T, N> const & vec) {
  18. matrix<T, N, N> rval = identity<T, N>();
  19. VECTOR_FOR_EACH(i) { rval.at(i,i) = vec[i]; }
  20. return rval;
  21. }
  22. template <typename T, std::size_t N>
  23. matrix<T, N+1, N+1> translation(vector::vector<T, N> const & vec) {
  24. matrix<T, N+1, N+1> rval = identity<T, N+1>();
  25. VECTOR_FOR_EACH(i) { rval.at(i,N) = vec[i]; }
  26. return rval;
  27. }
  28. template <typename T, std::size_t N>
  29. matrix<T, N+1, N+1> scalar(vector::vector<T, N> const & vec) {
  30. matrix<T, N+1, N+1> rval = identity<T, N+1>();
  31. VECTOR_FOR_EACH(i) { rval.at(i,i) = vec[i]; }
  32. return rval;
  33. }
  34. template <size_t N>
  35. struct rotation_t {
  36. constexpr rotation_t(size_t f, size_t s)
  37. : first(f), second(s) {}
  38. size_t first, second;
  39. };
  40. namespace rotate {
  41. constexpr rotation_t<3> const X_AXIS{1,2};
  42. constexpr rotation_t<3> const Y_AXIS{2,0};
  43. constexpr rotation_t<3> const Z_AXIS{0,1};
  44. constexpr rotation_t<3> const ROLL{1,2};
  45. constexpr rotation_t<3> const PITCH{2,0};
  46. constexpr rotation_t<3> const YAW{0,1};
  47. constexpr rotation_t<2> const ROT_2D{0,1};
  48. }
  49. template <typename T, size_t D>
  50. auto rotation(T theta, rotation_t<D> r) -> matrix<decltype(sin(theta)), D, D> {
  51. static_assert(D >= 2, "cannot rotate with 1D matrix");
  52. using G = decltype(sin(theta));
  53. using std::sin;
  54. using std::cos;
  55. matrix<G, D, D> rval = identity<G, D>();
  56. G const vsin = sin(theta);
  57. G const vcos = cos(theta);
  58. rval.at(r.first, r.first) = vcos;
  59. rval.at(r.second, r.second) = vcos;
  60. rval.at(r.first, r.second) = -vsin;
  61. rval.at(r.second, r.first) = vsin;
  62. return rval;
  63. }
  64. template <size_t D, typename T, size_t RD>
  65. auto rotation(T theta, rotation_t<RD> r) -> matrix<decltype(sin(theta)), D, D> {
  66. using G = decltype(sin(theta));
  67. return rotation(theta, r).concat(identity<G, D - RD>(), concat_strategy::diagonal);
  68. }
  69. template <typename T, size_t N>
  70. vector::vector<T, N> operator*(matrix<T, N+1, N+1> const & lhs, vector::vector<T, N> const & rhs) {
  71. vector::vector<T, N+1> tmp(rhs);
  72. tmp[N] = 1;
  73. return vector::vector<T, N>(lhs * tmp);
  74. }
  75. } }