#pragma once #include #include #include namespace J3ML::LinearAlgebra { using namespace J3ML; /// A 2D (x, y) ordered pair. class Vector2 { public: /// Default Constructor - Initializes values to zero Vector2(); /// Constructs a new Vector2 with the value (X, Y) Vector2(float X, float Y); Vector2(const Vector2& rhs); // Copy Constructor //Vector2(Vector2&&) = default; // Move Constructor static const Vector2 Zero; static const Vector2 Up; static const Vector2 Left; static const Vector2 Down; static const Vector2 Right; static const Vector2 NaN; float GetX() const; float GetY() const; void SetX(float newX); void SetY(float newY); bool IsWithinMarginOfError(const Vector2& rhs, float margin=0.001f) const; bool IsNormalized(float epsilonSq = 1e-5f) const; bool IsZero(float epsilonSq = 1e-6f) const; bool IsPerpendicular(const Vector2& other, float epsilonSq=1e-5f) const; float operator[](std::size_t index); bool operator == (const Vector2& rhs) const; bool operator != (const Vector2& rhs) const; Vector2 Min(const Vector2& min) const; static Vector2 Min(const Vector2& value, const Vector2& minimum); Vector2 Max(const Vector2& max) const; static Vector2 Max(const Vector2& value, const Vector2& maximum); Vector2 Clamp(const Vector2& min, const Vector2& max) const; static Vector2 Clamp(const Vector2& min, const Vector2& middle, const Vector2& max); /// Returns the magnitude between the two vectors. float Distance(const Vector2& to) const; static float Distance(const Vector2& from, const Vector2& to); float DistanceSq(const Vector2& to) const; static float DistanceSq(const Vector2& from, const Vector2& to); float MinElement() const; float MaxElement() const; float Length() const; static float Length(const Vector2& of); float LengthSquared() const; static float LengthSquared(const Vector2& of); /// Returns the length of the vector, which is sqrt(x^2 + y^2) float Magnitude() const; static float Magnitude(const Vector2& of); bool IsFinite() const; static bool IsFinite(const Vector2& v); /// Returns a float value equal to the magnitudes of the two vectors multiplied together and then multiplied by the cosine of the angle between them. /// For normalized vectors, dot returns 1 if they point in exactly the same direction, /// -1 if they point in completely opposite directions, and 0 if the vectors are perpendicular. float Dot(const Vector2& rhs) const; static float Dot(const Vector2& lhs, const Vector2& rhs); /// Projects one vector onto another and returns the result. (IDK) Vector2 Project(const Vector2& rhs) const; /// @see Project static Vector2 Project(const Vector2& lhs, const Vector2& rhs); /// Returns a copy of this vector, resized to have a magnitude of 1, while preserving "direction" Vector2 Normalize() const; static Vector2 Normalize(const Vector2& of); /// Linearly interpolates between two points. /// Interpolates between the points and b by the interpolant t. /// The parameter is (TODO: SHOULD BE!) clamped to the range[0, 1]. /// This is most commonly used to find a point some fraction of the wy along a line between two endpoints (eg. to move an object gradually between those points). Vector2 Lerp(const Vector2& rhs, float alpha) const; /// @see Lerp static Vector2 Lerp(const Vector2& lhs, const Vector2& rhs, float alpha); /// Note: Input vectors MUST be normalized first! float AngleBetween(const Vector2& rhs) const; static float AngleBetween(const Vector2& lhs, const Vector2& rhs); /// Adds two vectors. Vector2 operator +(const Vector2& rhs) const; Vector2 Add(const Vector2& rhs) const; static Vector2 Add(const Vector2& lhs, const Vector2& rhs); /// Subtracts two vectors. Vector2 operator -(const Vector2& rhs) const; Vector2 Sub(const Vector2& rhs) const; static Vector2 Sub(const Vector2& lhs, const Vector2& rhs); /// Multiplies this vector by a scalar value. Vector2 operator *(float rhs) const; Vector2 Mul(float scalar) const; static Vector2 Mul(const Vector2& lhs, float rhs); /// Multiplies this vector by a vector, element-wise /// @note Mathematically, the multiplication of two vectors is not defined in linear space structures, /// but this function is provided here for syntactical convenience. Vector2 operator *(const Vector2& rhs) const { } Vector2 Mul(const Vector2& v) const; /// Divides this vector by a scalar. Vector2 operator /(float rhs) const; Vector2 Div(float scalar) const; static Vector2 Div(const Vector2& lhs, float rhs); /// Divides this vector by a vector, element-wise /// @note Mathematically, the multiplication of two vectors is not defined in linear space structures, /// but this function is provided here for syntactical convenience Vector2 Div(const Vector2& v) const; /// Unary operator + Vector2 operator +() const; // TODO: Implement Vector2 operator -() const; /// Assigns a vector to another Vector2& operator+=(const Vector2& rhs); // Adds a vector to this vector, in-place. Vector2& operator-=(const Vector2& rhs); // Subtracts a vector from this vector, in-place Vector2& operator*=(float scalar); Vector2& operator/=(float scalar); public: float x = 0; float y = 0; }; static Vector2 operator*(float lhs, const Vector2 &rhs) { return rhs * lhs; } }