#if GTEST #include #include #include #include #include "Spherical.h" #include "Vector3.h" #define FLOAT_INFINITY std::numeric_limits::infinity() using BaseTypes = ::testing::Types; template class SphericalTests : public ::testing::Test {}; TYPED_TEST_SUITE(SphericalTests, BaseTypes); TYPED_TEST(SphericalTests, FromVector3) { using T = TypeParam; using Spherical = SphericalOf; Vector3Of v = Vector3Of(0, 0, 1); Spherical s = Spherical::FromVector3(v); EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 0 1"; EXPECT_FLOAT_EQ((float)s.direction.horizontal.InDegrees(), 0.0F) << "s.hor 0 0 1"; EXPECT_FLOAT_EQ((float)s.direction.vertical.InDegrees(), 0.0F) << "s.vert 0 0 1"; v = Vector3Of(0, 1, 0); s = Spherical::FromVector3(v); EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 1 0"; EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 0.0F) << "s.hor 0 1 0"; EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 90.0F) << "s.vert 0 1 0"; v = Vector3Of(1, 0, 0); s = Spherical::FromVector3(v); EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 1 0 0"; EXPECT_FLOAT_EQ(s.direction.horizontal.InDegrees(), 90.0F) << "s.hor 1 0 0"; EXPECT_FLOAT_EQ(s.direction.vertical.InDegrees(), 0.0F) << "s.vert 1 0 0"; } TYPED_TEST(SphericalTests, Vector3) { using T = TypeParam; using Spherical = SphericalOf; Vector3Of v = Vector3Of(1, 2, 3); Spherical rd = Spherical::FromVector3(v); Vector3Of rv = rd.ToVector3(); EXPECT_LT(Vector3Of::Distance(v, rv), 10e-4) << " 1 2 3 <-> spherical"; v = Vector3Of(1, 2, -3); rd = Spherical::FromVector3(v); rv = rd.ToVector3(); EXPECT_LT(Vector3Of::Distance(v, rv), 10e-4) << " 1 2 3 <-> spherical"; } // TYPED_TEST(SphericalTests, FromPolar) { // using T = TypeParam; // using Spherical = SphericalOf; // Polar p = Polar(1, 0); // Spherical s = Spherical::FromPolar(p); // EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 0)"; // EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor Polar(1 0)"; // EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 0)"; // p = Polar(1, 45); // s = Spherical::FromPolar(p); // EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 45)"; // EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 45.0F) << "s.hor Polar(1 45)"; // EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 45)"; // p = Polar(1, -45); // s = Spherical::FromPolar(p); // EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 -45)"; // EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), -45.0F) << "s.hor Polar(1 -45)"; // EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 -45)"; // p = Polar(0, 0); // s = Spherical::FromPolar(p); // EXPECT_FLOAT_EQ(s.distance, 0.0F) << "s.distance Polar(0 0)"; // EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor Polar(0 0)"; // EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(0 0)"; // p = Polar(-1, 0); // s = Spherical::FromPolar(p); // EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(-1 0)"; // EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), -180.0F) << "s.hor Polar(-1 0)"; // EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(-1 0)"; // } TYPED_TEST(SphericalTests, Incident1) { using T = TypeParam; using Spherical = SphericalOf; using Angle = AngleOf; Vector3Of v = Vector3Of(2.242557f, 1.027884f, -0.322347f); Spherical s = Spherical::FromVector3(v); Spherical sr = Spherical(2.49F, Angle::Degrees(98.18f), Angle::Degrees(24.4F)); EXPECT_NEAR(s.distance, sr.distance, 1.0e-01); EXPECT_NEAR(s.direction.horizontal.InDegrees(), sr.direction.horizontal.InDegrees(), 1.0e-02); EXPECT_NEAR(s.direction.vertical.InDegrees(), sr.direction.vertical.InDegrees(), 1.0e-02); Vector3Of r = Spherical(sr.distance, sr.direction.horizontal, sr.direction.vertical) .ToVector3(); EXPECT_NEAR(r.horizontal, v.horizontal, 1.0e-02) << "toVector3.x 1 0 0"; EXPECT_NEAR(r.vertical, v.vertical, 1.0e-02) << "toVector3.y 1 0 0"; EXPECT_NEAR(r.depth, v.depth, 1.0e-02) << "toVector3.z 1 0 0"; } TYPED_TEST(SphericalTests, Incident2) { using T = TypeParam; using Spherical = SphericalOf; using Angle = AngleOf; Vector3Of v = Vector3Of(1.0f, 0.0f, 1.0f); Spherical s = Spherical::FromVector3(v); Spherical sr = Spherical(1.4142135623F, Angle::Degrees(45.0f), Angle::Degrees(0.0F)); EXPECT_NEAR(s.distance, sr.distance, 1.0e-05); EXPECT_NEAR(s.direction.horizontal.InDegrees(), sr.direction.horizontal.InDegrees(), 1.0e-05); EXPECT_NEAR(s.direction.vertical.InDegrees(), sr.direction.vertical.InDegrees(), 1.0e-05); Vector3Of r = Spherical(sr.distance, sr.direction.horizontal, sr.direction.vertical) .ToVector3(); EXPECT_NEAR(r.horizontal, v.horizontal, 1.0e-06); EXPECT_NEAR(r.vertical, v.vertical, 1.0e-06); EXPECT_NEAR(r.depth, v.depth, 1.0e-06); v = Vector3Of(0.0f, 1.0f, 1.0f); s = Spherical::FromVector3(v); sr = Spherical(1.4142135623F, Angle::Degrees(0), Angle::Degrees(45)); EXPECT_NEAR(s.distance, sr.distance, 1.0e-05); EXPECT_NEAR(s.direction.horizontal.InDegrees(), sr.direction.horizontal.InDegrees(), 1.0e-05); EXPECT_NEAR(s.direction.vertical.InDegrees(), sr.direction.vertical.InDegrees(), 1.0e-05); r = Spherical(sr.distance, sr.direction.horizontal, sr.direction.vertical) .ToVector3(); EXPECT_NEAR(r.horizontal, v.horizontal, 1.0e-06); EXPECT_NEAR(r.vertical, v.vertical, 1.0e-06); EXPECT_NEAR(r.depth, v.depth, 1.0e-06); v = Vector3Of(1.0f, 1.0f, 1.0f); s = Spherical::FromVector3(v); r = Spherical(s.distance, s.direction.horizontal, s.direction.vertical) .ToVector3(); EXPECT_NEAR(s.distance, 1.73205080F, 1.0e-02); EXPECT_NEAR(s.direction.horizontal.InDegrees(), 45.0F, 1.0e-02); EXPECT_NEAR(s.direction.vertical.InDegrees(), 35.26F, 1.0e-02); EXPECT_NEAR(r.horizontal, v.horizontal, 1.0e-04); EXPECT_NEAR(r.vertical, v.vertical, 1.0e-04); EXPECT_NEAR(r.depth, v.depth, 1.0e-04); // s = Spherical(10, 45, 45); // r = s.ToVector3(); // EXPECT_NEAR(r.x, 5, 1.0e-06); // EXPECT_NEAR(r.y, 7.07, 1.0e-06); // EXPECT_NEAR(r.z, 5, 1.0e-06); } TYPED_TEST(SphericalTests, Addition) { using T = TypeParam; using Spherical = SphericalOf; using Angle = AngleOf; Spherical v1 = Spherical(1, Angle::Degrees(45), Angle::Degrees(0)); Spherical v2 = Spherical::zero; Spherical r = Spherical::zero; r = v1 + v2; EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0 0)"; r = v1; r += v2; EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0 0)"; v2 = Spherical(1, Angle::Degrees(-45), Angle::Degrees(0)); r = v1 + v2; EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 -45 0)"; EXPECT_FLOAT_EQ(r.direction.horizontal.InDegrees(), 0) << "Addition(1 -45 0)"; EXPECT_FLOAT_EQ(r.direction.vertical.InDegrees(), 0) << "Addition(1 -45 0)"; v2 = Spherical(1, Angle::Degrees(0), Angle::Degrees(90)); r = v1 + v2; EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 0 90)"; EXPECT_FLOAT_EQ(r.direction.horizontal.InDegrees(), 45) << "Addition(1 0 90)"; EXPECT_FLOAT_EQ(r.direction.vertical.InDegrees(), 45) << "Addition(1 0 90)"; } TYPED_TEST(SphericalTests, AdditionPerformance) { using T = TypeParam; using Spherical = SphericalOf; const int numIterations = 1000000; // Number of additions to test std::vector sphericalObjects; // Populate the vector with random SphericalOf objects for (int i = 0; i < numIterations; ++i) { float distance = (float)(rand() % 100); float horizontal = (float)(rand() % 180); float vertical = (float)(rand() % 360); Spherical s = Spherical::Deg(distance, horizontal, vertical); sphericalObjects.push_back(s); } // Measure the time to perform multiple additions auto start = std::chrono::high_resolution_clock::now(); Spherical result = Spherical::zero; // Start with a // zero-initialized object for (int i = 0; i < numIterations - 1; ++i) { result = result + sphericalObjects[i]; // Add objects // together } auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration duration = end - start; std::cout << "Time to perform " << numIterations - 1 << " additions: " << duration.count() << " seconds." << std::endl; // Assert that the time taken is less than // 1 second (or any other performance // requirement) ASSERT_LE(duration.count(), 2.0) << "Performance test failed: " "Additions took longer than 1 " "second."; } #endif