Initial commit
This commit is contained in:
237
inc/EliteMath/EVector2.h
Normal file
237
inc/EliteMath/EVector2.h
Normal file
@@ -0,0 +1,237 @@
|
||||
/*=============================================================================*/
|
||||
// Copyright 2021-2022 Elite Engine
|
||||
// Authors: Matthieu Delaere
|
||||
/*=============================================================================*/
|
||||
// EVector2.h: Vector2D struct
|
||||
/*=============================================================================*/
|
||||
#ifndef ELITE_MATH_VECTOR2
|
||||
#define ELITE_MATH_VECTOR2
|
||||
namespace Elite
|
||||
{
|
||||
#define ZeroVector2 Vector2()
|
||||
#define UnitVector2 Vector2(1.f,1.f)
|
||||
|
||||
//Vector 2D
|
||||
struct Vector2
|
||||
{
|
||||
//=== Datamembers ===
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
|
||||
//=== Constructors ===
|
||||
Vector2() = default;
|
||||
Vector2(float _x, float _y) :x(_x), y(_y) {};
|
||||
|
||||
//=== Vector Conversions Functions ===
|
||||
#ifdef USE_BOX2D
|
||||
explicit Vector2(const b2Vec2& v) : x(v.x), y(v.y) {};
|
||||
Vector2& operator=(const b2Vec2& v) { x = v.x; y = v.y; return *this; }
|
||||
operator b2Vec2() const
|
||||
{return {x, y};};
|
||||
#endif
|
||||
|
||||
//=== Arithmetic Operators ===
|
||||
inline auto operator-(const Vector2& v) const
|
||||
{ return Vector2(x - v.x, y - v.y); }
|
||||
inline auto operator-() const
|
||||
{ return Vector2(-x, -y); }
|
||||
inline auto operator*(float scale) const
|
||||
{ return Vector2(x * scale, y * scale); }
|
||||
inline auto operator/(float scale) const
|
||||
{
|
||||
const auto revScale = 1.0f / scale;
|
||||
return Vector2(x * revScale, y * revScale);
|
||||
}
|
||||
|
||||
//=== Compound Assignment Operators === //auto& for type deduction
|
||||
inline auto& operator+=(const Vector2& v)
|
||||
{ x += v.x; y += v.y; return *this; }
|
||||
inline auto& operator-=(const Vector2& v)
|
||||
{ x -= v.x; y -= v.y; return *this; }
|
||||
inline auto& operator*=(float scale)
|
||||
{ x *= scale; y *= scale; return *this; }
|
||||
inline auto& operator/=(float scale)
|
||||
{
|
||||
const auto revScale = 1.0f / scale;
|
||||
x *= revScale; y *= revScale; return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=== Relational Operators ===
|
||||
inline auto operator==(const Vector2& v) const /*Check if both components are equal*/
|
||||
{ return AreEqual(x, v.x) && AreEqual(y, v.y); }
|
||||
inline auto operator!=(const Vector2& v) const /*Check if one or both components are NOT equal*/
|
||||
{ return !(*this == v); }
|
||||
|
||||
//=== Member Access Operators ===
|
||||
inline float operator[](unsigned int i) const
|
||||
{
|
||||
return ((i == 0) ? x : y);
|
||||
//if (i >= 0 && i < 2)
|
||||
// return ((i == 0) ? x : y);
|
||||
//throw; /*TODO : specify error thrown;*/
|
||||
}
|
||||
inline float& operator[](unsigned int i)
|
||||
{
|
||||
return ((i == 0) ? x : y);
|
||||
//if (i >= 0 && i < 2)
|
||||
// return ((i == 0) ? x : y);
|
||||
//throw; /*TODO : specify error thrown;*/
|
||||
}
|
||||
|
||||
//=== Internal Vector Functions ===
|
||||
inline auto Dot(const Vector2& v) const
|
||||
{ return x * v.x + y * v.y; }
|
||||
|
||||
inline auto Cross(const Vector2& v) const
|
||||
{ return x * v.y - y * v.x; }
|
||||
|
||||
inline auto GetAbs() const
|
||||
{ return Vector2(abs(x), abs(y)); }
|
||||
|
||||
inline auto MagnitudeSquared() const
|
||||
{ return x*x + y*y; }
|
||||
|
||||
inline auto Magnitude() const
|
||||
{ return sqrtf(MagnitudeSquared()); }
|
||||
|
||||
inline float Normalize()
|
||||
{
|
||||
auto m = Magnitude();
|
||||
if (AreEqual(m, 0.f))
|
||||
{
|
||||
*this = ZeroVector2;
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
auto invM = 1.f / m;
|
||||
x *= invM;
|
||||
y *= invM;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline Vector2 GetNormalized() const /*! Returns a normalized copy of this vector. This vector does not change.*/
|
||||
{
|
||||
auto v = Vector2(*this);
|
||||
v.Normalize();
|
||||
return v;
|
||||
}
|
||||
|
||||
inline auto DistanceSquared(const Vector2& v) const
|
||||
{ return Square(v.x - x) + Square(v.y - y); }
|
||||
|
||||
inline auto Distance(const Vector2& v) const
|
||||
{ return sqrtf(DistanceSquared(v)); }
|
||||
|
||||
inline auto Clamp(float max)
|
||||
{
|
||||
auto scale = max / Magnitude();
|
||||
scale = scale < 1.f ? scale : 1.f;
|
||||
return *this * scale;
|
||||
}
|
||||
};
|
||||
|
||||
//=== Global Vector Operators ===
|
||||
#pragma region GlobalVectorOperators
|
||||
inline auto operator+(const Vector2& v, const Vector2& v2)
|
||||
{ return Vector2(v.x + v2.x, v.y + v2.y); }
|
||||
|
||||
inline auto operator* (float s, const Vector2& v)
|
||||
{ return Vector2(s * v.x, s * v.y); }
|
||||
|
||||
inline auto operator*(const Vector2& a, const Vector2& b)
|
||||
{ return Vector2(a.x*b.x, a.y*b.y); }
|
||||
|
||||
inline auto operator/ (float s, const Vector2& v)
|
||||
{
|
||||
const auto revScale = 1.0f / s;
|
||||
return Vector2(revScale * v.x, revScale * v.y);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Vector2& rhs)
|
||||
{
|
||||
os << "(" << rhs.x << ", " << rhs.y << " )";
|
||||
return os;
|
||||
}
|
||||
#pragma endregion //GlobalVectorOperators
|
||||
|
||||
//=== Global Vector Functions ===
|
||||
#pragma region GlobalVectorFunctions
|
||||
inline auto Dot(const Vector2& v1, const Vector2& v2)
|
||||
{ return v1.Dot(v2); }
|
||||
|
||||
inline auto Cross(const Vector2& v1, const Vector2& v2)
|
||||
{ return v1.Cross(v2); }
|
||||
|
||||
inline auto GetAbs(const Vector2& v)
|
||||
{ return v.GetAbs(); }
|
||||
|
||||
inline void Abs(Vector2& v) /*! Make absolute Vector2 of this Vector2 */
|
||||
{ v = v.GetAbs(); }
|
||||
|
||||
inline void Normalize(Vector2& v)
|
||||
{ v.Normalize(); }
|
||||
|
||||
inline auto GetNormalized(const Vector2& v)
|
||||
{ return v.GetNormalized(); }
|
||||
|
||||
inline auto DistanceSquared(const Vector2& v1, const Vector2& v2)
|
||||
{ return v1.DistanceSquared(v2); }
|
||||
|
||||
inline auto Distance(const Vector2& v1, const Vector2& v2)
|
||||
{ return v1.Distance(v2); }
|
||||
|
||||
inline auto Clamp(const Vector2& v, float max)
|
||||
{
|
||||
auto scale = max / v.Magnitude();
|
||||
scale = scale < 1.f ? scale : 1.f;
|
||||
return v * scale;
|
||||
}
|
||||
#pragma endregion //GlobalVectorFunctions
|
||||
|
||||
#pragma region ExtraFunctions
|
||||
/*! Random Vector2 */
|
||||
inline Vector2 randomVector2(float max = 1.f)
|
||||
{
|
||||
return{ randomBinomial(max),randomBinomial(max) };
|
||||
}
|
||||
inline Vector2 randomVector2(float min, float max)
|
||||
{
|
||||
return{ randomFloat(min, max),randomFloat(min, max) };
|
||||
}
|
||||
|
||||
/* Get orientation from an a velocity vector
|
||||
-- [Deprecated] -- Use VectorToAngle instead*/
|
||||
[[deprecated("Use VectorToOrientation instead")]]
|
||||
inline float GetOrientationFromVelocity(const Elite::Vector2& velocity)
|
||||
{
|
||||
if (velocity.Magnitude() == 0)
|
||||
return 0.f;
|
||||
|
||||
return atan2f(velocity.x, -velocity.y);
|
||||
}
|
||||
|
||||
/* Creates a normalized vector from an angle in radians. */
|
||||
inline Vector2 OrientationToVector(float orientation)
|
||||
{
|
||||
return Vector2(cos(orientation), sin(orientation));
|
||||
}
|
||||
|
||||
/*Calculates the orientation angle from a vector*/
|
||||
inline float VectorToOrientation(const Vector2& vector)
|
||||
{
|
||||
return atan2f(vector.y, vector.x);
|
||||
}
|
||||
|
||||
/*! Get Angle Between 2 vectors*/
|
||||
inline float AngleBetween(const Elite::Vector2& v1, const Elite::Vector2& v2) {
|
||||
float x = v1.Dot(v2);
|
||||
float y = v1.Cross(v2);
|
||||
return atan2(y, x);
|
||||
}
|
||||
|
||||
#pragma endregion //ExtraFunctions
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user