matrix_helpers.hpp 2.7 KB

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