Disabled old Vector2 implementation
All checks were successful
Build and Run C++ Unit Tests / build-and-test (push) Successful in 2m19s

This commit is contained in:
Pascal Serrarens 2025-12-19 17:19:45 +01:00
parent 0def678cc5
commit a2ba625bac
8 changed files with 333 additions and 98 deletions

View File

@ -37,10 +37,9 @@ PolarOf<T> PolarOf<T>::Radians(float distance, float radians) {
}
template <typename T>
PolarOf<T> PolarOf<T>::FromVector2(Vector2 v) {
float distance = v.magnitude();
AngleOf<T> angle =
AngleOf<T>::Degrees(Vector2::SignedAngle(Vector2::forward, v));
PolarOf<T> PolarOf<T>::FromVector2(Vector2Of<T> v) {
float distance = v.Magnitude();
AngleOf<T> angle = Vector2Of<T>::SignedAngle(Vector2Of<T>::forward, v);
PolarOf<T> p = PolarOf(distance, angle);
return p;
}

View File

@ -9,7 +9,8 @@
namespace LinearAlgebra {
struct Vector2;
template <typename T>
class Vector2Of;
template <typename T>
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<T> FromVector2(Vector2 v);
static PolarOf<T> FromVector2(Vector2Of<T> 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

View File

@ -13,6 +13,7 @@
#include <math.h>
// #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 <typename T>
Vector2Of<T>::Vector2Of(T horizontal, T vertical)
: horizontal(horizontal), vertical(vertical) {}
template <typename T>
Vector2Of<float> Vector2Of<T>::FromPolar(PolarOf<T> p) {
float horizontalRad = p.angle.InDegrees() * Deg2Rad;
float cosHorizontal = cosf(horizontalRad);
float sinHorizontal = sinf(horizontalRad);
Vector2Of<float> v;
v.horizontal = p.distance * sinHorizontal;
v.vertical = p.distance * cosHorizontal;
return v;
}
template <typename T>
const Vector2Of<T> Vector2Of<T>::zero = Vector2Of(T{}, T{});
template <typename T>
const Vector2Of<T> Vector2Of<T>::forward = Vector2Of(T{}, 1);
template <typename T>
bool LinearAlgebra::Vector2Of<T>::operator==(const Vector2Of& v) {
return (this->horizontal == v.horizontal && this->vertical == v.vertical);
}
template <typename T>
float Vector2Of<T>::MagnitudeOf(const Vector2Of& v) {
T sqr = v.horizontal * v.horizontal + v.vertical * v.vertical;
@ -201,12 +223,29 @@ float Vector2Of<T>::MagnitudeOf(const Vector2Of& v) {
}
template <typename T>
float LinearAlgebra::Vector2Of<T>::Magnitude() const {
float Vector2Of<T>::Magnitude() const {
T sqr = this->horizontal * this->horizontal + this->vertical * this->vertical;
float sqrFloat = static_cast<float>(sqr);
return sqrtf(sqrFloat);
}
template <typename T>
float Vector2Of<T>::SqrMagnitudeOf(const Vector2Of& v) {
T sqr = v.horizontal * v.horizontal + v.vertical * v.vertical;
return static_cast<float>(sqr);
}
template <typename T>
float Vector2Of<T>::SqrMagnitude() const {
T sqr = this->horizontal * this->horizontal + this->vertical * this->vertical;
return static_cast<float>(sqr);
}
template <typename T>
Vector2Of<T> Vector2Of<T>::operator-() {
return Vector2Of<T>(-this->horizontal, -this->vertical);
}
template <typename T>
Vector2Of<T> Vector2Of<T>::operator-(const Vector2Of& v) const {
return Vector2Of(this->horizontal - v.horizontal,
@ -233,6 +272,11 @@ Vector2Of<T> Vector2Of<T>::operator+=(const Vector2Of& v) {
return *this;
}
template <typename T>
Vector2Of<T> Vector2Of<T>::Scale(const Vector2Of& v1, const Vector2Of& v2) {
return Vector2Of<T>(v1.horizontal * v2.horizontal, v1.vertical * v2.vertical);
}
// template <typename T>
// Vector2Of<float> Vector2Of<T>::operator/=(float f) {
// this->x /= f;
@ -240,33 +284,101 @@ Vector2Of<T> Vector2Of<T>::operator+=(const Vector2Of& v) {
// return *this;
// }
template <typename T>
T Vector2Of<T>::Dot(const Vector2Of& v1, const Vector2Of& v2) {
return v1.horizontal * v2.horizontal + v1.vertical * v2.vertical;
}
template <typename T>
float Vector2Of<T>::Distance(const Vector2Of& v1, const Vector2Of& v2) {
return MagnitudeOf(v1 - v2);
}
template <typename T>
Vector2 Vector2Of<T>::Normalize(const Vector2Of<T>& v) {
Vector2Of<float> Vector2Of<T>::Normalize(const Vector2Of<T>& v) {
float num = Vector2Of<T>::MagnitudeOf(v);
Vector2 result = Vector2::zero;
Vector2Of<float> result = Vector2Of::zero;
if (num > Float::epsilon) {
result = v / num;
result = static_cast<Vector2Of<float>>(v) / num;
}
return result;
}
template <typename T>
Vector2 Vector2Of<T>::normalized() const {
AngleOf<T> Vector2Of<T>::UnsignedAngle(const Vector2Of& v1,
const Vector2Of& v2) {
return AngleOf<T>::Abs(SignedAngle(v1, v2));
}
template <typename T>
AngleOf<T> Vector2Of<T>::SignedAngle(const Vector2Of& v1, const Vector2Of& v2) {
float sqrMagFrom = v1.SqrMagnitude();
float sqrMagTo = v2.SqrMagnitude();
if (sqrMagFrom == 0 || sqrMagTo == 0)
return AngleOf<T>::zero;
if (!isfinite(sqrMagFrom) || !isfinite(sqrMagTo))
return AngleOf<T>::zero; // Angle does not support NaN...
AngleOf<T> angleFrom = AngleOf<T>::Atan2(static_cast<float>(v1.vertical),
static_cast<float>(v1.horizontal));
AngleOf<T> angleTo = AngleOf<T>::Atan2(static_cast<float>(v2.vertical),
static_cast<float>(v2.horizontal));
return -(angleTo - angleFrom);
}
template <typename T>
Vector2Of<float> Vector2Of<T>::Rotate(const Vector2Of& v, AngleOf<T> a) {
float sinValue = AngleOf<T>::Sin(a);
float cosValue = AngleOf<T>::Cos(a);
float tx = static_cast<float>(v.horizontal);
float ty = static_cast<float>(v.vertical);
Vector2Of<float> r = Vector2Of<float>((cosValue * tx) - (sinValue * ty),
(sinValue * tx) + (cosValue * ty));
return r;
}
template <typename T>
Vector2Of<float> Vector2Of<T>::Lerp(const Vector2Of& v1,
const Vector2Of& v2,
float f) {
Vector2Of<float> v = v1 + static_cast<Vector2Of<float>>(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 <typename T>
Vector2Of<float> Vector2Of<T>::Normalized() const {
float num = Vector2Of<T>::MagnitudeOf(*this);
Vector2 result = Vector2::zero;
Vector2Of<float> result = Vector2Of::zero;
if (num > Float::epsilon) {
result = *this / num;
result = static_cast<Vector2Of<float>>(*this) / num;
}
return result;
}
// Explicit instantiation for int
template class Vector2Of<int>;
template class Vector2Of<signed short>;
template class Vector2Of<float>;
#pragma endregion Vector2Of

170
Vector2.h
View File

@ -7,6 +7,7 @@
#include "Angle.h"
/*
extern "C" {
/// <summary>
/// 2-dimensional Vector representation (C-style)
@ -25,13 +26,14 @@ typedef struct Vec2 {
} Vec2;
}
*/
namespace LinearAlgebra {
struct Vector3;
// struct Vector3;
template <typename T>
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 <typename T>
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<float> FromPolar(PolarOf<T> v);
/// @brief Converting constructor: allow Vector2Of<U> -> Vector2Of<T>
/// @tparam U
/// @param other
template <typename U>
constexpr Vector2Of(const Vector2Of<U>& other) noexcept
: horizontal(static_cast<T>(other.horizontal)), vertical(static_cast<T>(other.vertical)) {}
: horizontal(static_cast<T>(other.horizontal)),
vertical(static_cast<T>(other.vertical)) {}
template <typename U>
constexpr Vector2Of& operator=(const Vector2Of<U>& 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 <typename U>
friend Vector2Of<U> operator*(const Vector2Of<U>& m, U f);
template <typename U>
friend Vector2Of<U> operator*(U f, const Vector2Of<U>& 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<int> is provided as a free function below (inside namespace)
// Vector2Of<float> operator/=(float f);
/// @remark Each component of the vector will be divided by the same factor.
template <typename U>
friend Vector2Of<U> operator/(const Vector2Of<U>& m, U f);
template <typename U>
friend Vector2Of<U> operator/(U f, const Vector2Of<U>& 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<float> 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<float> 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<T> 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<T> 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<float> Rotate(const Vector2Of& v, AngleOf<T> 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<float> Lerp(const Vector2Of& v1, const Vector2Of& v2, float f);
};
//template class Vector2Of<float>;
#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 <typename U>
Vector2Of<U> operator*(const Vector2Of<U>& v, U f) {
return Vector2Of<U>(v.horizontal * f, v.vertical * f);
}
template <typename U>
Vector2Of<U> operator*(U f, const Vector2Of<U>& v) {
return Vector2Of<U>(f * v.horizontal, f * v.vertical);
}
template <typename U>
Vector2Of<U> operator/(const Vector2Of<U>& v, U f) {
return Vector2Of<U>(v.horizontal / f, v.vertical / f);
}
template <typename U>
Vector2Of<U> operator/(U f, const Vector2Of<U>& v) {
return Vector2Of<U>(f / v.horizontal, f / v.vertical);
}
#pragma endregion friend functions
// template class Vector2Of<float>;
using Vector2Int = Vector2Of<int>;
using Vector2Float = Vector2Of<float>;
template <typename T>
inline Vector2 operator/(const Vector2Of<T>& v, float f) {
return Vector2(v.horizontal / f, v.vertical / f);
}
// template <typename T>
// inline Vector2Of operator/(const Vector2Of<T>& v, float f) {
// return Vector2Of(v.horizontal / f, v.vertical / f);
// }
} // namespace LinearAlgebra
using namespace LinearAlgebra;
// using namespace LinearAlgebra;
#endif

View File

@ -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<float> s) {
float verticalRad = (90.0f - s.direction.vertical.InDegrees()) * Deg2Rad;

View File

@ -7,6 +7,7 @@
#include "Vector2.h"
extern "C" {
/// <summary>
/// 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

View File

@ -9,6 +9,8 @@
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
using Vector2 = Vector2Of<float>;
TEST(Polar, FromVector2) {
Vector2 v = Vector2(0, 1);
PolarSingle p = PolarSingle::FromVector2(v);

View File

@ -1,65 +1,67 @@
#if GTEST
#include <gtest/gtest.h>
#include <limits>
#include <math.h>
#include <limits>
#include "Vector2.h"
#include "Polar.h"
#include "Vector2.h"
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
using Vector2 = Vector2Of<float>;
TEST(Vector2, FromPolar) {
Vector2 v;
PolarSingle p;
Vector2 r;
Vector2Float r;
v = Vector2(0, 1);
p = PolarSingle::FromVector2(v);
r = Vector2(p);
r = Vector2Of<float>::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<float>::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<float>::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<float>::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<float>::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<float>::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<float>::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<float>::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) {