diff --git a/Vector2.cpp b/Vector2.cpp index 1e34a99..b8e99f8 100644 --- a/Vector2.cpp +++ b/Vector2.cpp @@ -180,3 +180,93 @@ Vector2 Vector2::Lerp(const Vector2& v1, const Vector2& v2, float f) { Vector2 v = v1 + (v2 - v1) * f; return v; } + +#pragma region Vector2Of + +template +Vector2Of::Vector2Of() {} + +template +Vector2Of::Vector2Of(T horizontal, T vertical) + : horizontal(horizontal), vertical(vertical) {} + +template +const Vector2Of Vector2Of::zero = Vector2Of(T{}, T{}); + +template +float Vector2Of::MagnitudeOf(const Vector2Of& v) { + T sqr = v.horizontal * v.horizontal + v.vertical * v.vertical; + float sqrFloat = static_cast(sqr); + return sqrtf(sqrFloat); +} + +template +float LinearAlgebra::Vector2Of::Magnitude() const { + T sqr = this->horizontal * this->horizontal + this->vertical * this->vertical; + float sqrFloat = static_cast(sqr); + return sqrtf(sqrFloat); +} + +template +Vector2Of Vector2Of::operator-(const Vector2Of& v) const { + return Vector2Of(this->horizontal - v.horizontal, + this->vertical - v.vertical); +} + +template +Vector2Of Vector2Of::operator-=(const Vector2Of& v) { + this->horizontal -= v.horizontal; + this->vertical -= v.vertical; + return *this; +} + +template +Vector2Of Vector2Of::operator+(const Vector2Of& v) const { + return Vector2Of(this->horizontal + v.horizontal, + this->vertical + v.vertical); +} + +template +Vector2Of Vector2Of::operator+=(const Vector2Of& v) { + this->horizontal += v.horizontal; + this->vertical += v.vertical; + return *this; +} + +// template +// Vector2Of Vector2Of::operator/=(float f) { +// this->x /= f; +// this->y /= f; +// return *this; +// } + +template +float Vector2Of::Distance(const Vector2Of& v1, const Vector2Of& v2) { + return MagnitudeOf(v1 - v2); +} + +template +Vector2 Vector2Of::Normalize(const Vector2Of& v) { + float num = Vector2Of::MagnitudeOf(v); + Vector2 result = Vector2::zero; + if (num > Float::epsilon) { + result = v / num; + } + return result; +} + +template +Vector2 Vector2Of::normalized() const { + float num = Vector2Of::MagnitudeOf(*this); + Vector2 result = Vector2::zero; + if (num > Float::epsilon) { + result = *this / num; + } + return result; +} + +// Explicit instantiation for int +template class Vector2Of; +template class Vector2Of; + +#pragma endregion Vector2Of \ No newline at end of file diff --git a/Vector2.h b/Vector2.h index 04fa669..350e96a 100644 --- a/Vector2.h +++ b/Vector2.h @@ -138,9 +138,7 @@ struct Vector2 : Vec2 { /// @return The scaled vector /// @remark Each component of the vector will be multipled with the same /// factor f. - friend Vector2 operator*(const Vector2& v, float f) { - return Vector2(v.x * f, v.y * f); - } + friend Vector2 operator*(const Vector2& v, float f) { return Vector2(v.x * f, v.y * f); } friend Vector2 operator*(float f, const Vector2& v) { return Vector2(v.x * f, v.y * f); // return Vector2(f * v.x, f * v.y); @@ -150,12 +148,8 @@ struct Vector2 : Vec2 { /// @param f The scaling factor /// @return The scaled vector /// @remark Each componet of the vector will be divided by the same factor. - friend Vector2 operator/(const Vector2& v, float f) { - return Vector2(v.x / f, v.y / f); - } - friend Vector2 operator/(float f, const Vector2& v) { - return Vector2(f / v.x, f / v.y); - } + friend Vector2 operator/(const Vector2& v, float f) { return Vector2(v.x / f, v.y / f); } + friend Vector2 operator/(float f, const Vector2& v) { return Vector2(f / v.x, f / v.y); } Vector2 operator/=(float f); /// @brief The dot product of two vectors @@ -201,9 +195,90 @@ struct Vector2 : Vec2 { static Vector2 Lerp(const Vector2& v1, const Vector2& v2, float f); }; +template +class Vector2Of { + public: + /// @brief The distance in the horizontal direction, left = negative, right = positive + T horizontal = T{}; + /// @brief The distance in the vertical direction, down = negative, up = positive + T vertical = T{}; + + /// @brief A new 2-dimensional zero vector + Vector2Of(); + /// @brief A new 2-dimensional vector + /// @param horizontal The distance in the horizontal direction, left = negative, right = + /// positive + /// @param vertical The distance in the vertical direction, down = negative, up = + /// positive + Vector2Of(T horizontal, T vertical); + + /// @brief Converting constructor: allow Vector2Of -> Vector2Of + /// @tparam U + /// @param other + template + constexpr Vector2Of(const Vector2Of& other) noexcept + : horizontal(static_cast(other.horizontal)), vertical(static_cast(other.vertical)) {} + + template + constexpr Vector2Of& operator=(const Vector2Of& other) noexcept { + this.horizontal = static_cast(other.horizontal); + this.vertical = static_cast(other.vertical); + } + + /// @brief A vector with zero for all axis + const static Vector2Of zero; + + /// @brief The vector length + /// @param v The vector for which you need the length + /// @return The vector length + static float MagnitudeOf(const Vector2Of& v); + + /// @brief The vector length + /// @return The vector length + float Magnitude() const; + + /// @brief Subtract a vector from this vector + /// @param v The vector to subtract from this vector + /// @return The result of the subtraction + Vector2Of operator-(const Vector2Of& v) const; + Vector2Of operator-=(const Vector2Of& v); + + /// @brief Add a vector to this vector + /// @param v The vector to add to this vector + /// @return The result of the addition + Vector2Of operator+(const Vector2Of& v) const; + Vector2Of operator+=(const Vector2Of& v); + + /// @brief Scale the vector uniformly down + /// @param f The scaling factor + /// @return The scaled vector + /// @remark Each componet of the vector will be divided by the same factor. + // operator/ for Vector2Of is provided as a free function below (inside namespace) + // Vector2Of operator/=(float f); + + /// @brief The distance between two vectors + /// @param v1 The first vector + /// @param v2 The second vector + /// @return The distance between the two vectors + static float Distance(const Vector2Of& v1, const Vector2Of& v2); + + static Vector2 Normalize(const Vector2Of& v); + /// @brief Convert the vector to a length 1 + /// @return The vector normalized to a length of 1 + Vector2 normalized() const; +}; + +//template class Vector2Of; + +using Vector2Int = Vector2Of; +using Vector2Float = Vector2Of; + +template +inline Vector2 operator/(const Vector2Of& v, float f) { + return Vector2(v.horizontal / f, v.vertical / f); +} + } // namespace LinearAlgebra using namespace LinearAlgebra; -#include "Polar.h" - #endif \ No newline at end of file diff --git a/test/Vector2_test.cc b/test/Vector2_test.cc index 3afeb4b..c453be9 100644 --- a/test/Vector2_test.cc +++ b/test/Vector2_test.cc @@ -4,6 +4,7 @@ #include #include "Vector2.h" +#include "Polar.h" #define FLOAT_INFINITY std::numeric_limits::infinity()