LinearAlgebra-cpp/test/Angle_test.cc
Pascal Serrarens 679471f748
All checks were successful
Build and Run C++ Unit Tests / build-and-test (push) Successful in 2m1s
Improved unit tests
2025-12-22 10:23:27 +01:00

257 lines
8.3 KiB
C++

#if GTEST
#include <gtest/gtest.h>
#include <math.h>
#include <limits>
#include "Angle.h"
using namespace LinearAlgebra;
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
//using AngleTypes = ::testing::Types<AngleOf<float>, AngleOf<signed short>, AngleOf<signed char>>;
using BaseTypes = ::testing::Types<float, signed short, signed char>;
template <typename T>
class AngleTests : public ::testing::Test {};
TYPED_TEST_SUITE(AngleTests, BaseTypes);
TYPED_TEST(AngleTests, Construct) {
using Angle = AngleOf<TypeParam>;
float angle = 0.0F;
Angle a = Angle::Degrees(angle);
EXPECT_FLOAT_EQ(a.InDegrees(), angle);
angle = -180.0F;
a = Angle::Degrees(angle);
EXPECT_FLOAT_EQ(a.InDegrees(), angle);
angle = 270.0F;
a = Angle::Degrees(angle);
EXPECT_FLOAT_EQ(a.InDegrees(), -90);
}
TYPED_TEST(AngleTests, Negate) {
using Angle = AngleOf<TypeParam>;
float angle = 0;
Angle a = Angle::Degrees(angle);
a = -a;
EXPECT_FLOAT_EQ(a.InDegrees(), angle);
angle = 90.0F;
a = Angle::Degrees(angle);
a = -a;
EXPECT_FLOAT_EQ(a.InDegrees(), -angle);
}
TYPED_TEST(AngleTests, Add) {
using Angle = AngleOf<TypeParam>;
Angle a = Angle::Degrees(-45);
Angle b = Angle::Degrees(45.0F);
Angle r = a + b;
EXPECT_FLOAT_EQ(r.InDegrees(), 0);
}
TYPED_TEST(AngleTests, Subtract) {
using Angle = AngleOf<TypeParam>;
Angle a = Angle::Degrees(0);
Angle b = Angle::Degrees(45.0F);
Angle r = a - b;
EXPECT_FLOAT_EQ(r.InDegrees(), -45);
}
TYPED_TEST(AngleTests, Compare) {
using Angle = AngleOf<TypeParam>;
Angle a = Angle::Degrees(45);
bool r = false;
r = a > Angle::Degrees(0);
EXPECT_TRUE(r) << "45 > 0";
r = a > Angle::Degrees(90);
EXPECT_FALSE(r) << "45 > 90";
r = a > Angle::Degrees(-90);
EXPECT_TRUE(r) << "45 > -90";
}
TYPED_TEST(AngleTests, Normalize) {
using Angle = AngleOf<TypeParam>;
Angle r = Angle();
r = Angle::Normalize(Angle::Degrees(90.0f));
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Normalize 90";
r = Angle::Normalize(Angle::Degrees(-90));
EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Normalize -90";
r = Angle::Normalize(Angle::Degrees(270));
EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Normalize 270";
r = Angle::Normalize(Angle::Degrees(270 + 360));
EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Normalize 270+360";
r = Angle::Normalize(Angle::Degrees(-270));
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Normalize -270";
r = Angle::Normalize(Angle::Degrees(-270 - 360));
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Normalize -270-360";
r = Angle::Normalize(Angle::Degrees(0));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Normalize 0";
if (false) { // std::numeric_limits<float>::is_iec559) {
// Infinites are not supported
r = Angle::Normalize(Angle::Degrees(FLOAT_INFINITY));
EXPECT_FLOAT_EQ(r.InDegrees(), FLOAT_INFINITY) << "Normalize INFINITY";
r = Angle::Normalize(Angle::Degrees(-FLOAT_INFINITY));
EXPECT_FLOAT_EQ(r.InDegrees(), -FLOAT_INFINITY) << "Normalize INFINITY";
}
}
TYPED_TEST(AngleTests, Clamp) {
using Angle = AngleOf<TypeParam>;
Angle r = Angle();
// Clamp(1, 0, 2) will fail because Angle does not have enough resolution for
// this. Instead we use Clamp(10, 0, 20) etc.
r = Angle::Clamp(Angle::Degrees(10), Angle::Degrees(0),
Angle::Degrees(20));
EXPECT_NEAR(r.InDegrees(), 10, 1.0e-0) << "Clamp 10 0 20";
r = Angle::Clamp(Angle::Degrees(-10), Angle::Degrees(0),
Angle::Degrees(20));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Clamp -10 0 20";
r = Angle::Clamp(Angle::Degrees(30), Angle::Degrees(0),
Angle::Degrees(20));
EXPECT_NEAR(r.InDegrees(), 20, 1.0e-0) << "Clamp 30 0 20";
r = Angle::Clamp(Angle::Degrees(10), Angle::Degrees(0),
Angle::Degrees(0));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Clamp 10 0 0";
r = Angle::Clamp(Angle::Degrees(0), Angle::Degrees(0), Angle::Degrees(0));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Clamp 0 0 0";
r = Angle::Clamp(Angle::Degrees(0), Angle::Degrees(10),
Angle::Degrees(-10));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Clamp 0 10 -10";
if (false) { // std::numeric_limits<float>::is_iec559) {
// Infinites are not supported
r = Angle::Clamp(Angle::Degrees(10), Angle::Degrees(0),
Angle::Degrees(FLOAT_INFINITY));
EXPECT_NEAR(r.InDegrees(), 10, 1.0e-0) << "Clamp 1 0 INFINITY";
r = Angle::Clamp(Angle::Degrees(10), Angle::Degrees(-FLOAT_INFINITY),
Angle::Degrees(10));
EXPECT_NEAR(r.InDegrees(), 10, 1.0e-0) << "Clamp 1 -INFINITY 1";
}
}
// TEST(Angle, Difference) {
// using Angle = AngleOf<TypeParam>;
// Angle r = 0;
// r = Angle::Difference(0, 90);
// EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Difference 0 90";
// r = Angle::Difference(0, -90);
// EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Difference 0 -90";
// r = Angle::Difference(0, 270);
// EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Difference 0 270";
// r = Angle::Difference(0, -270);
// EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Difference 0 -270";
// r = Angle::Difference(90, 0);
// EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Difference 90 0";
// r = Angle::Difference(-90, 0);
// EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Difference -90 0";
// r = Angle::Difference(0, 0);
// EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Difference 0 0";
// r = Angle::Difference(90, 90);
// EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Difference 90 90";
// if (std::numeric_limits<float>::is_iec559) {
// r = Angle::Difference(0, INFINITY);
// EXPECT_FLOAT_EQ(r.InDegrees(), INFINITY) << "Difference 0 INFINITY";
// r = Angle::Difference(0, -INFINITY);
// EXPECT_FLOAT_EQ(r.InDegrees(), -INFINITY) << "Difference 0 -INFINITY";
// r = Angle::Difference(-INFINITY, INFINITY);
// EXPECT_FLOAT_EQ(r.InDegrees(), INFINITY) << "Difference -INFINITY
// INFINITY";
// }
// }
TYPED_TEST(AngleTests, MoveTowards) {
using Angle = AngleOf<TypeParam>;
Angle r = Angle();
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90), 30);
EXPECT_NEAR(r.InDegrees(), 30, 1.0e-0) << "MoveTowards 0 90 30";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90), 90);
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "MoveTowards 0 90 90";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-90), 180);
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "MoveTowards 0 -90 -180";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90), 270);
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "MoveTowards 0 90 270";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90), -30);
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "MoveTowards 0 90 -30";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-90), -30);
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "MoveTowards 0 -90 -30";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-90), -90);
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "MoveTowards 0 -90 -90";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-90), -180);
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "MoveTowards 0 -90 -180";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-90), -270);
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "MoveTowards 0 -90 -270";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90), 0);
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "MoveTowards 0 90 0";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(0), 0);
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "MoveTowards 0 0 0";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(0), 30);
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "MoveTowards 0 0 30";
if (false) { // std::numeric_limits<float>::is_iec559) {
// infinites are not supported
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90),
FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "MoveTowards 0 90 FLOAT_INFINITY";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(FLOAT_INFINITY),
30);
EXPECT_FLOAT_EQ(r.InDegrees(), 30) << "MoveTowards 0 FLOAT_INFINITY 30";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-90),
-FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r.InDegrees(), FLOAT_INFINITY)
<< "MoveTowards 0 -90 -FLOAT_INFINITY";
r = Angle::MoveTowards(Angle::Degrees(0),
Angle::Degrees(-FLOAT_INFINITY), -30);
EXPECT_FLOAT_EQ(r.InDegrees(), 30) << "MoveTowards 0 -FLOAT_INFINITY -30";
}
}
#endif