Created
October 13, 2023 22:20
-
-
Save W4RH4WK/962a181472c941285e4866b698207d84 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////////////////////////////////////////////// | |
// Vector 2D | |
template <typename T> | |
struct Vec2T { | |
constexpr Vec2T() = default; | |
constexpr Vec2T(T v) : x(v), y(v) {} | |
constexpr Vec2T(T x, T y) : x(x), y(y) {} | |
constexpr Vec2T(const Vec2T&) = default; | |
constexpr Vec2T& operator=(const Vec2T&) = default; | |
constexpr Vec2T(Vec2T&&) noexcept = default; | |
constexpr Vec2T& operator=(Vec2T&&) noexcept = default; | |
constexpr Vec2T(glm::vec<2, T> v) : x(v.x), y(v.y) {} | |
constexpr operator glm::vec<2, T>() const { return {x, y}; } | |
constexpr Vec2T(b2Vec2 v) requires(std::is_same_v<T, float>) : x(v.x), y(v.y) {} | |
constexpr operator b2Vec2() const requires(std::is_same_v<T, float>) { return {x, y}; } | |
template <typename TT> | |
explicit constexpr operator Vec2T<TT>() const | |
{ | |
return {TT(x), TT(y)}; | |
} | |
constexpr double length() const { return glm::length(glm::vec<2, T>(*this)); } | |
constexpr double lengthSquared() const { return glm::length2(glm::vec<2, T>(*this)); } | |
constexpr double ratio() const { return double(x) / double(y); } | |
constexpr Vec2T& clampLength(double maximum) | |
{ | |
if (lengthSquared() > maximum * maximum) { | |
auto l = length(); | |
x = T(maximum * x / l); | |
y = T(maximum * y / l); | |
} | |
return *this; | |
} | |
constexpr Vec2T& rotate(T angle) { return *this = glm::rotate(glm::vec<2, T>(*this), angle); } | |
constexpr Vec2T& moveTowards(Vec2T target, Vec2T speed, float dt, T epsilon = T(1e-6)) | |
{ | |
x = Anker::moveTowards(x, target.x, speed.x, dt, epsilon); | |
y = Anker::moveTowards(y, target.y, speed.y, dt, epsilon); | |
return *this; | |
} | |
friend constexpr auto operator<=>(Vec2T, Vec2T) = default; | |
T x = 0; | |
T y = 0; | |
static const Vec2T Up, Down, Left, Right; | |
static const Vec2T WorldUp, WorldDown, WorldLeft, WorldRight; | |
}; | |
// Default coordinate system: -Y is up | |
template <typename T> | |
const Vec2T<T> Vec2T<T>::Up{0, -1}; | |
template <typename T> | |
const Vec2T<T> Vec2T<T>::Down{0, 1}; | |
template <typename T> | |
const Vec2T<T> Vec2T<T>::Left{-1, 0}; | |
template <typename T> | |
const Vec2T<T> Vec2T<T>::Right{1, 0}; | |
// World coordinate system: +Y is up | |
template <typename T> | |
const Vec2T<T> Vec2T<T>::WorldUp{0, 1}; | |
template <typename T> | |
const Vec2T<T> Vec2T<T>::WorldDown{0, -1}; | |
template <typename T> | |
const Vec2T<T> Vec2T<T>::WorldLeft{-1, 0}; | |
template <typename T> | |
const Vec2T<T> Vec2T<T>::WorldRight{1, 0}; | |
template <typename T> | |
constexpr T dot(Vec2T<T> a, Vec2T<T> b) | |
{ | |
return a.x * b.x + a.y * b.y; | |
} | |
template <typename T> | |
constexpr Vec2T<T>& operator+=(Vec2T<T>& a, Vec2T<T> b) | |
{ | |
a.x += b.x; | |
a.y += b.y; | |
return a; | |
} | |
template <typename T> | |
constexpr Vec2T<T>& operator-=(Vec2T<T>& a, Vec2T<T> b) | |
{ | |
a.x -= b.x; | |
a.y -= b.y; | |
return a; | |
} | |
template <typename T, typename C> | |
constexpr Vec2T<T>& operator*=(Vec2T<T>& v, C c) | |
{ | |
v.x *= c; | |
v.y *= c; | |
return v; | |
} | |
template <typename T> | |
constexpr Vec2T<T>& operator*=(Vec2T<T>& a, Vec2T<T> b) | |
{ | |
a.x *= b.x; | |
a.y *= b.y; | |
return a; | |
} | |
template <typename T, typename C> | |
constexpr Vec2T<T>& operator/=(Vec2T<T>& v, C c) | |
{ | |
v.x /= c; | |
v.y /= c; | |
return v; | |
} | |
template <typename T> | |
constexpr Vec2T<T>& operator/=(Vec2T<T>& a, Vec2T<T> b) | |
{ | |
a.x /= b.x; | |
a.y /= b.y; | |
return a; | |
} | |
// clang-format off | |
template <typename T> | |
constexpr Vec2T<T> operator-(Vec2T<T> v) { return {-v.x, -v.y}; } | |
template <typename T> | |
constexpr Vec2T<T> operator+(Vec2T<T> a, Vec2T<T> b) { return a += b; } | |
template <typename T> | |
constexpr Vec2T<T> operator-(Vec2T<T> a, Vec2T<T> b) { return a -= b; } | |
template <typename T, typename C> | |
constexpr Vec2T<T> operator*(C c, Vec2T<T> v) { return v *= c; } | |
template <typename T, typename C> | |
constexpr Vec2T<T> operator*(Vec2T<T> v, C c) { return v *= c; } | |
template <typename T> | |
constexpr Vec2T<T> operator*(Vec2T<T> a, Vec2T<T> b) { return a *= b; } | |
template <typename T, typename C> | |
constexpr Vec2T<T> operator/(Vec2T<T> v, C c) { return v /= c; } | |
template <typename T, typename C> | |
constexpr Vec2T<T> operator/(C c, Vec2T<T> v) { return {c / v.x, c / v.y}; } | |
template <typename T> | |
constexpr Vec2T<T> operator/(Vec2T<T> a, Vec2T<T> b) { return a /= b; } | |
// clang-format on | |
using Vec2 = Vec2T<float>; | |
using Vec2i = Vec2T<int>; | |
using Vec2u = Vec2T<unsigned>; | |
using Vec2d = Vec2T<double>; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment