#include "fesa/math/vector3.h" #include #include #include namespace fesa { namespace { TEST(Vector3, StoresComponentsWithExactArithmetic) { constexpr Vector3 zero; static_assert(zero.X() == 0.0); static_assert(zero.Y() == 0.0); static_assert(zero.Z() == 0.0); constexpr Vector3 lhs{1.0, -2.0, 3.0}; constexpr Vector3 rhs{-4.0, 5.0, 6.0}; constexpr Vector3 sum = lhs + rhs; constexpr Vector3 difference = lhs - rhs; constexpr Vector3 scaled = lhs * -2.0; EXPECT_DOUBLE_EQ(lhs.X(), 1.0); EXPECT_DOUBLE_EQ(lhs.Y(), -2.0); EXPECT_DOUBLE_EQ(lhs.Z(), 3.0); EXPECT_DOUBLE_EQ(lhs[0], 1.0); EXPECT_DOUBLE_EQ(lhs[1], -2.0); EXPECT_DOUBLE_EQ(lhs[2], 3.0); EXPECT_DOUBLE_EQ(sum[0], -3.0); EXPECT_DOUBLE_EQ(sum[1], 3.0); EXPECT_DOUBLE_EQ(sum[2], 9.0); EXPECT_DOUBLE_EQ(difference[0], 5.0); EXPECT_DOUBLE_EQ(difference[1], -7.0); EXPECT_DOUBLE_EQ(difference[2], -3.0); EXPECT_DOUBLE_EQ(scaled[0], -2.0); EXPECT_DOUBLE_EQ(scaled[1], 4.0); EXPECT_DOUBLE_EQ(scaled[2], -6.0); } TEST(Vector3, ComputesDotProduct) { const Vector3 lhs{1.0, 2.0, 3.0}; const Vector3 rhs{4.0, -5.0, 6.0}; EXPECT_DOUBLE_EQ(lhs.Dot(rhs), 12.0); } TEST(Vector3, UsesRightHandedCrossProductOrientation) { const Vector3 x_axis{1.0, 0.0, 0.0}; const Vector3 y_axis{0.0, 1.0, 0.0}; const Vector3 positive_z = x_axis.Cross(y_axis); const Vector3 negative_z = y_axis.Cross(x_axis); EXPECT_DOUBLE_EQ(positive_z.X(), 0.0); EXPECT_DOUBLE_EQ(positive_z.Y(), 0.0); EXPECT_DOUBLE_EQ(positive_z.Z(), 1.0); EXPECT_DOUBLE_EQ(negative_z.X(), 0.0); EXPECT_DOUBLE_EQ(negative_z.Y(), 0.0); EXPECT_DOUBLE_EQ(negative_z.Z(), -1.0); } TEST(Vector3, ComputesEuclideanNorm) { EXPECT_DOUBLE_EQ(Vector3(2.0, -3.0, 6.0).Norm(), 7.0); } TEST(Vector3, NormalizesNonzeroVectors) { const std::optional normalized = Vector3(3.0, 0.0, 4.0).Normalized(); ASSERT_TRUE(normalized.has_value()); EXPECT_DOUBLE_EQ(normalized->X(), 0.6); EXPECT_DOUBLE_EQ(normalized->Y(), 0.0); EXPECT_DOUBLE_EQ(normalized->Z(), 0.8); } TEST(Vector3, ReportsFiniteComponents) { const double infinity = std::numeric_limits::infinity(); const double not_a_number = std::numeric_limits::quiet_NaN(); EXPECT_TRUE(Vector3(1.0, -2.0, 3.0).IsFinite()); EXPECT_FALSE(Vector3(infinity, 0.0, 0.0).IsFinite()); EXPECT_FALSE(Vector3(0.0, not_a_number, 0.0).IsFinite()); } TEST(Vector3, RejectsZeroAndNonfiniteNormalization) { const double infinity = std::numeric_limits::infinity(); const double not_a_number = std::numeric_limits::quiet_NaN(); EXPECT_FALSE(Vector3().Normalized().has_value()); EXPECT_FALSE(Vector3(infinity, 0.0, 0.0).Normalized().has_value()); EXPECT_FALSE(Vector3(0.0, not_a_number, 0.0).Normalized().has_value()); } } // namespace } // namespace fesa