Files
TSE/TSE_Math/src/Vector2.hpp

154 lines
6.4 KiB
C++

#pragma once
#include "Types.hpp"
#include "MathF.hpp"
#include <functional>
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<TSE::Vector2>
{
size_t operator()(const TSE::Vector2& v) const noexcept
{
size_t h1 = std::hash<float>{}(v.x);
size_t h2 = std::hash<float>{}(v.y);
return h1 ^ (h2 + TSE::TSE_HASH_GOLDEN_RATIO_32 + (h1 << 6) + (h1 >> 2));
}
};
}