#ifndef VEX_H #define VEX_H 1 #include #include #include #include #include namespace vex { template concept arithmetic = std::is_arithmetic::value; template requires (D > 1) struct vec_dimd { std::array v; explicit vec_dimd() = default; template explicit vec_dimd(Args&&... args) : v{args...} {} explicit vec_dimd(T args[D]) : v(args) {} explicit vec_dimd(T fill) { v.fill(fill); } T operator[](std::size_t i) { return v[i]; } T operator[](std::size_t i) const { return v[i]; } vec_dimd operator+=(const vec_dimd &rhs) { for(size_t i = 0; i < D; i++) v[i] += rhs.v[i]; return *this; } vec_dimd operator-=(const vec_dimd &rhs) { for(size_t i = 0; i < D; i++) v[i] -= rhs.v[i]; return *this; } vec_dimd operator*=(const vec_dimd &rhs) { for(size_t i = 0; i < D; i++) v[i] *= rhs.v[i]; return *this; } vec_dimd operator/=(const vec_dimd &rhs) { for(size_t i = 0; i < D; i++) v[i] /= rhs.v[i]; return *this; } vec_dimd operator*=(const T &rhs) { for(size_t i = 0; i < D; i++) v[i] *= rhs; return *this; } vec_dimd operator/=(const T &rhs) { for(size_t i = 0; i < D; i++) v[i] /= rhs; return *this; } vec_dimd operator-() { return vec_dimd(0) - *this; } auto operator<=>(const vec_dimd &rhs) const { return magnitude() <=> rhs.magnitude(); } bool operator==(const vec_dimd &rhs) const { for(unsigned i = 0; i < D; i++) if(v[i] != rhs.v[i]) return false; return true; } friend vec_dimd operator+(vec_dimd lhs, const vec_dimd &rhs) { lhs += rhs; return lhs; } friend vec_dimd operator-(vec_dimd lhs, const vec_dimd &rhs) { lhs -= rhs; return lhs; } friend vec_dimd operator*(vec_dimd lhs, const vec_dimd &rhs) { lhs *= rhs; return lhs; } friend vec_dimd operator/(vec_dimd lhs, const vec_dimd &rhs) { lhs /= rhs; return lhs; } friend vec_dimd operator*(vec_dimd lhs, const T &rhs) { lhs *= rhs; return lhs; } friend vec_dimd operator/(vec_dimd lhs, const T &rhs) { lhs /= rhs; return lhs; } friend std::ostream &operator<<(std::ostream &os, const vec_dimd obj) { os << '{'; for(std::size_t i = 0; i < D; i++) os << obj.v[i] << ((i < (D - 1)) ? ',' : '}'); return os; } /*Finds the distance from the origin to the ray cast in D dimension space using components of vec*/ T sqrMagnitude() const { T t{}; for(size_t i = 0; i < D; i++) t += v[i] * v[i]; return t; } T magnitude() const { return std::sqrt(sqrMagnitude()); } /*Finds the dot product of itself and another vec of same T and D*/ T dot(const vec_dimd &b) const { T t; for(size_t i = 0; i < D; i++) t += (v[i] * b.v[i]); return t; } friend T dot(const vec_dimd &lhs, const vec_dimd &rhs) { return lhs.dot(rhs); } vex::vec_dimd normalize() const { return *this / magnitude(); } vex::vec_dimd abs() const { vex::vec_dimd copy(*this); for(unsigned i = 0; i < D; i++) copy.v[i] = std::abs(copy.v[i]); return copy; } auto cross(const vec_dimd &o) const { if constexpr(D == 2) return v[0]*o[0] - v[1]*o[1]; if constexpr(D == 3) return vec_dimd{v[1]*o[2]-v[2]*o[1], v[2]*o[0]-v[0]*o[2],v[0]*o[1]-v[1]*o[0]}; } }; template using vec2 = vec_dimd; template using vec3 = vec_dimd; /*(x, y) -> (r, theta)*/ template static vec2 polar(const vec2

&in) { return vec2( std::sqrt(in[0] * in[0] + in[1] * in[1]), std::atan2(in[1], in[0]) ); } /*(r, theta) -> (x, y)*/ template static vec2 cartesian(const vec2

&in) { return vec2( (R)(cos(in[1]) * in[0]), (R)(sin(in[1]) * in[0]) ); } }; #endif