TEST(Vector3, BinaryOperators) {
    Vector3F vec(3.f, 9.f, 4.f);
    vec = vec + 4.f;
    EXPECT_FLOAT_EQ(7.f, vec.x);
    EXPECT_FLOAT_EQ(13.f, vec.y);
    EXPECT_FLOAT_EQ(8.f, vec.z);

    vec = vec + Vector3F(-2.f, 1.f, 5.f);
    EXPECT_FLOAT_EQ(5.f, vec.x);
    EXPECT_FLOAT_EQ(14.f, vec.y);
    EXPECT_FLOAT_EQ(13.f, vec.z);

    vec = vec - 8.f;
    EXPECT_FLOAT_EQ(-3.f, vec.x);
    EXPECT_FLOAT_EQ(6.f, vec.y);
    EXPECT_FLOAT_EQ(5.f, vec.z);

    vec = vec - Vector3F(-5.f, 3.f, 12.f);
    EXPECT_FLOAT_EQ(2.f, vec.x);
    EXPECT_FLOAT_EQ(3.f, vec.y);
    EXPECT_FLOAT_EQ(-7.f, vec.z);

    vec = vec * 2.f;
    EXPECT_FLOAT_EQ(4.f, vec.x);
    EXPECT_FLOAT_EQ(6.f, vec.y);
    EXPECT_FLOAT_EQ(-14.f, vec.z);

    vec = vec * Vector3F(3.f, -2.f, 0.5f);
    EXPECT_FLOAT_EQ(12.f, vec.x);
    EXPECT_FLOAT_EQ(-12.f, vec.y);
    EXPECT_FLOAT_EQ(-7.f, vec.z);

    vec = vec / 4.f;
    EXPECT_FLOAT_EQ(3.f, vec.x);
    EXPECT_FLOAT_EQ(-3.f, vec.y);
    EXPECT_FLOAT_EQ(-1.75f, vec.z);

    vec = vec / Vector3F(3.f, -1.f, 0.25f);
    EXPECT_FLOAT_EQ(1.f, vec.x);
    EXPECT_FLOAT_EQ(3.f, vec.y);
    EXPECT_FLOAT_EQ(-7.f, vec.z);

    Vector3D v = Vector3D(2.0, 1.0, 3.0).normalized();
    Vector3D normal = Vector3D(1.0, 1.0, 1.0).normalized();

    Vector3D reflected = v.reflected(normal);
    Vector3D reflectedAnswer = Vector3D(-2.0, -3.0, -1.0).normalized();
    EXPECT_NEAR(reflected.distanceTo(reflectedAnswer), 0.0, 1e-9);

    Vector3D projected = v.projected(normal);
    EXPECT_NEAR(projected.dot(normal), 0.0, 1e-9);

    auto tangential = normal.tangential();
    EXPECT_NEAR(std::get<0>(tangential).dot(normal), 0.0, 1e-9);
    EXPECT_NEAR(std::get<1>(tangential).dot(normal), 0.0, 1e-9);
}