diff --git a/Engine/Source/Runtime/Core/public/Math/Vector2.hpp b/Engine/Source/Runtime/Core/public/Math/Vector2.hpp index 6372399..3186e62 100644 --- a/Engine/Source/Runtime/Core/public/Math/Vector2.hpp +++ b/Engine/Source/Runtime/Core/public/Math/Vector2.hpp @@ -25,11 +25,11 @@ namespace Phanes::Core::Math { - /** + /** * A 2D Vector with components x and y with floating point precision. */ - - + + template struct TVector2 { @@ -39,9 +39,9 @@ namespace Phanes::Core::Math { // Using in combination with a struct and an array allows us the reflect changes of the x and y variables in the comp array and vise versa. - union + union { - + struct { /** X component of Vector @@ -50,22 +50,22 @@ namespace Phanes::Core::Math { * @note x does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience. */ Real x; - - /** Y component of Vector - * + + /** Y component of Vector + * * @see [FIELD]components - * + * * @note y does not hold the component, but is a reference two the second item in the components array. The varibale exists wholly for convenience. */ Real y; }; - /** Components array holding the data - * + /** Components array holding the data + * * @see [FIELD]x * @see [FIELD]y - * - * @note Components are split into x and y. Access and manipulation is possible by these variables. + * + * @note Components are split into x and y. Access and manipulation is possible by these variables. */ union @@ -86,7 +86,7 @@ namespace Phanes::Core::Math { */ TVector2() = default; - + /** * Copy constructor */ @@ -95,7 +95,7 @@ namespace Phanes::Core::Math { /** * Construct Vector from xy components. - * + * * @param(x) X component * @param(y) Y component */ @@ -113,15 +113,15 @@ namespace Phanes::Core::Math { /// /// Scalar TVector2(Real s); - }; + }; // ====================== // // TVector2 operators // // ====================== // - + /** * Addition operation on same TVector2 (this) by a floating point value. - * + * * @param(v1) Vector to add to * @param(s) Floating point to add */ @@ -160,7 +160,7 @@ namespace Phanes::Core::Math { TVector2 operator-= (TVector2& v1, const TVector2& v2); /** - * Multiplication of TVector2 (this) with a floating point. + * Multiplication of TVector2 (this) with a floating point. * * @param(v1) Vector to multiply with * @param(s Floating point to multiply with @@ -169,6 +169,17 @@ namespace Phanes::Core::Math { template TVector2 operator*= (TVector2& v1, T s); + /// + /// Componentwise multiplication of vector by other vector. + /// + /// + /// + /// + /// + /// Copy of v1. + template + TVector2 operator*= (TVector2& v1, const TVector2& v2); + /** * Devision of Vector (this) by floating point. * @@ -179,72 +190,112 @@ namespace Phanes::Core::Math { template TVector2 operator/= (TVector2& v1, T s); + /// + /// Componentwise division of vector by other vector. + /// + /// + /// + /// + /// + /// Copy of v1. + template + TVector2 operator/= (TVector2& v1, const TVector2& v2); + /** * Scale of Vector by floating point. (> Creates a new TVector2) * * @param(v1) Vector to multiply with * @param(s Floating point to multiply with - * + * * @return Result Vector */ template TVector2 operator* (const TVector2& v1, T s); + /// + /// Componentwise multiplication with vector by vector. + /// + /// + /// + /// + /// + /// + template + TVector2 operator* (const TVector2& v1, const TVector2& v2); + /** * Division of Vector by floating point. (> Creates another TVector2) * * @param(v1) Vector to multiply with * @param(s Floating point to divide with - * + * * @return Result Vector */ template TVector2 operator/ (const TVector2& v1, T s); + /// + /// Componentwise multiplication with vector by vector. + /// + /// + /// + /// + /// + /// + template + TVector2 operator/ (const TVector2& v1, const TVector2& v2); + /** * Scale of Vector by floating point. (> Creates a new TVector2) * * @param(v1) Vector to multiply with * @param(s Floating point to multiply with - * + * * @return Result Vector */ template - inline TVector2 operator* (T s, const TVector2& v1); + inline TVector2 operator* (T s, const TVector2& v1) + { + return v1 * s; + } /** * Division of Vector by floating point. (> For convenience not arithmethicaly correct. Works like overloaded counterpart.) * * @param(v1) Vector to multiply with * @param(s Floating point to divide with - * + * * @return Result Vector */ + template - inline TVector2 operator/ (T s, const TVector2& v1); + inline TVector2 operator/ (T s, const TVector2& v1) + { + return v1 / s; + } /** - * Componentwise addition of Vector with floating point. + * Componentwise addition of Vector with floating point. * * @param(v1) Vector to add to * @param(s Floating point to add - * + * * @return Result Vector */ template TVector2 operator+ (const TVector2& v1, T s); - + /** - * Componentwise addition of Vector with floating point. + * Componentwise addition of Vector with floating point. * * @param(v1) Vector to add to * @param(s Floating point to add - * + * * @return Result Vector */ @@ -256,7 +307,7 @@ namespace Phanes::Core::Math { * * @param(v1) Vector to substract from * @param(s Floating point to substract - * + * * @return Result Vector */ @@ -268,7 +319,7 @@ namespace Phanes::Core::Math { * * @param(v1) Vector to substract from * @param(s Floating point to substract - * + * * @return Result Vector */ @@ -276,22 +327,12 @@ namespace Phanes::Core::Math { TVector2 operator- (const TVector2& v1, const TVector2& v2); /** - * Negate Vector. + * Compare Vector for equality. * - * @param(v1) Vector to negate - */ - - template - TVector2 operator- (const TVector2& v1); - - - /** - * Compare Vector for equality. - * * @see [FUNC]Equals * * @param(v1) Vector to negate - * + * * @return true if equal, false if inequal */ @@ -305,7 +346,7 @@ namespace Phanes::Core::Math { * @see [FUNC]Equals * * @param(v1) Vector to negate - * + * * @return true if inequal, false if equal */ @@ -313,6 +354,8 @@ namespace Phanes::Core::Math { bool operator!= (const TVector2& v1, const TVector2& v2); + + // ============================================ // // TVector2 static function implementation // // ============================================ // @@ -410,7 +453,7 @@ namespace Phanes::Core::Math { template T CosineAngle(const TVector2& v1, const TVector2& v2) { - return (v1 * v2) / Magnitude(v1) * Magnitude(v2); + return DotP(v1, v2) / (Magnitude(v1) * Magnitude(v2)); } /** @@ -422,8 +465,8 @@ namespace Phanes::Core::Math { template TVector2 SignVectorV(TVector2& v1) { - v1.x = (v1.x >= 0) ? 1 : -1; - v1.y = (v1.y >= 0) ? 1 : -1; + v1.x = (v1.x >= (T)0.0) ? (T)1.0 : -(T)1.0; + v1.y = (v1.y >= (T)0.0) ? (T)1.0 : -(T)1.0; return v1; } @@ -521,9 +564,9 @@ namespace Phanes::Core::Math { template TVector2 GetPerpendicularV(TVector2& v1) { - T x = v1.x; + T x = -v1.x; v1.x = v1.y; - v1.y = -v1.x; + v1.y = x; return v1; } @@ -543,7 +586,7 @@ namespace Phanes::Core::Math { { T x = v1.x; v1.x = -v1.y; - v1.y = v1.x; + v1.y = x; return v1; } @@ -595,7 +638,7 @@ namespace Phanes::Core::Math { template TVector2 ReflectV(TVector2& v1, const TVector2& normal) { - Set(v1, v1 - (2 * DotP(v1, normal) * normal)); + v1 = (2.0f * DotP(v1, normal) * normal) - v1; return v1; } @@ -681,6 +724,8 @@ namespace Phanes::Core::Math { { v1.x = -v1.x; v1.y = -v1.y; + + return v1; } /** @@ -782,7 +827,7 @@ namespace Phanes::Core::Math { template TVector2 Reflect(const TVector2& v1, const TVector2& normal) { - return TVector2(v1 - (2 * DotP(v1, normal) * normal)); + return TVector2((2.0f * DotP(v1, normal) * normal) - v1); } /** @@ -927,7 +972,7 @@ namespace Phanes::Core::Math { template TVector2 SignVector(const TVector2& v1) { - return TVector2((v1.x >= 0) ? 1 : -1, (v1.y >= 0) ? 1 : -1); + return TVector2((v1.x >= (T)0.0) ? 1 : -1, (v1.y >= (T)0.0) ? (T)1.0 : (T)-1.0); } /** @@ -981,7 +1026,7 @@ namespace Phanes::Core::Math { { t = Phanes::Core::Math::Clamp(t, (T)0.0, (T)1.0); - return (t * destVec) + ((1 - t) * startVec); + return ((1 - t) * startVec) + (t * destVec); } /** @@ -1043,6 +1088,5 @@ namespace Phanes::Core::Math { #endif // !VECTOR2_H - - +// Include operator impl. #include "Core/public/Math/Vector2.inl" \ No newline at end of file diff --git a/Engine/Source/Runtime/Core/public/Math/Vector2.inl b/Engine/Source/Runtime/Core/public/Math/Vector2.inl index 82e1e08..432c0b3 100644 --- a/Engine/Source/Runtime/Core/public/Math/Vector2.inl +++ b/Engine/Source/Runtime/Core/public/Math/Vector2.inl @@ -95,7 +95,7 @@ namespace Phanes::Core::Math } template - TVector2 operator+(TVector2& v1, const TVector2& v2) + TVector2 operator+(const TVector2& v1, const TVector2& v2) { TVector2 r; Detail::compute_vec2_add::map(r, v1, v2); @@ -103,7 +103,7 @@ namespace Phanes::Core::Math } template - TVector2 operator+(TVector2& v1, T s) + TVector2 operator+(const TVector2& v1, T s) { TVector2 r; Detail::compute_vec2_add::map(r, v1, s); @@ -111,7 +111,7 @@ namespace Phanes::Core::Math } template - TVector2 operator-(TVector2& v1, const TVector2& v2) + TVector2 operator-(const TVector2& v1, const TVector2& v2) { TVector2 r; Detail::compute_vec2_sub::map(r, v1, v2); @@ -119,7 +119,7 @@ namespace Phanes::Core::Math } template - TVector2 operator-(TVector2& v1, T s) + TVector2 operator-(const TVector2& v1, T s) { TVector2 r; Detail::compute_vec2_sub::map(r, v1, s); @@ -127,7 +127,7 @@ namespace Phanes::Core::Math } template - TVector2 operator*(TVector2& v1, const TVector2& v2) + TVector2 operator*(const TVector2& v1, const TVector2& v2) { TVector2 r; Detail::compute_vec2_mul::map(r, v1, v2); @@ -135,7 +135,7 @@ namespace Phanes::Core::Math } template - TVector2 operator*(TVector2& v1, T s) + TVector2 operator*(const TVector2& v1, T s) { TVector2 r; Detail::compute_vec2_mul::map(r, v1, s); @@ -143,7 +143,7 @@ namespace Phanes::Core::Math } template - TVector2 operator/(TVector2& v1, const TVector2& v2) + TVector2 operator/(const TVector2& v1, const TVector2& v2) { TVector2 r; Detail::compute_vec2_div::map(r, v1, v2); @@ -151,7 +151,7 @@ namespace Phanes::Core::Math } template - TVector2 operator/(TVector2& v1, T s) + TVector2 operator/(const TVector2& v1, T s) { TVector2 r; Detail::compute_vec2_div::map(r, v1, s); diff --git a/MathTestFPU/packages.config b/MathTestFPU/packages.config new file mode 100644 index 0000000..be1fa03 --- /dev/null +++ b/MathTestFPU/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/MathTestFPU/pch.cpp b/MathTestFPU/pch.cpp new file mode 100644 index 0000000..250fb27 --- /dev/null +++ b/MathTestFPU/pch.cpp @@ -0,0 +1,5 @@ +// +// pch.cpp +// + +#include "pch.h" diff --git a/MathTestFPU/pch.h b/MathTestFPU/pch.h new file mode 100644 index 0000000..0572a70 --- /dev/null +++ b/MathTestFPU/pch.h @@ -0,0 +1,7 @@ +// +// pch.h +// + +#pragma once + +#include "gtest/gtest.h" diff --git a/MathTestFPU/test.cpp b/MathTestFPU/test.cpp new file mode 100644 index 0000000..08e0ae7 --- /dev/null +++ b/MathTestFPU/test.cpp @@ -0,0 +1,163 @@ +#include "pch.h" + +#include "Core/public/Math/Include.h" + +namespace PMath = Phanes::Core::Math; +using namespace Phanes::Core::Math::UnitLiterals; + +namespace VectorTests +{ + TEST(Vector2, OperatorTests) + { + PMath::Vector2 v0(2.4f, 3.1f); + PMath::Vector2 v1(5.1f, 2.5f); + + v0 += v1; + EXPECT_TRUE(v0 == PMath::Vector2(7.5f, 5.6f)); + + v0 -= v1; + EXPECT_TRUE(v0 == PMath::Vector2(2.4f, 3.1f)); + + v0 *= v1; + EXPECT_TRUE(v0 == PMath::Vector2(12.24f, 7.75f)); + + v0 /= v1; + EXPECT_TRUE(v0 == PMath::Vector2(2.4f, 3.1f)); + + + v0 += 4.0f; + EXPECT_TRUE(v0 == PMath::Vector2(6.4f, 7.1f)); + + v0 -= 4.0f; + EXPECT_TRUE(v0 == PMath::Vector2(2.4f, 3.1f)); + + v0 *= 4.0f; + EXPECT_TRUE(v0 == PMath::Vector2(9.6f, 12.4f)); + + v0 /= 4.0f; + EXPECT_TRUE(v0 == PMath::Vector2(2.4f, 3.1f)); + + // ------------------------------------------ + + PMath::Vector2 r; + + r = v0 + v1; + EXPECT_TRUE(r == PMath::Vector2(7.5f, 5.6f)); + + r = v0 - v1; + EXPECT_TRUE(r == PMath::Vector2(-2.7f, 0.6f)); + + r = v0 * v1; + EXPECT_TRUE(r == PMath::Vector2(12.24f, 7.75f)); + + r = v0 / v1; + EXPECT_TRUE(r == PMath::Vector2(0.470588f, 1.24f)); + + + + r = v0 + 4.0f; + EXPECT_TRUE(r == PMath::Vector2(6.4f, 7.1f)); + + r = v0 - 4.0f; + EXPECT_TRUE(r == PMath::Vector2(-1.6f, -0.9f)); + + r = v0 * 4.0f; + EXPECT_TRUE(r == PMath::Vector2(9.6f, 12.4f)); + + r = v0 / 4.0f; + EXPECT_TRUE(r == PMath::Vector2(0.6f, 0.775f)); + + // -------------------------------------------- + + EXPECT_TRUE(r != PMath::Vector2(0.480588f, 3.24f)); + + EXPECT_FALSE(r != PMath::Vector2(0.6f, 0.775f)); + + } + + TEST(Vector2, FunctionTest) + { + PMath::Vector2 v0(2.4f, 3.1f); + PMath::Vector2 v1(5.1f, 2.5f); + PMath::Vector2 v2(0.0f, 0.0f); + + EXPECT_FLOAT_EQ(PMath::Magnitude(v0), 3.9204591f); + EXPECT_FLOAT_EQ(PMath::SqrMagnitude(v0), 15.37f); + EXPECT_TRUE(PMath::NormalizeV(v0) == PMath::Vector2(0.612173f, 0.790724f)); + EXPECT_TRUE(PMath::NormalizeV(v2) == PMath::Vector2(0.0f, 0.0f)); + EXPECT_TRUE(PMath::IsNormalized(v0)); + EXPECT_TRUE(PMath::Abs(PMath::Angle(v0, v1) - 26.13928198243463_deg) < P_FLT_INAC); + EXPECT_FLOAT_EQ(PMath::CosineAngle(v0,v1), 0.897725742f); + EXPECT_TRUE(PMath::SignVectorV(v0) == PMath::Vector2(1, 1)); + EXPECT_TRUE(PMath::BindToSquareV(v1, 2.0f) == PMath::Vector2(2.0f, 0.9803921568f)); + + // Re-init vectors. + v0 = PMath::Vector2(2.4f, 3.1f); + v1 = PMath::Vector2(5.1f, 2.5f); + + EXPECT_TRUE(PMath::ClampToSquareV(v0, 2.0f) == PMath::Vector2(1.5483870968f, 2.0f)); + EXPECT_FLOAT_EQ(PMath::DotP(v0, v1), 12.89677419368f); + + // Re-init vector + v0 = PMath::Vector2(2.4f, 3.1f); + + EXPECT_TRUE(PMath::MaxV(v0, v1) == PMath::Vector2(5.1f, 3.1f)); + + // Re-init vector + v0 = PMath::Vector2(2.4f, 3.1f); + + EXPECT_TRUE(PMath::MinV(v0, v1) == PMath::Vector2(2.4f, 2.5f)); + + EXPECT_TRUE(PMath::GetPerpendicularV(v0) == PMath::Vector2(2.5f, -2.4f)); + EXPECT_TRUE(PMath::GetReversePerpendicularV(v1) == PMath::Vector2(-2.5f, 5.1f)); + + EXPECT_TRUE(PMath::ScaleV(v0, v1) == PMath::Vector2(-6.25f, -12.24f)); + EXPECT_TRUE(PMath::CompInverseV(v0) == PMath::Vector2(1.0f/-6.25f, 1.0f/-12.24f)); + + // re-init vectors. + v0 = PMath::Vector2(2.4f, 3.1f); + v1 = PMath::Vector2(5.1f, 2.5f); + + PMath::Vector2 n(0.8320502943f, 0.554700196f); + + // std::cerr << PMath::ToString(PMath::Reflect(v0, n)) << std::endl; + + EXPECT_TRUE(PMath::ReflectV(v0, n) == PMath::Vector2(3.784616f, 1.023077f)); + + // Re-init vectors. + v0 = PMath::Vector2(2.4f, 3.1f); + + EXPECT_TRUE(PMath::RotateV(v0, (float)30.0_deg) == PMath::Vector2(0.528460969082653f, 3.88467875173176f)); + EXPECT_TRUE(PMath::ClockwiseRotateV(v0, (float)30.0_deg) == PMath::Vector2(2.4f, 3.1f)); + EXPECT_TRUE(PMath::NegateV(v0) == PMath::Vector2(-2.4f, -3.1f)); + EXPECT_TRUE(PMath::IsPerpendicular(v0, PMath::GetPerpendicular(v0))); // Tests GetPerpendicular too. + EXPECT_TRUE(PMath::IsNormalized(n)); + EXPECT_FALSE(PMath::IsNormalized(v0)); + + // Re-init vectors. + v0 = PMath::Vector2(2.4f, 3.1f); + v1 = PMath::Vector2(5.1f, 2.5f); + + EXPECT_TRUE(PMath::IsParallel(v0, PMath::Vector2(-7.2f, -9.3f))); + EXPECT_TRUE(PMath::IsCoincident(v0, PMath::Vector2(7.2f, 9.3f))); + EXPECT_FALSE(PMath::IsCoincident(v0, PMath::Vector2(-7.2f, -9.3f))); + + + EXPECT_TRUE(PMath::Reflect(v0, n) == PMath::Vector2(3.784616f, 1.023077f)); + EXPECT_TRUE(PMath::Scale(v0, v1) == PMath::Vector2(12.24f, 7.75f)); + EXPECT_TRUE(PMath::CompInverse(v0) == PMath::Vector2(1.0f / 2.4f, 1.0f / 3.1f)); + EXPECT_TRUE(PMath::Negate(v0) == PMath::Vector2(-2.4f, -3.1f)); + EXPECT_TRUE(PMath::GetPerpendicular(v0) == PMath::Vector2(3.1f, -2.4f)); + EXPECT_TRUE(PMath::GetReversePerpendicular(v0) == PMath::Vector2(-3.1f, 2.4f)); + EXPECT_TRUE(PMath::Max(v0, v1) == PMath::Vector2(5.1f, 3.1f)); + EXPECT_TRUE(PMath::Min(v0, v1) == PMath::Vector2(2.4f, 2.5f)); + EXPECT_TRUE(PMath::Normalize(v0) == PMath::Vector2(0.612173f, 0.790724f)); + EXPECT_TRUE(PMath::SignVector(v0) == PMath::Vector2(1.0f, 1.0f)); + EXPECT_TRUE(PMath::BindToSquare(v1, 2.0f) == PMath::Vector2(2.0f, 0.9803921568f)); + EXPECT_TRUE(PMath::ClampToSquare(v0, 2.0f) == PMath::Vector2(1.5483870968f, 2.0f)); + std::cerr << PMath::ToString(PMath::Lerp(v0, v1, 0.7f)) << std::endl; + EXPECT_TRUE(PMath::Lerp(v0, v1, 0.7f) == PMath::Vector2(4.29f, 2.68f)); + EXPECT_TRUE(PMath::Rotate(v0, (float)30.0_deg) == PMath::Vector2(0.528460969082653f, 3.88467875173176f)); + EXPECT_TRUE(PMath::ClockwiseRotate(v0, (float)30.0_deg) == PMath::Vector2(3.628461f, 1.484679f)); + } +} \ No newline at end of file