From a2ba625bac6056fea8db1777993ad8d88312b961 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Fri, 19 Dec 2025 17:19:45 +0100 Subject: [PATCH] Disabled old Vector2 implementation --- Polar.cpp | 7 +- Polar.h | 5 +- Vector2.cpp | 128 ++++++++++++++++++++++++++++++-- Vector2.h | 170 ++++++++++++++++++++++++++++++++++++------- Vector3.cpp | 10 +-- Vector3.h | 3 +- test/Polar_test.cc | 2 + test/Vector2_test.cc | 106 ++++++++++++++------------- 8 files changed, 333 insertions(+), 98 deletions(-) diff --git a/Polar.cpp b/Polar.cpp index 15ac40f..46c1842 100644 --- a/Polar.cpp +++ b/Polar.cpp @@ -37,10 +37,9 @@ PolarOf PolarOf::Radians(float distance, float radians) { } template -PolarOf PolarOf::FromVector2(Vector2 v) { - float distance = v.magnitude(); - AngleOf angle = - AngleOf::Degrees(Vector2::SignedAngle(Vector2::forward, v)); +PolarOf PolarOf::FromVector2(Vector2Of v) { + float distance = v.Magnitude(); + AngleOf angle = Vector2Of::SignedAngle(Vector2Of::forward, v); PolarOf p = PolarOf(distance, angle); return p; } diff --git a/Polar.h b/Polar.h index 541bec8..728f9f2 100644 --- a/Polar.h +++ b/Polar.h @@ -9,7 +9,8 @@ namespace LinearAlgebra { -struct Vector2; +template +class Vector2Of; template class SphericalOf; @@ -55,7 +56,7 @@ class PolarOf { /// @brief Convert a vector from 2D carthesian coordinates to polar /// coordinates /// @param v The vector to convert - static PolarOf FromVector2(Vector2 v); + static PolarOf FromVector2(Vector2Of v); /// @brief Convert a vector from spherical coordinates to polar coordinates /// @param s The vector to convert /// @note The resulting vector will be projected on the horizontal plane diff --git a/Vector2.cpp b/Vector2.cpp index b8e99f8..f703900 100644 --- a/Vector2.cpp +++ b/Vector2.cpp @@ -13,6 +13,7 @@ #include // #endif +/* Vector2::Vector2() { x = 0; y = 0; @@ -180,6 +181,7 @@ Vector2 Vector2::Lerp(const Vector2& v1, const Vector2& v2, float f) { Vector2 v = v1 + (v2 - v1) * f; return v; } + */ #pragma region Vector2Of @@ -190,9 +192,29 @@ template Vector2Of::Vector2Of(T horizontal, T vertical) : horizontal(horizontal), vertical(vertical) {} +template +Vector2Of Vector2Of::FromPolar(PolarOf p) { + float horizontalRad = p.angle.InDegrees() * Deg2Rad; + float cosHorizontal = cosf(horizontalRad); + float sinHorizontal = sinf(horizontalRad); + + Vector2Of v; + v.horizontal = p.distance * sinHorizontal; + v.vertical = p.distance * cosHorizontal; + return v; +} + template const Vector2Of Vector2Of::zero = Vector2Of(T{}, T{}); +template +const Vector2Of Vector2Of::forward = Vector2Of(T{}, 1); + +template +bool LinearAlgebra::Vector2Of::operator==(const Vector2Of& v) { + return (this->horizontal == v.horizontal && this->vertical == v.vertical); +} + template float Vector2Of::MagnitudeOf(const Vector2Of& v) { T sqr = v.horizontal * v.horizontal + v.vertical * v.vertical; @@ -201,12 +223,29 @@ float Vector2Of::MagnitudeOf(const Vector2Of& v) { } template -float LinearAlgebra::Vector2Of::Magnitude() const { +float Vector2Of::Magnitude() const { T sqr = this->horizontal * this->horizontal + this->vertical * this->vertical; float sqrFloat = static_cast(sqr); return sqrtf(sqrFloat); } +template +float Vector2Of::SqrMagnitudeOf(const Vector2Of& v) { + T sqr = v.horizontal * v.horizontal + v.vertical * v.vertical; + return static_cast(sqr); +} + +template +float Vector2Of::SqrMagnitude() const { + T sqr = this->horizontal * this->horizontal + this->vertical * this->vertical; + return static_cast(sqr); +} + +template +Vector2Of Vector2Of::operator-() { + return Vector2Of(-this->horizontal, -this->vertical); +} + template Vector2Of Vector2Of::operator-(const Vector2Of& v) const { return Vector2Of(this->horizontal - v.horizontal, @@ -233,6 +272,11 @@ Vector2Of Vector2Of::operator+=(const Vector2Of& v) { return *this; } +template +Vector2Of Vector2Of::Scale(const Vector2Of& v1, const Vector2Of& v2) { + return Vector2Of(v1.horizontal * v2.horizontal, v1.vertical * v2.vertical); +} + // template // Vector2Of Vector2Of::operator/=(float f) { // this->x /= f; @@ -240,33 +284,101 @@ Vector2Of Vector2Of::operator+=(const Vector2Of& v) { // return *this; // } +template +T Vector2Of::Dot(const Vector2Of& v1, const Vector2Of& v2) { + return v1.horizontal * v2.horizontal + v1.vertical * v2.vertical; +} + template float Vector2Of::Distance(const Vector2Of& v1, const Vector2Of& v2) { return MagnitudeOf(v1 - v2); } template -Vector2 Vector2Of::Normalize(const Vector2Of& v) { +Vector2Of Vector2Of::Normalize(const Vector2Of& v) { float num = Vector2Of::MagnitudeOf(v); - Vector2 result = Vector2::zero; + Vector2Of result = Vector2Of::zero; if (num > Float::epsilon) { - result = v / num; + result = static_cast>(v) / num; } return result; } template -Vector2 Vector2Of::normalized() const { +AngleOf Vector2Of::UnsignedAngle(const Vector2Of& v1, + const Vector2Of& v2) { + return AngleOf::Abs(SignedAngle(v1, v2)); +} + +template +AngleOf Vector2Of::SignedAngle(const Vector2Of& v1, const Vector2Of& v2) { + float sqrMagFrom = v1.SqrMagnitude(); + float sqrMagTo = v2.SqrMagnitude(); + + if (sqrMagFrom == 0 || sqrMagTo == 0) + return AngleOf::zero; + if (!isfinite(sqrMagFrom) || !isfinite(sqrMagTo)) + return AngleOf::zero; // Angle does not support NaN... + + AngleOf angleFrom = AngleOf::Atan2(static_cast(v1.vertical), + static_cast(v1.horizontal)); + AngleOf angleTo = AngleOf::Atan2(static_cast(v2.vertical), + static_cast(v2.horizontal)); + return -(angleTo - angleFrom); +} + +template +Vector2Of Vector2Of::Rotate(const Vector2Of& v, AngleOf a) { + float sinValue = AngleOf::Sin(a); + float cosValue = AngleOf::Cos(a); + float tx = static_cast(v.horizontal); + float ty = static_cast(v.vertical); + Vector2Of r = Vector2Of((cosValue * tx) - (sinValue * ty), + (sinValue * tx) + (cosValue * ty)); + return r; +} + +template +Vector2Of Vector2Of::Lerp(const Vector2Of& v1, + const Vector2Of& v2, + float f) { + Vector2Of v = v1 + static_cast>(v2 - v1) * f; + return v; +} + +// float Vector2::Angle(const Vector2& v1, const Vector2& v2) { +// return (float)fabs(SignedAngle(v1, v2)); +// } +// float Vector2::SignedAngle(const Vector2& v1, const Vector2& v2) { +// float sqrMagFrom = v1.sqrMagnitude(); +// float sqrMagTo = v2.sqrMagnitude(); + +// if (sqrMagFrom == 0 || sqrMagTo == 0) +// return 0; +// if (!isfinite(sqrMagFrom) || !isfinite(sqrMagTo)) +// #if defined(AVR) +// return NAN; +// #else +// return nanf(""); +// #endif + +// float angleFrom = atan2f(v1.y, v1.x); +// float angleTo = atan2f(v2.y, v2.x); +// return -(angleTo - angleFrom) * Rad2Deg; +// } + +template +Vector2Of Vector2Of::Normalized() const { float num = Vector2Of::MagnitudeOf(*this); - Vector2 result = Vector2::zero; + Vector2Of result = Vector2Of::zero; if (num > Float::epsilon) { - result = *this / num; + result = static_cast>(*this) / num; } return result; } // Explicit instantiation for int -template class Vector2Of; +template class Vector2Of; template class Vector2Of; #pragma endregion Vector2Of \ No newline at end of file diff --git a/Vector2.h b/Vector2.h index 350e96a..6267660 100644 --- a/Vector2.h +++ b/Vector2.h @@ -7,6 +7,7 @@ #include "Angle.h" +/* extern "C" { /// /// 2-dimensional Vector representation (C-style) @@ -25,13 +26,14 @@ typedef struct Vec2 { } Vec2; } - +*/ namespace LinearAlgebra { -struct Vector3; +// struct Vector3; template class PolarOf; +/* /// @brief A 2-dimensional vector /// @remark This uses the right=handed carthesian coordinate system. /// @note This implementation intentionally avoids the use of x and y @@ -138,9 +140,9 @@ 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*(float f, const Vector2& v) { - 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); } Vector2 operator*=(float f); @@ -148,9 +150,9 @@ 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); } - Vector2 operator/=(float 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(f / v.x, f / v.y); } Vector2 operator/=(float f); /// @brief The dot product of two vectors /// @param v1 The first vector @@ -194,30 +196,35 @@ struct Vector2 : Vec2 { /// between *v1* and *v2* etc. 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 + /// @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 + /// @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 + /// @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); + static Vector2Of FromPolar(PolarOf v); + /// @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)) {} + : horizontal(static_cast(other.horizontal)), + vertical(static_cast(other.vertical)) {} template constexpr Vector2Of& operator=(const Vector2Of& other) noexcept { @@ -227,16 +234,42 @@ class Vector2Of { /// @brief A vector with zero for all axis const static Vector2Of zero; + /// @brief A normalized forward-oriented vector + const static Vector2Of forward; + + /// @brief Check if this vector to the given vector + /// @param v The vector to check against + /// @return true if it is identical to the given vector + /// @note This uses float comparison to check equality which may have strange + /// effects. Equality on floats should be avoided. + bool operator==(const Vector2Of& v); /// @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 The squared vector length + /// @param v The vector for which you need the squared length + /// @return The squared vector length + /// @remark The squared length is computationally simpler than the real + /// length. Think of Pythagoras A^2 + B^2 = C^2. This prevents the calculation + /// of the squared root of C. + static float SqrMagnitudeOf(const Vector2Of& v); + /// @brief The squared vector length + /// @return The squared vector length + /// @remark The squared length is computationally simpler than the real + /// length. Think of Pythagoras A^2 + B^2 = C^2. This prevents the calculation + /// of the squared root of C. + float SqrMagnitude() const; + + /// @brief Negate the vector such that it points in the opposite direction + /// @return The negated vector + Vector2Of operator-(); + /// @brief Subtract a vector from this vector /// @param v The vector to subtract from this vector /// @return The result of the subtraction @@ -249,12 +282,38 @@ class Vector2Of { Vector2Of operator+(const Vector2Of& v) const; Vector2Of operator+=(const Vector2Of& v); + /// @brief Scale the vector using another vector + /// @param v1 The vector to scale + /// @param v2 A vector with the scaling factors + /// @return The scaled vector + /// @remark Each component of the vector v1 will be multiplied with the + /// matching component from the scaling vector v2. + static Vector2Of Scale(const Vector2Of& v1, const Vector2Of& v2); + + /// @brief Scale the vector uniformly up + /// @param f The scaling factor + /// @return The scaled vector + /// @remark Each component of the vector will be multiplied by the same + /// factor. + template + friend Vector2Of operator*(const Vector2Of& m, U f); + template + friend Vector2Of operator*(U f, const Vector2Of& m); + /// @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); + /// @remark Each component of the vector will be divided by the same factor. + template + friend Vector2Of operator/(const Vector2Of& m, U f); + template + friend Vector2Of operator/(U f, const Vector2Of& m); + + /// @brief The dot product of two vectors + /// @param v1 The first vector + /// @param v2 The second vector + /// @return The dot product of the two vectors + static T Dot(const Vector2Of& v1, const Vector2Of& v2); /// @brief The distance between two vectors /// @param v1 The first vector @@ -262,23 +321,78 @@ class Vector2Of { /// @return The distance between the two vectors static float Distance(const Vector2Of& v1, const Vector2Of& v2); - static Vector2 Normalize(const Vector2Of& v); + static Vector2Of Normalize(const Vector2Of& v); /// @brief Convert the vector to a length 1 /// @return The vector normalized to a length of 1 - Vector2 normalized() const; + Vector2Of Normalized() const; + + /// @brief The angle between two vectors + /// @param v1 The first vector + /// @param v2 The second vector + /// @return The angle between the two vectors + /// @remark This reterns an unsigned angle which is the shortest distance + /// between the two vectors. Use Vector2::SignedAngle if a signed angle is + /// needed. + static AngleOf UnsignedAngle(const Vector2Of& v1, const Vector2Of& v2); + /// @brief The signed angle between two vectors + /// @param v1 The starting vector + /// @param v2 The ending vector + /// @return The signed angle between the two vectors + static AngleOf SignedAngle(const Vector2Of& v1, const Vector2Of& v2); + + /// @brief Rotate the vector + /// @param v The vector to rotate + /// @param a The angle in degrees to rotate + /// @return The rotated vector + static Vector2Of Rotate(const Vector2Of& v, AngleOf a); + + /// @brief Lerp (linear interpolation) between two vectors + /// @param v1 The starting vector + /// @param v2 The end vector + /// @param f The interpolation distance + /// @return The lerped vector + /// @remark The factor f is unclamped. Value 0 matches the vector *v1*, Value + /// 1 matches vector *v2*. Value -1 is vector *v1* minus the difference + /// between *v1* and *v2* etc. + static Vector2Of Lerp(const Vector2Of& v1, const Vector2Of& v2, float f); }; -//template class Vector2Of; +#pragma region friend functions + +// For a class template a friend function must also be a template and defined in +// the header (unless you restrict to a concrete instantiation)... + +template +Vector2Of operator*(const Vector2Of& v, U f) { + return Vector2Of(v.horizontal * f, v.vertical * f); +} +template +Vector2Of operator*(U f, const Vector2Of& v) { + return Vector2Of(f * v.horizontal, f * v.vertical); +} + +template +Vector2Of operator/(const Vector2Of& v, U f) { + return Vector2Of(v.horizontal / f, v.vertical / f); +} +template +Vector2Of operator/(U f, const Vector2Of& v) { + return Vector2Of(f / v.horizontal, f / v.vertical); +} + +#pragma endregion friend functions + +// 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); -} +// template +// inline Vector2Of operator/(const Vector2Of& v, float f) { +// return Vector2Of(v.horizontal / f, v.vertical / f); +// } } // namespace LinearAlgebra -using namespace LinearAlgebra; +// using namespace LinearAlgebra; #endif \ No newline at end of file diff --git a/Vector3.cpp b/Vector3.cpp index 8893df4..ab2abe1 100644 --- a/Vector3.cpp +++ b/Vector3.cpp @@ -25,11 +25,11 @@ Vector3::Vector3(float right, float up, float forward) { this->z = forward; } -Vector3::Vector3(Vector2 v) { - this->x = v.x; - this->y = 0.0f; - this->z = v.y; -} +// Vector3::Vector3(Vector2 v) { +// this->x = v.x; +// this->y = 0.0f; +// this->z = v.y; +// } Vector3::Vector3(SphericalOf s) { float verticalRad = (90.0f - s.direction.vertical.InDegrees()) * Deg2Rad; diff --git a/Vector3.h b/Vector3.h index b94fa0d..4105931 100644 --- a/Vector3.h +++ b/Vector3.h @@ -7,6 +7,7 @@ #include "Vector2.h" + extern "C" { /// /// 3-dimensional Vector representation (C-style) @@ -52,7 +53,7 @@ struct Vector3 : Vec3 { Vector3(float right, float up, float forward); /// @brief Convert a 2-dimenstional vector to a 3-dimensional vector /// @param v The vector to convert - Vector3(Vector2 v); + //Vector3(Vector2 v); /// @brief Convert vector in spherical coordinates to 3d carthesian /// coordinates /// @param v The vector to convert diff --git a/test/Polar_test.cc b/test/Polar_test.cc index ba65946..0bbd207 100644 --- a/test/Polar_test.cc +++ b/test/Polar_test.cc @@ -9,6 +9,8 @@ #define FLOAT_INFINITY std::numeric_limits::infinity() +using Vector2 = Vector2Of; + TEST(Polar, FromVector2) { Vector2 v = Vector2(0, 1); PolarSingle p = PolarSingle::FromVector2(v); diff --git a/test/Vector2_test.cc b/test/Vector2_test.cc index c453be9..0eece89 100644 --- a/test/Vector2_test.cc +++ b/test/Vector2_test.cc @@ -1,65 +1,67 @@ #if GTEST #include -#include #include +#include -#include "Vector2.h" #include "Polar.h" +#include "Vector2.h" #define FLOAT_INFINITY std::numeric_limits::infinity() +using Vector2 = Vector2Of; + TEST(Vector2, FromPolar) { Vector2 v; PolarSingle p; - Vector2 r; + Vector2Float r; v = Vector2(0, 1); p = PolarSingle::FromVector2(v); - r = Vector2(p); + r = Vector2Of::FromPolar(p); - EXPECT_FLOAT_EQ(r.x, 0.0F) << "FromPolar(0 1)"; - EXPECT_FLOAT_EQ(r.y, 1.0F) << "FromPolar(0 1)"; + EXPECT_FLOAT_EQ(r.horizontal, 0.0F) << "FromPolar(0 1)"; + EXPECT_FLOAT_EQ(r.vertical, 1.0F) << "FromPolar(0 1)"; v = Vector2(1, 0); p = PolarSingle::FromVector2(v); - r = Vector2(p); + r = Vector2Of::FromPolar(p); - EXPECT_FLOAT_EQ(r.x, 1.0F) << "FromPolar(1 0)"; - EXPECT_NEAR(r.y, 0.0F, 1.0e-07) << "FromPolar(1 0)"; + EXPECT_FLOAT_EQ(r.horizontal, 1.0F) << "FromPolar(1 0)"; + EXPECT_NEAR(r.vertical, 0.0F, 1.0e-07) << "FromPolar(1 0)"; v = Vector2(0, 0); p = PolarSingle::FromVector2(v); - r = Vector2(p); + r = Vector2Of::FromPolar(p); - EXPECT_FLOAT_EQ(r.x, 0.0F) << "FromPolar(0 0)"; - EXPECT_FLOAT_EQ(r.y, 0.0F) << "FromPolar(0 0)"; + EXPECT_FLOAT_EQ(r.horizontal, 0.0F) << "FromPolar(0 0)"; + EXPECT_FLOAT_EQ(r.vertical, 0.0F) << "FromPolar(0 0)"; } TEST(Vector2, Magnitude) { Vector2 v = Vector2(1, 2); float m = 0; - m = v.magnitude(); + m = v.Magnitude(); EXPECT_FLOAT_EQ(m, 2.236068F) << "v.magnitude 1 2"; - m = Vector2::Magnitude(v); + m = Vector2::MagnitudeOf(v); EXPECT_FLOAT_EQ(m, 2.236068F) << "Vector2::Magnitude 1 2"; v = Vector2(-1, -2); - m = v.magnitude(); + m = v.Magnitude(); EXPECT_FLOAT_EQ(m, 2.236068F) << "v.magnitude -1 -2"; v = Vector2(0, 0); - m = v.magnitude(); + m = v.Magnitude(); EXPECT_FLOAT_EQ(m, 0) << "v.magnitude 0 0 "; if (std::numeric_limits::is_iec559) { v = Vector2(FLOAT_INFINITY, FLOAT_INFINITY); - m = v.magnitude(); + m = v.Magnitude(); EXPECT_FLOAT_EQ(m, FLOAT_INFINITY) << "v.magnitude INFINITY INFINITY "; v = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY); - m = v.magnitude(); + m = v.Magnitude(); EXPECT_FLOAT_EQ(m, FLOAT_INFINITY) << "v.magnitude -INFINITY -INFINITY "; } } @@ -68,27 +70,27 @@ TEST(Vector2, SqrMagnitude) { Vector2 v = Vector2(1, 2); float m = 0; - m = v.sqrMagnitude(); + m = v.SqrMagnitude(); EXPECT_FLOAT_EQ(m, 5) << "v.sqrMagnitude 1 2"; - m = Vector2::SqrMagnitude(v); + m = Vector2::SqrMagnitudeOf(v); EXPECT_FLOAT_EQ(m, 5) << "Vector2::SqrMagnitude 1 2"; v = Vector2(-1, -2); - m = v.sqrMagnitude(); + m = v.SqrMagnitude(); EXPECT_FLOAT_EQ(m, 5) << "v.sqrMagnitude -1 -2"; v = Vector2(0, 0); - m = v.sqrMagnitude(); + m = v.SqrMagnitude(); EXPECT_FLOAT_EQ(m, 0) << "v.sqrMagnitude 0 0 "; if (std::numeric_limits::is_iec559) { v = Vector2(FLOAT_INFINITY, FLOAT_INFINITY); - m = v.sqrMagnitude(); + m = v.SqrMagnitude(); EXPECT_FLOAT_EQ(m, FLOAT_INFINITY) << "v.sqrMagnitude INFINITY INFINITY "; v = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY); - m = v.sqrMagnitude(); + m = v.SqrMagnitude(); EXPECT_FLOAT_EQ(m, FLOAT_INFINITY) << "v.sqrMagnitude -INFINITY -INFINITY "; } } @@ -99,29 +101,29 @@ TEST(Vector2, Normalize) { Vector2 v1 = Vector2(0, 2); Vector2 v = Vector2::zero; - v = v1.normalized(); + v = v1.Normalized(); EXPECT_TRUE(v == Vector2(0, 1)) << "v.normalized 0 2"; v = Vector2::Normalize(v1); EXPECT_TRUE(v == Vector2(0, 1)) << "Vector3::Normalize 0 2"; v1 = Vector2(0, -2); - v = v1.normalized(); + v = v1.Normalized(); EXPECT_TRUE(v == Vector2(0, -1)) << "v.normalized 0 -2"; v1 = Vector2(0, 0); - v = v1.normalized(); + v = v1.Normalized(); EXPECT_TRUE(v == Vector2(0, 0)) << "v.normalized 0 0"; if (std::numeric_limits::is_iec559) { v1 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY); - v = v1.normalized(); - r = isnan(v.x) && isnan(v.y); + v = v1.Normalized(); + r = isnan(v.horizontal) && isnan(v.vertical); EXPECT_TRUE(r) << "v.normalized INFINITY INFINITY"; v1 = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY); - v = v1.normalized(); - r = isnan(v.x) && isnan(v.y); + v = v1.Normalized(); + r = isnan(v.horizontal) && isnan(v.vertical); EXPECT_TRUE(r) << "v.normalized -INFINITY -INFINITY"; } } @@ -392,29 +394,31 @@ TEST(Vector2, Distance) { TEST(Vector2, Angle) { Vector2 v1 = Vector2(4, 5); Vector2 v2 = Vector2(1, 2); - float f = 0; + Angle f = Angle::zero; bool r = false; - f = Vector2::Angle(v1, v2); - EXPECT_FLOAT_EQ(f, 12.09476F) << "Angle(4 5, 1 2)"; + f = Vector2::UnsignedAngle(v1, v2); + EXPECT_FLOAT_EQ(f.InDegrees(), 12.09476F) << "Angle(4 5, 1 2)"; v2 = Vector2(-1, -2); - f = Vector2::Angle(v1, v2); - EXPECT_FLOAT_EQ(f, 167.9052F) << "Angle(4 5, -1 -2)"; + f = Vector2::UnsignedAngle(v1, v2); + EXPECT_FLOAT_EQ(f.InDegrees(), 167.9052F) << "Angle(4 5, -1 -2)"; v2 = Vector2(0, 0); - f = Vector2::Angle(v1, v2); - EXPECT_FLOAT_EQ(f, 0) << "Angle(4 5, 0 0)"; + f = Vector2::UnsignedAngle(v1, v2); + EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "Angle(4 5, 0 0)"; if (std::numeric_limits::is_iec559) { v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY); - f = Vector2::Angle(v1, v2); - r = isnan(f); + f = Vector2::UnsignedAngle(v1, v2); + //r = isnan(f.InDegrees()); + r = f.InDegrees() == 0; EXPECT_TRUE(r) << "Angle(4 5, INFINITY INFINITY)"; v2 = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY); - f = Vector2::Angle(v1, v2); - r = isnan(f); + f = Vector2::UnsignedAngle(v1, v2); + //r = isnan(f.InDegrees()); + r = f.InDegrees() == 0; EXPECT_TRUE(r) << "Angle(4 5, -INFINITY -INFINITY)"; } } @@ -422,41 +426,43 @@ TEST(Vector2, Angle) { TEST(Vector2, SignedAngle) { Vector2 v1 = Vector2(4, 5); Vector2 v2 = Vector2(1, 2); - float f = 0; + Angle f = Angle::zero; bool r = false; f = Vector2::SignedAngle(v1, v2); - EXPECT_FLOAT_EQ(f, -12.09476F) << "SignedAngle(4 5, 1 2)"; + EXPECT_FLOAT_EQ(f.InDegrees(), -12.09476F) << "SignedAngle(4 5, 1 2)"; v2 = Vector2(-1, -2); f = Vector2::SignedAngle(v1, v2); - EXPECT_FLOAT_EQ(f, 167.9052F) << "SignedAngle(4 5, -1 -2)"; + EXPECT_FLOAT_EQ(f.InDegrees(), 167.9052F) << "SignedAngle(4 5, -1 -2)"; v2 = Vector2(0, 0); f = Vector2::SignedAngle(v1, v2); - EXPECT_FLOAT_EQ(f, 0) << "SignedAngle(4 5, 0 0)"; + EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "SignedAngle(4 5, 0 0)"; if (std::numeric_limits::is_iec559) { v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY); f = Vector2::SignedAngle(v1, v2); - r = isnan(f); + //r = isnan(f.InDegrees()); + r = f.InDegrees() == 0; EXPECT_TRUE(r) << "SignedAngle(4 5, INFINITY INFINITY)"; v2 = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY); f = Vector2::SignedAngle(v1, v2); - r = isnan(f); + //r = isnan(f.InDegrees()); + r = f.InDegrees() == 0; EXPECT_TRUE(r) << "SignedAngle(4 5, -INFINITY -INFINITY)"; } v1 = Vector2(0, 1); v2 = Vector2(1, 0); f = Vector2::SignedAngle(v1, v2); - EXPECT_FLOAT_EQ(f, 90.0F) << "SignedAngle(0 1, 1 0)"; + EXPECT_FLOAT_EQ(f.InDegrees(), 90.0F) << "SignedAngle(0 1, 1 0)"; v1 = Vector2(0, 1); v2 = Vector2(0, -1); f = Vector2::SignedAngle(v1, v2); - EXPECT_FLOAT_EQ(f, 180.0F) << "SignedAngle(0 1, 1 0)"; + EXPECT_FLOAT_EQ(f.InDegrees(), 180.0F) << "SignedAngle(0 1, 1 0)"; } TEST(Vector2, Rotate) {