#pragma once #include "Types.hpp" #include "MathF.hpp" #include namespace TSE { class Vector3; class Vector4; class Vector2 { public: #pragma region members float x = 0, y = 0; #pragma endregion members #pragma region consts static const Vector2 left; static const Vector2 right; static const Vector2 up; static const Vector2 down; static const Vector2 one; static const Vector2 zero; #pragma endregion #pragma region ctor /// @brief enpty constructor defined as (0,0) Vector2(); /// @brief constructs a vector2 with custom values /// @param _x the x component /// @param _y the y component Vector2(float _x, float _y); /// @brief copy constructor /// @param other the vector2 to be copied from Vector2(const Vector2& other); /// @brief converter constructor. it converts a Vector3 to a Vector2 without encointing for the z component /// @param other the Vector3 to convert Vector2(const Vector3& other); /// @brief converter constructor. it converts a Vector4 to a Vector2 without encointing for the z, and w component /// @param other the Vector4 to convert Vector2(const Vector4& other); #pragma endregion ctor #pragma region methods /// @brief the length of the vector /// @return the length float Length() const; /// @brief the length² of the vector /// @return the length² float LengthSqr() const; /// @brief checks if the individual components have valid values aka are not nan /// @return are the values valid bool IsValid() const; /// @brief normalizes the Vector2 to have a length of 1 void Normalize(); /// @brief normalizes the Vector2 to have a length of 1. If the current length of the vector is smaller then epsilon, it gives you the fallback value. /// @param fallback the value to set the vector to if the current length is smaller then epsilon void NormalizeSafe(const Vector2& fallback); /// @brief gives you the vector2 as a string representation. mostly for debugging /// @return the vector2 in a format like (x|y) string ToString() const; /// @brief creates a Vector3 with the same values as the Vector2, the y component gets the value 0 /// @return the Vector2 as a Vector3 Vector3 ToVector3() const; /// @brief creates a Vector4 with the same values as the Vector2, the y and w components get the value 0 /// @return the Vector2 as a Vector4 Vector4 ToVector4() const; #pragma region static /// @brief gives you the distance between two vectors. /// @param a point 1 /// @param b point 2 /// @return the distance between point 1 and point 2 static float Distance(const Vector2& a, const Vector2& b); /// @brief gives you the distance² between two vectors. /// @param a point 1 /// @param b point 2 /// @return the distance² between point 1 and point 2 static float DistanceSqr(const Vector2& a, const Vector2& b); /// @brief normalizes a copy of the Vector2 to have a length of 1 /// @param v the vector to be normaliezed /// @return a normalies copy of the vector static Vector2 Normalize(const Vector2& v); /// @brief normalizes a copy of the Vector2 to have a length of 1. If the current length of the vector is smaller then epsilon, it gives you the fallback value. /// @param fallback the value to set the vector to if the current length is smaller then epsilon /// @param v the vector to be normaliezed /// @return a normalies copy of the vector static Vector2 NormalizeSafe(const Vector2& v, const Vector2& fallback); /// @brief linearly interpolates between two points using t /// @param a point 1 /// @param b point 2 /// @param t the amoint to interpolate by /// @return the interpolated point static Vector2 Lerp(const Vector2& a, const Vector2& b, float t); /// @brief bezier interpolation using three points using t /// @param a point 1 /// @param b controll point /// @param c point 2 /// @param t the amoint to interpolate by /// @return the interpolated point static Vector2 Berp(const Vector2& a, const Vector2& b, const Vector2& c, float t); /// @brief gives you the midpoint between two points /// @param a point 1 /// @param b point 2 /// @return the midpoint static Vector2 Midpoint(const Vector2& a, const Vector2& b); /// @brief gives you the dot product between to vectors /// @param a vector 1 /// @param b vector 2 /// @return the dot product static float Dot(const Vector2& a, const Vector2& b); /// @brief it gives you the "2D Cross Product" (there is no real 2D Cross product, but this function is still usefull sometimes) /// @param a vector 1 /// @param b vector 2 /// @return 2D cross product static float Cross(const Vector2& a, const Vector2& b); #pragma endregion static #pragma region operators Vector2 operator+(const Vector2& other) const; Vector2 operator+=(const Vector2& other); Vector2 operator-(const Vector2& other) const; Vector2 operator-=(const Vector2& other); Vector2 operator*(const Vector2& other) const; Vector2 operator*=(const Vector2& other); Vector2 operator/(const Vector2& other) const; Vector2 operator/=(const Vector2& other); Vector2 operator*(const float other) const; Vector2 operator*=(const float other); Vector2 operator/(const float other) const; Vector2 operator/=(const float other); bool operator==(const Vector2& other) const; bool operator!=(const Vector2& other) const; #pragma endregion operators #pragma endregion methods }; } // namespace TSE namespace std { template<> struct hash { size_t operator()(const TSE::Vector2& v) const noexcept { size_t h1 = std::hash{}(v.x); size_t h2 = std::hash{}(v.y); return h1 ^ (h2 + TSE::TSE_HASH_GOLDEN_RATIO_32 + (h1 << 6) + (h1 >> 2)); } }; }