matrix_helpers.hpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. //
  2. // matrix_helpers.hpp
  3. // math
  4. //
  5. // Created by Sam Jaffe on 8/20/16.
  6. //
  7. #pragma once
  8. #include "math/matrix/matrix.hpp"
  9. #include "math/matrix/macro.h"
  10. namespace math::matrix {
  11. template <typename T, std::size_t N> 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> struct rotation_t {
  35. constexpr rotation_t(size_t f, size_t s) : first(f), second(s) {}
  36. size_t first, second;
  37. };
  38. namespace rotate {
  39. constexpr rotation_t<3> const X_AXIS{1, 2};
  40. constexpr rotation_t<3> const Y_AXIS{2, 0};
  41. constexpr rotation_t<3> const Z_AXIS{0, 1};
  42. constexpr rotation_t<3> const ROLL{1, 2};
  43. constexpr rotation_t<3> const PITCH{2, 0};
  44. constexpr rotation_t<3> const YAW{0, 1};
  45. constexpr rotation_t<2> const ROT_2D{0, 1};
  46. }
  47. template <typename T, size_t D>
  48. auto rotation(T theta, rotation_t<D> r) -> 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) -> matrix<decltype(sin(theta)), D, D> {
  64. static_assert(D > RD, "rotation<D> has to increase the number of dimensions");
  65. using G = decltype(sin(theta));
  66. return rotation(theta, r).concat(identity<G, D - RD>(),
  67. 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,
  71. vector::vector<T, N> const & rhs) {
  72. vector::vector<T, N + 1> tmp(rhs);
  73. tmp[N] = 1;
  74. return vector::vector<T, N>(lhs * tmp);
  75. }
  76. }
  77. #include "math/matrix/undef.h"