From f66cf28c8b4d80122896c87dba8af74ea1872eba Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Tue, 17 Oct 2017 16:39:13 +0200 Subject: New vectors. Start refactoring to use it. --- src/math.hpp | 231 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 src/math.hpp (limited to 'src/math.hpp') 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 +class vec_t { + template + 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 + void load_from_args(T first, U... rest) + { + v[index] = first; + load_from_args(rest...); + } + +public: + T v[N]; + + // Basic operations + + vec_t() = default; + + template + vec_t(T first, U... rest) + { + load_from_args<0>(first, rest...); + } + + template + vec_t(vec_t 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 &a, const vec_t &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 &a, const vec_t &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 operator+(const vec_t &v) + { + return v; + } + + friend vec_t operator+(const vec_t &a, const vec_t &b) + { + vec_t r; + + for (size_t i = 0; i < N; i++) + r[i] = a[i] + b[i]; + + return r; + } + + friend vec_t &operator+=(vec_t &v, const vec_t &b) + { + for (size_t i = 0; i < N; i++) + v[i] += b[i]; + + return v; + } + + friend vec_t operator-(const vec_t &v) + { + return -1 * v; + } + + friend vec_t operator-(const vec_t &a, const vec_t &b) + { + vec_t r; + + for (size_t i = 0; i < N; i++) + r[i] = a[i] - b[i]; + + return r; + } + + friend vec_t &operator-=(vec_t &v, const vec_t &b) + { + for (size_t i = 0; i < N; i++) + v[i] -= b[i]; + + return v; + } + + friend T operator*(const vec_t &a, const vec_t &b) + { + T r = (T)0; + + for (size_t i = 0; i < N; i++) + r += a[i] * b[i]; + + return r; + } + + friend vec_t operator*(const vec_t &a, const T &b) + { + vec_t r; + + for (size_t i = 0; i < N; i++) + r[i] = a[i] * b; + + return r; + } + + friend vec_t operator*(const T &b, const vec_t &a) + { + return a * b; + } + + friend vec_t &operator*=(vec_t &v, const T &b) + { + for (size_t i = 0; i < N; i++) + v[i] *= b; + + return v; + } + + friend vec_t operator/(const vec_t &a, const T &b) + { + vec_t r; + + for (size_t i = 0; i < N; i++) + r[i] = a[i] / b; + + return r; + } + + friend vec_t operator/(const T &b, const vec_t &a) + { + return a / b; + } + + friend vec_t &operator/=(vec_t &v, const T &b) + { + for (size_t i = 0; i < N; i++) + v[i] /= b; + + return v; + } + + // Compatibility with SFML + + template + operator sf::Vector2() const + { + static_assert(N == 2, "conversion of vec_t with N != 2 to sf::Vector2"); + return sf::Vector2((U)v[0], (U)v[1]); + } + + template + vec_t(sf::Vector2 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 v) + { + stream << "("; + for (size_t i = 0; i < N; i++) { + if (i) + stream << ", "; + stream << v.v[i]; + } + stream << ")"; + + return stream; + } +}; + +// Shorthands +typedef vec_t v2f_t; +typedef vec_t v2d_t; + +template +class rect_t { +public: + vec_t a, b; + + rect_t() = default; + + rect_t(vec_t a_, vec_t b_) + { + a = a_; + b = b_; + } + + friend std::ostream& operator<<(std::ostream& stream, rect_t r) + { + stream << "(" << r.a << ", " << r.b << ")"; + return stream; + } +}; + -- cgit