diff options
Diffstat (limited to 'src/math.hpp')
-rw-r--r-- | src/math.hpp | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/src/math.hpp b/src/math.hpp new file mode 100644 index 0000000..b958092 --- /dev/null +++ b/src/math.hpp @@ -0,0 +1,231 @@ +template <typename T, size_t N> +class vec_t { + template<size_t index, typename... U> + void load_from_args(void) + { + static_assert(index < N + 1, "too many elements in the initializer"); + static_assert(index > N - 1, "too few elements in the initializer"); + } + + template<size_t index, typename... U> + void load_from_args(T first, U... rest) + { + v[index] = first; + load_from_args<index + 1>(rest...); + } + +public: + T v[N]; + + // Basic operations + + vec_t() = default; + + template<typename... U> + vec_t(T first, U... rest) + { + load_from_args<0>(first, rest...); + } + + template<typename U> + vec_t(vec_t<U, N> b) + { + for (size_t i = 0; i < N; i++) + v[i] = (T)b[i]; + } + + T& operator[](size_t i) + { + return v[i]; + } + + const T& operator[](size_t i) const + { + return v[i]; + } + + // Comparison + + friend bool operator==(const vec_t<T, N> &a, const vec_t<T, N> &b) + { + for (size_t i = 0; i < N; i++) + if (a[i] != b[i]) + return false; + + return true; + } + + // Good enough for maps or sets. + friend bool operator<(const vec_t<T, N> &a, const vec_t<T, N> &b) + { + for (size_t i = 0; i < N; i++) { + if (a[i] < b[i]) + return true; + else if (a[i] > b[i]) + return false; + } + + return false; + } + + // Arithmetics + + friend vec_t<T, N> operator+(const vec_t<T, N> &v) + { + return v; + } + + friend vec_t<T, N> operator+(const vec_t<T, N> &a, const vec_t<T, N> &b) + { + vec_t<T, N> r; + + for (size_t i = 0; i < N; i++) + r[i] = a[i] + b[i]; + + return r; + } + + friend vec_t<T, N> &operator+=(vec_t<T, N> &v, const vec_t<T, N> &b) + { + for (size_t i = 0; i < N; i++) + v[i] += b[i]; + + return v; + } + + friend vec_t<T, N> operator-(const vec_t<T, N> &v) + { + return -1 * v; + } + + friend vec_t<T, N> operator-(const vec_t<T, N> &a, const vec_t<T, N> &b) + { + vec_t<T, N> r; + + for (size_t i = 0; i < N; i++) + r[i] = a[i] - b[i]; + + return r; + } + + friend vec_t<T, N> &operator-=(vec_t<T, N> &v, const vec_t<T, N> &b) + { + for (size_t i = 0; i < N; i++) + v[i] -= b[i]; + + return v; + } + + friend T operator*(const vec_t<T, N> &a, const vec_t<T, N> &b) + { + T r = (T)0; + + for (size_t i = 0; i < N; i++) + r += a[i] * b[i]; + + return r; + } + + friend vec_t<T, N> operator*(const vec_t<T, N> &a, const T &b) + { + vec_t<T, N> r; + + for (size_t i = 0; i < N; i++) + r[i] = a[i] * b; + + return r; + } + + friend vec_t<T, N> operator*(const T &b, const vec_t<T, N> &a) + { + return a * b; + } + + friend vec_t<T, N> &operator*=(vec_t<T, N> &v, const T &b) + { + for (size_t i = 0; i < N; i++) + v[i] *= b; + + return v; + } + + friend vec_t<T, N> operator/(const vec_t<T, N> &a, const T &b) + { + vec_t<T, N> r; + + for (size_t i = 0; i < N; i++) + r[i] = a[i] / b; + + return r; + } + + friend vec_t<T, N> operator/(const T &b, const vec_t<T, N> &a) + { + return a / b; + } + + friend vec_t<T, N> &operator/=(vec_t<T, N> &v, const T &b) + { + for (size_t i = 0; i < N; i++) + v[i] /= b; + + return v; + } + + // Compatibility with SFML + + template <typename U> + operator sf::Vector2<U>() const + { + static_assert(N == 2, "conversion of vec_t with N != 2 to sf::Vector2"); + return sf::Vector2<U>((U)v[0], (U)v[1]); + } + + template <typename U> + vec_t(sf::Vector2<U> b) + { + static_assert(N == 2, "conversion of sf::Vector2 to vec_t with N != 2"); + v[0] = b.x; + v[1] = b.y; + } + + // Compatibility with iostream + + friend std::ostream& operator<<(std::ostream& stream, vec_t<T, N> v) + { + stream << "("; + for (size_t i = 0; i < N; i++) { + if (i) + stream << ", "; + stream << v.v[i]; + } + stream << ")"; + + return stream; + } +}; + +// Shorthands +typedef vec_t<float, 2> v2f_t; +typedef vec_t<double, 2> v2d_t; + +template <typename T, size_t N> +class rect_t { +public: + vec_t<T, N> a, b; + + rect_t() = default; + + rect_t(vec_t<T, N> a_, vec_t<T, N> b_) + { + a = a_; + b = b_; + } + + friend std::ostream& operator<<(std::ostream& stream, rect_t<T, N> r) + { + stream << "(" << r.a << ", " << r.b << ")"; + return stream; + } +}; + |