[WIP] tests transform it into BDD Style
This commit is contained in:
@@ -35,318 +35,594 @@ using namespace Raytracer;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] a tuple with w=1.0 is a point", "[Tuple]")
|
||||
SCENARIO("A tuple with w=1.0 is a point", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a(4.3, -4.2, 3.1, 1.0);
|
||||
|
||||
REQUIRE(a.x() == 4.3);
|
||||
REQUIRE(a.y() == -4.2);
|
||||
REQUIRE(a.z() == 3.1);
|
||||
REQUIRE(a.w() == 1.0);
|
||||
|
||||
REQUIRE(a.is_point() == true);
|
||||
REQUIRE(a.is_vector() == false);
|
||||
GIVEN("A tuple with w=1.0 is a point")
|
||||
{
|
||||
Tuple a(4.3, -4.2, 3.1, 1.0);
|
||||
THEN("a.x = 4.3")
|
||||
{
|
||||
REQUIRE(a.x() == 4.3);
|
||||
}
|
||||
AND_THEN("a.y = -4.2")
|
||||
{
|
||||
REQUIRE(a.y() == -4.2);
|
||||
}
|
||||
AND_THEN("a.z = 3.1")
|
||||
{
|
||||
REQUIRE(a.z() == 3.1);
|
||||
}
|
||||
AND_THEN("a.w = 1.0")
|
||||
{
|
||||
REQUIRE(a.w() == 1.0);
|
||||
}
|
||||
AND_THEN("a is a point")
|
||||
{
|
||||
REQUIRE(a.is_point() == true);
|
||||
}
|
||||
AND_THEN("a is not a vector")
|
||||
{
|
||||
REQUIRE(a.is_vector() == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] a tuple with w=0 is a vector", "[Tuple]")
|
||||
SCENARIO("A tuple with w=0 is a vector", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a(4.3, -4.2, 3.1, 0.0);
|
||||
|
||||
REQUIRE(a.x() == 4.3);
|
||||
REQUIRE(a.y() == -4.2);
|
||||
REQUIRE(a.z() == 3.1);
|
||||
REQUIRE(a.w() == 0.0);
|
||||
|
||||
REQUIRE(a.is_point() == false);
|
||||
GIVEN("a <-tuple(4.3, -4.2, 3.1, 0.0)")
|
||||
{
|
||||
Tuple a(4.3, -4.2, 3.1, 0.0);
|
||||
THEN("a.x = 4.3")
|
||||
{
|
||||
REQUIRE(a.x() == 4.3);
|
||||
}
|
||||
AND_THEN("a.y = -4.2")
|
||||
{
|
||||
REQUIRE(a.y() == -4.2);
|
||||
}
|
||||
AND_THEN("a.z = 3.1")
|
||||
{
|
||||
REQUIRE(a.z() == 3.1);
|
||||
}
|
||||
AND_THEN("a.w = 0.0")
|
||||
{
|
||||
REQUIRE(a.w() == 0.0);
|
||||
}
|
||||
AND_THEN("a is not a point")
|
||||
{
|
||||
REQUIRE(a.is_point() == false);
|
||||
}
|
||||
AND_THEN("a is a vector")
|
||||
{
|
||||
REQUIRE(a.is_vector() == true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] access of data with []", "[Tuple]")
|
||||
SCENARIO("Access of data with []", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a(4.3, -4.2, 3.1, 0.0);
|
||||
|
||||
REQUIRE(a[0] == 4.3);
|
||||
REQUIRE(a[1] == -4.2);
|
||||
REQUIRE(a[2] == 3.1);
|
||||
REQUIRE(a[3] == 0.0);
|
||||
GIVEN(" a <- tuple(4.3, -4.2, 3.1, 0.0)")
|
||||
{
|
||||
Tuple a(4.3, -4.2, 3.1, 0.0);
|
||||
THEN("a[0] = 4.3")
|
||||
{
|
||||
REQUIRE(a[0] == 4.3);
|
||||
}
|
||||
AND_THEN("a[1] = -4.2")
|
||||
{
|
||||
REQUIRE(a[1] == -4.2);
|
||||
}
|
||||
AND_THEN("a[2] = 3.1")
|
||||
{
|
||||
REQUIRE(a[2] == 3.1);
|
||||
}
|
||||
AND_THEN("a[3] = 0.0")
|
||||
{
|
||||
REQUIRE(a[3] == 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] constructor with std::vector", "[Tuple]")
|
||||
SCENARIO("A constructor with std::vector", "[features/tuples.feature]")
|
||||
{
|
||||
std::vector<double> v = {4.3, -4.2, 3.1, 0.0};
|
||||
Tuple a(v);
|
||||
GIVEN(" a <- tuple with {4.3, -4.2, 3.1, 0.0}")
|
||||
{
|
||||
std::vector<double> v = {4.3, -4.2, 3.1, 0.0};
|
||||
Tuple a(v);
|
||||
|
||||
REQUIRE(a[0] == 4.3);
|
||||
REQUIRE(a[1] == -4.2);
|
||||
REQUIRE(a[2] == 3.1);
|
||||
REQUIRE(a[3] == 0.0);
|
||||
THEN("a[0] = 4.3")
|
||||
{
|
||||
REQUIRE(a[0] == 4.3);
|
||||
}
|
||||
AND_THEN("a[1] = -4.2")
|
||||
{
|
||||
REQUIRE(a[1] == -4.2);
|
||||
}
|
||||
AND_THEN("a[2] = 3.1")
|
||||
{
|
||||
REQUIRE(a[2] == 3.1);
|
||||
}
|
||||
AND_THEN("a[3] = 0.0")
|
||||
{
|
||||
REQUIRE(a[3] == 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] test copy constructor", "[Tuple]")
|
||||
SCENARIO("A test copy constructor", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a;
|
||||
Tuple b(4.3, -4.2, 3.1, 0.0);
|
||||
|
||||
a = b;
|
||||
|
||||
REQUIRE(a[0] == 4.3);
|
||||
REQUIRE(a[1] == -4.2);
|
||||
REQUIRE(a[2] == 3.1);
|
||||
REQUIRE(a[3] == 0.0);
|
||||
GIVEN(" a <- tuple(4.3, -4.2, 3.1, 0.0)")
|
||||
{
|
||||
Tuple a(4.3, -4.2, 3.1, 0.0);
|
||||
AND_GIVEN(" b <- tuple")
|
||||
{
|
||||
Tuple b;
|
||||
WHEN("b = a")
|
||||
{
|
||||
b = a;
|
||||
THEN("b[0] = 4.3")
|
||||
{
|
||||
REQUIRE(b[0] == 4.3);
|
||||
}
|
||||
AND_THEN("b[1] = -4.2")
|
||||
{
|
||||
REQUIRE(b[1] == -4.2);
|
||||
}
|
||||
AND_THEN("b[2] = 3.1")
|
||||
{
|
||||
REQUIRE(b[2] == 3.1);
|
||||
}
|
||||
AND_THEN("b[3] = 0.0")
|
||||
{
|
||||
REQUIRE(b[3] == 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Tuple could be copy", "[Tuple]")
|
||||
SCENARIO("Tuple could be copy", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple p = Tuple::Point(4, -4, 3);
|
||||
Tuple n;
|
||||
|
||||
n = p;
|
||||
|
||||
REQUIRE(n == p);
|
||||
GIVEN("p <-point(4, -4, 3)")
|
||||
{
|
||||
Tuple p = Tuple::Point(4, -4, 3);
|
||||
Tuple n;
|
||||
WHEN("n <- p")
|
||||
{
|
||||
n = p;
|
||||
THEN(" n = p")
|
||||
{
|
||||
REQUIRE(n == p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Point() creates tuples with w=1", "[Tuple][Point]")
|
||||
SCENARIO("Point() creates tuples with w=1", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple p = Tuple::Point(4, -4, 3);
|
||||
|
||||
REQUIRE(p == Tuple(4, -4, 3, 1));
|
||||
GIVEN("p <-point(4, -4, 3)")
|
||||
{
|
||||
Tuple p = Tuple::Point(4, -4, 3);
|
||||
THEN("p = tuple(4,-4, 3, 1)")
|
||||
{
|
||||
REQUIRE(p == Tuple(4, -4, 3, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Vector() creates tuples with w=0", "[Tuple][Vector]")
|
||||
SCENARIO("Vector() creates tuples with w=0", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(4, -4, 3);
|
||||
|
||||
REQUIRE(v == Tuple(4, -4, 3, 0));
|
||||
GIVEN("v <-vector(4, -4, 3)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(4, -4, 3);
|
||||
THEN("v = tuple(4,-4, 3, 1)")
|
||||
{
|
||||
REQUIRE(v == Tuple(4, -4, 3, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Adding two tuples", "[Tuple][Operations]")
|
||||
SCENARIO("Adding two tuples", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a1(3, -2, 5, 1);
|
||||
Tuple a2(-2, 3, 1, 0);
|
||||
|
||||
REQUIRE((a1 + a2) == Tuple(1, 1, 6, 1));
|
||||
GIVEN("a1 <-tuple(3, -2, 5, 1)")
|
||||
{
|
||||
Tuple a1(3, -2, 5, 1);
|
||||
AND_GIVEN("a2 <- tuple(-2, 3, 1, 0)")
|
||||
{
|
||||
Tuple a2(-2, 3, 1, 0);
|
||||
THEN("a1 + a2 = tuple(1, 1, 6, 1)")
|
||||
{
|
||||
REQUIRE((a1 + a2) == Tuple(1, 1, 6, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Adding two tuples without modify a1", "[Tuple][Operations]")
|
||||
SCENARIO("Adding two tuples without modify a1", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a1(3, -2, 5, 1);
|
||||
Tuple a2(-2, 3, 1, 0);
|
||||
|
||||
Tuple a3 = a1 + a2;
|
||||
|
||||
REQUIRE((a1 + a2) == Tuple(1, 1, 6, 1));
|
||||
GIVEN("a1 <-tuple(3, -2, 5, 1)")
|
||||
{
|
||||
Tuple a1(3, -2, 5, 1);
|
||||
AND_GIVEN("a2 <- tuple(-2, 3, 1, 0)")
|
||||
{
|
||||
Tuple a2(-2, 3, 1, 0);
|
||||
WHEN("a3 = a1 + a2")
|
||||
{
|
||||
Tuple a3 = a1 + a2;
|
||||
THEN("a1 + a2 = tuple(1, 1, 6, 1)")
|
||||
{
|
||||
REQUIRE((a1 + a2) == Tuple(1, 1, 6, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Subtracting two points", "[Tuple][Operations]")
|
||||
SCENARIO("Subtracting two points", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple p1 = Tuple::Point(3, 2, 1);
|
||||
Tuple p2 = Tuple::Point(5, 6, 7);
|
||||
|
||||
REQUIRE((p1 - p2) == Tuple::Vector(-2, -4, -6));
|
||||
GIVEN("p1 <- point(3, 2, 1)")
|
||||
{
|
||||
Tuple p1 = Tuple::Point(3, 2, 1);
|
||||
AND_GIVEN("p2 <- point(5, 6, 7)")
|
||||
{
|
||||
Tuple p2 = Tuple::Point(5, 6, 7);
|
||||
THEN("p1 - p2 = vector(-2, -4, -6)")
|
||||
{
|
||||
REQUIRE((p1 - p2) == Tuple::Vector(-2, -4, -6));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Subtracting two points without modify p1", "[Tuple][Operations]")
|
||||
SCENARIO("Subtracting two points without modify p1", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple p1 = Tuple::Point(3, 2, 1);
|
||||
Tuple p2 = Tuple::Point(5, 6, 7);
|
||||
GIVEN("p1 <- point(3, 2, 1)")
|
||||
{
|
||||
Tuple p1 = Tuple::Point(3, 2, 1);
|
||||
AND_GIVEN("p2 <- point(5, 6, 7)")
|
||||
{
|
||||
Tuple p2 = Tuple::Point(5, 6, 7);
|
||||
|
||||
Tuple p3 = p1 - p2;
|
||||
|
||||
REQUIRE((p1 - p2) == Tuple::Vector(-2, -4, -6));
|
||||
WHEN("p3 = p1 - p2")
|
||||
{
|
||||
Tuple p3 = p1 - p2;
|
||||
THEN("(p1 - p2) = vector(-2, -4, -6)")
|
||||
{
|
||||
REQUIRE((p1 - p2) == Tuple::Vector(-2, -4, -6));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Subtracting a vector from a point", "[Tuple][Operations]")
|
||||
SCENARIO("Subtracting a vector from a point", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple p = Tuple::Point(3, 2, 1);
|
||||
Tuple v = Tuple::Vector(5, 6, 7);
|
||||
GIVEN("p <- point(3, 2, 1)")
|
||||
{
|
||||
Tuple p = Tuple::Point(3, 2, 1);
|
||||
|
||||
REQUIRE((p - v) == Tuple::Point(-2, -4, -6));
|
||||
AND_GIVEN("v <-vector(5, 6, 7)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(5, 6, 7);
|
||||
THEN("p - v = point(-2, -4, -6)")
|
||||
{
|
||||
REQUIRE((p - v) == Tuple::Point(-2, -4, -6));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Subtracting two vectors", "[Tuple][Operations]")
|
||||
SCENARIO("Subtracting two vectors", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple v1 = Tuple::Vector(3, 2, 1);
|
||||
Tuple v2 = Tuple::Vector(5, 6, 7);
|
||||
|
||||
REQUIRE((v1 - v2) == Tuple::Vector(-2, -4, -6));
|
||||
GIVEN("v1 <-vector(3, 2, 1)")
|
||||
{
|
||||
Tuple v1 = Tuple::Vector(3, 2, 1);
|
||||
AND_GIVEN("v2 <-vector(5, 6, 7)")
|
||||
{
|
||||
Tuple v2 = Tuple::Vector(5, 6, 7);
|
||||
THEN("v1 - v2 = vector(-2, -4, -6)")
|
||||
{
|
||||
REQUIRE((v1 - v2) == Tuple::Vector(-2, -4, -6));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Subtracting a vector from the zero vector", "[Tuple][Operations]")
|
||||
SCENARIO("Subtracting a vector from the zero vector", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple zero = Tuple::Vector(0, 0, 0);
|
||||
Tuple v = Tuple::Vector(1, -2, 3);
|
||||
|
||||
REQUIRE((zero - v) == Tuple::Vector(-1, 2, -3));
|
||||
GIVEN("zero <-vector(0, 0, 0)")
|
||||
{
|
||||
Tuple zero = Tuple::Vector(0, 0, 0);
|
||||
AND_GIVEN("v <-vector(1, -2, 3)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(1, -2, 3);
|
||||
THEN("zero - v = vector(-1, 2, -3)")
|
||||
{
|
||||
REQUIRE((zero - v) == Tuple::Vector(-1, 2, -3));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Negative a tuple", "[Tuple][Operations]")
|
||||
SCENARIO("Negative a tuple", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a(1, -2, 3, -4);
|
||||
|
||||
REQUIRE(-a == Tuple(-1, 2, -3, 4));
|
||||
GIVEN("a <-tuple(1, -2, 3, -4)")
|
||||
{
|
||||
Tuple a(1, -2, 3, -4);
|
||||
THEN("-a = tuple(-1, 2, -3, 4)")
|
||||
{
|
||||
REQUIRE(-a == Tuple(-1, 2, -3, 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Multiplying a tuple by a scalar", "[Tuple][Multiplication]")
|
||||
SCENARIO("Multiplying a tuple by a scalar", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a(1, -2, 3, -4);
|
||||
|
||||
REQUIRE(a * 3.5 == Tuple(3.5, -7, 10.5, -14));
|
||||
GIVEN("a <-tuple(1, -2, 3, -4)")
|
||||
{
|
||||
Tuple a(1, -2, 3, -4);
|
||||
THEN("a * 3.5 = tuple(3.5, -7, 10.5, -14)")
|
||||
{
|
||||
REQUIRE(a * 3.5 == Tuple(3.5, -7, 10.5, -14));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Multiplying a tuple by a scalar without modify a", "[Tuple][Multiplication]")
|
||||
SCENARIO("Multiplying a tuple by a scalar without modify a", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a(1, -2, 3, -4);
|
||||
|
||||
Tuple b = a * 3.5;
|
||||
|
||||
REQUIRE(a * 3.5 == Tuple(3.5, -7, 10.5, -14));
|
||||
GIVEN("a <-tuple(1, -2, 3, -4)")
|
||||
{
|
||||
Tuple a(1, -2, 3, -4);
|
||||
WHEN("b = a * 3.5;")
|
||||
{
|
||||
Tuple b = a * 3.5;
|
||||
THEN("a * 3.5 = tuple(3.5, -7, 10.5, -14)")
|
||||
{
|
||||
REQUIRE(a * 3.5 == Tuple(3.5, -7, 10.5, -14));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Dividing a tuple by a scalar", "[Tuple][Multiplication]")
|
||||
SCENARIO("Multiplying a tuple by a fraction", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a(1, -2, 3, -4);
|
||||
|
||||
REQUIRE(a / 2 == Tuple(0.5, -1, 1.5, -2));
|
||||
GIVEN("a <-tuple(1, -2, 3, -4)")
|
||||
{
|
||||
Tuple a(1, -2, 3, -4);
|
||||
THEN("a * 0.5 = tuple(0.5, -1, 1.5, -2)")
|
||||
{
|
||||
REQUIRE(a * 0.5 == Tuple(0.5, -1, 1.5, -2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Dividing a tuple by a scalar without modify a", "[Tuple][Multiplication]")
|
||||
SCENARIO("Dividing a tuple by a scalar", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a(1, -2, 3, -4);
|
||||
|
||||
Tuple b = a / 2;
|
||||
|
||||
REQUIRE(a / 2 == Tuple(0.5, -1, 1.5, -2));
|
||||
GIVEN("a <-tuple(1, -2, 3, -4)")
|
||||
{
|
||||
Tuple a(1, -2, 3, -4);
|
||||
THEN("a / 2 = tuple(0.5, -1, 1.5, -2)")
|
||||
{
|
||||
REQUIRE(a / 2 == Tuple(0.5, -1, 1.5, -2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Computing the magnitude of vector(1,0,0)", "[Tuple][Magnitude]")
|
||||
SCENARIO("Dividing a tuple by a scalar without modify a", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(1, 0, 0);
|
||||
|
||||
REQUIRE(v.magnitude() == 1);
|
||||
GIVEN("a <-tuple(1, -2, 3, -4)")
|
||||
{
|
||||
Tuple a(1, -2, 3, -4);
|
||||
WHEN("b = a / 2")
|
||||
{
|
||||
Tuple b = a / 2;
|
||||
THEN("a / 2 = tuple(0.5, -1, 1.5, -2)")
|
||||
{
|
||||
REQUIRE(a / 2 == Tuple(0.5, -1, 1.5, -2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Computing the magnitude of vector(0,1,0)", "[Tuple][Magnitude]")
|
||||
SCENARIO("Computing the magnitude of vector(1,0,0)", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(0, 1, 0);
|
||||
|
||||
REQUIRE(v.magnitude() == 1);
|
||||
GIVEN("v <-vector(1, 0, 0)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(1, 0, 0);
|
||||
THEN("magnitude(v) = 1")
|
||||
{
|
||||
REQUIRE(v.magnitude() == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Computing the magnitude of vector(0,0,1)", "[Tuple][Magnitude]")
|
||||
SCENARIO("Computing the magnitude of vector(0,1,0)", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(0, 0, 1);
|
||||
GIVEN("v <-vector(0, 1, 0)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(0, 1, 0);
|
||||
|
||||
REQUIRE(v.magnitude() == 1);
|
||||
THEN("magnitude(v) = 1")
|
||||
{
|
||||
REQUIRE(v.magnitude() == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Computing the magnitude of vector(1,2,3)", "[Tuple][Magnitude]")
|
||||
SCENARIO("Computing the magnitude of vector(0,0,1)", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(1, 2, 3);
|
||||
GIVEN("v <-vector(0, 0, 1)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(0, 0, 1);
|
||||
|
||||
REQUIRE(v.magnitude() == sqrt(14));
|
||||
THEN("magnitude(v) = 1")
|
||||
{
|
||||
REQUIRE(v.magnitude() == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Computing the magnitude of vector(-1,-2,-3)", "[Tuple][Magnitude]")
|
||||
SCENARIO("Computing the magnitude of vector(1,2,3)", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(-1, -2, -3);
|
||||
GIVEN("v <-vector(1, 2, 3)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(1, 2, 3);
|
||||
|
||||
REQUIRE(v.magnitude() == sqrt(14));
|
||||
THEN("magnitude(v) = sqrt(14)")
|
||||
{
|
||||
REQUIRE(v.magnitude() == sqrt(14));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Normalize vector(4,0,0) gives (1,0,0)", "[Tuple][Normalize]")
|
||||
SCENARIO("Computing the magnitude of vector(-1,-2,-3)", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(4, 0, 0);
|
||||
GIVEN("v <-vector(-1, -2, -3)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(-1, -2, -3);
|
||||
|
||||
REQUIRE(v.normalize() == Tuple::Vector(1, 0, 0));
|
||||
THEN("magnitude(v) = sqrt(14)")
|
||||
{
|
||||
REQUIRE(v.magnitude() == sqrt(14));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] Normalize vector(1,2,3)", "[Tuple][Normalize]")
|
||||
SCENARIO("Normalize vector(4,0,0) gives (1,0,0)", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(1, 2, 3);
|
||||
|
||||
REQUIRE(v.normalize() == Tuple::Vector(1 / sqrtf(14), 2 / sqrtf(14), 3 / sqrtf(14)));
|
||||
GIVEN("v <-vector(4, 0, 0)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(4, 0, 0);
|
||||
THEN("normalize(v) = vector(1, 0, 0)")
|
||||
{
|
||||
REQUIRE(v.normalize() == Tuple::Vector(1, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] The magnitude of a normalized vector", "[Tuple][Normalize]")
|
||||
SCENARIO("Normalize vector(1,2,3)", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple norm;
|
||||
Tuple v = Tuple::Vector(1, 2, 3);
|
||||
|
||||
norm = v.normalize();
|
||||
|
||||
REQUIRE(norm.magnitude() == 1);
|
||||
GIVEN("v <-vector(1, 2, 3)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(1, 2, 3);
|
||||
// vector (1/sqrt(14), 2/sqrt(14), 3/sqrt(14))
|
||||
THEN("normalize(v) = approximately vector(0.26726, 0.53452, 0.80178)")
|
||||
{
|
||||
REQUIRE(v.normalize() == Tuple::Vector(1 / sqrtf(14), 2 / sqrtf(14), 3 / sqrtf(14)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] The dot product of two tuples", "[Tuple][Dot]")
|
||||
SCENARIO("The magnitude of a normalized vector", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a = Tuple::Vector(1, 2, 3);
|
||||
Tuple b = Tuple::Vector(2, 3, 4);
|
||||
|
||||
REQUIRE(a.dot(b) == 20);
|
||||
GIVEN("v <-vector(1, 2, 3)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(1, 2, 3);
|
||||
Tuple norm;
|
||||
WHEN("norm <- normalize(v)")
|
||||
{
|
||||
norm = v.normalize();
|
||||
THEN("magnitude(norm) = 1")
|
||||
{
|
||||
REQUIRE(norm.magnitude() == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[01][Tuple] The cross product of two vector", "[Tuple][Cross]")
|
||||
SCENARIO("The dot product of two tuples", "[features/tuples.feature]")
|
||||
{
|
||||
Tuple a = Tuple::Vector(1, 2, 3);
|
||||
Tuple b = Tuple::Vector(2, 3, 4);
|
||||
GIVEN("a <-vector(1, 2, 3)")
|
||||
{
|
||||
Tuple a = Tuple::Vector(1, 2, 3);
|
||||
|
||||
REQUIRE(a.cross(b) == Tuple::Vector(-1, 2, -1));
|
||||
REQUIRE(b.cross(a) == Tuple::Vector(1, -2, 1));
|
||||
AND_GIVEN("b <-vector(2, 3, 4)")
|
||||
{
|
||||
Tuple b = Tuple::Vector(2, 3, 4);
|
||||
THEN("dot(a,b) = 20")
|
||||
{
|
||||
REQUIRE(a.dot(b) == 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
SCENARIO("The cross product of two vectors", "[features/tuples.feature]")
|
||||
{
|
||||
GIVEN("a <-vector(1, 2, 3)")
|
||||
{
|
||||
Tuple a = Tuple::Vector(1, 2, 3);
|
||||
AND_GIVEN("b <-vector(2, 3, 4)")
|
||||
{
|
||||
Tuple b = Tuple::Vector(2, 3, 4);
|
||||
THEN("cross(a,b) = vector(-1, 2, -1)")
|
||||
{
|
||||
REQUIRE(a.cross(b) == Tuple::Vector(-1, 2, -1));
|
||||
}
|
||||
AND_THEN("cross(b,a) = vector(1, -2, -1)")
|
||||
{
|
||||
REQUIRE(b.cross(a) == Tuple::Vector(1, -2, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,99 +33,184 @@ using namespace Raytracer;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][01][Color] colors are (red,green,blue) tuples", "[Colors]")
|
||||
SCENARIO("Colors are (red,green,blue) tuples", "[features/tuples.feature]")
|
||||
{
|
||||
Color c(-0.5, 0.4, 1.7);
|
||||
|
||||
REQUIRE(c.red() == -0.5);
|
||||
REQUIRE(c.green() == 0.4);
|
||||
REQUIRE(c.blue() == 1.7);
|
||||
GIVEN("c <-color(-0.5, 0.4, 1.7)")
|
||||
{
|
||||
Color c(-0.5, 0.4, 1.7);
|
||||
THEN("c.red = -0.5")
|
||||
{
|
||||
REQUIRE(c.red() == -0.5);
|
||||
}
|
||||
AND_THEN("c.green = 0.4")
|
||||
{
|
||||
REQUIRE(c.green() == 0.4);
|
||||
}
|
||||
AND_THEN("c.blue = 1.7")
|
||||
{
|
||||
REQUIRE(c.blue() == 1.7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][01][Color] Colors could be copied", "[Colors]")
|
||||
SCENARIO("Colors could be copied", "[features/tuples.feature]")
|
||||
{
|
||||
Color c1(-0.5, 0.4, 1.7);
|
||||
Color c2;
|
||||
|
||||
c2 = c1;
|
||||
|
||||
REQUIRE(c2.red() == -0.5);
|
||||
REQUIRE(c2.green() == 0.4);
|
||||
REQUIRE(c2.blue() == 1.7);
|
||||
GIVEN("c1 <-color(-0.5, 0.4, 1.7)")
|
||||
{
|
||||
Color c1(-0.5, 0.4, 1.7);
|
||||
AND_GIVEN("c2 <-color")
|
||||
{
|
||||
Color c2;
|
||||
WHEN("c2 <- c1")
|
||||
{
|
||||
c2 = c1;
|
||||
THEN("c2.red = -0.5")
|
||||
{
|
||||
REQUIRE(c2.red() == -0.5);
|
||||
}
|
||||
AND_THEN("c2.green = 0.4")
|
||||
{
|
||||
REQUIRE(c2.green() == 0.4);
|
||||
}
|
||||
AND_THEN("c2.blue = 1.7")
|
||||
{
|
||||
REQUIRE(c2.blue() == 1.7);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][01][Color] Adding colors", "[Colors]")
|
||||
SCENARIO("Adding colors", "[features/tuples.feature]")
|
||||
{
|
||||
Color c1(0.9, 0.6, 0.75);
|
||||
Color c2(0.7, 0.1, 0.25);
|
||||
GIVEN("c1 <-color(0.9, 0.6, 0.75)")
|
||||
{
|
||||
Color c1(0.9, 0.6, 0.75);
|
||||
AND_GIVEN("c2 <-color(0.7, 0.1, 0.25)")
|
||||
{
|
||||
Color c2(0.7, 0.1, 0.25);
|
||||
|
||||
REQUIRE((c1 + c2) == Color(1.6, 0.7, 1.0));
|
||||
THEN("c1 + c2 = color(1.6, 0.7, 1.0)")
|
||||
{
|
||||
REQUIRE((c1 + c2) == Color(1.6, 0.7, 1.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][01][Color] Adding colors without modify c1", "[Colors]")
|
||||
SCENARIO("Adding colors without modify c1", "[features/tuples.feature]")
|
||||
{
|
||||
Color c1(0.9, 0.6, 0.75);
|
||||
Color c2(0.7, 0.1, 0.25);
|
||||
|
||||
Color c3 = c1 + c2;
|
||||
|
||||
REQUIRE((c1 + c2) == Color(1.6, 0.7, 1.0));
|
||||
GIVEN("c1 <-color(0.9, 0.6, 0.75)")
|
||||
{
|
||||
Color c1(0.9, 0.6, 0.75);
|
||||
AND_GIVEN("c2 <-color(0.7, 0.1, 0.25)")
|
||||
{
|
||||
Color c2(0.7, 0.1, 0.25);
|
||||
WHEN("color c3 = c1 + c2")
|
||||
{
|
||||
Color c3 = c1 + c2;
|
||||
THEN("c1 + c2 = color(1.6, 0.7, 1.0)")
|
||||
{
|
||||
REQUIRE((c1 + c2) == Color(1.6, 0.7, 1.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][01][Color] Subtracting colors", "[Colors]")
|
||||
SCENARIO("Subtracting colors", "[features/tuples.feature]")
|
||||
{
|
||||
Color c1(0.9, 0.6, 0.75);
|
||||
Color c2(0.7, 0.1, 0.25);
|
||||
GIVEN("c1 <-color(0.9, 0.6, 0.75)")
|
||||
{
|
||||
Color c1(0.9, 0.6, 0.75);
|
||||
AND_GIVEN("c2 <-color(0.7, 0.1, 0.25)")
|
||||
{
|
||||
Color c2(0.7, 0.1, 0.25);
|
||||
|
||||
REQUIRE((c1 - c2) == Color(0.2, 0.5, 0.5));
|
||||
THEN("c1 - c2 = color(0.2, 0.5, 0.5)")
|
||||
{
|
||||
REQUIRE((c1 - c2) == Color(0.2, 0.5, 0.5));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][01][Color] Subtracting colors without modify c1", "[Colors]")
|
||||
SCENARIO("Subtracting colors without modify c1", "[features/tuples.feature]")
|
||||
{
|
||||
Color c1(0.9, 0.6, 0.75);
|
||||
Color c2(0.7, 0.1, 0.25);
|
||||
|
||||
Color c3 = c1 - c2;
|
||||
|
||||
REQUIRE((c1 - c2) == Color(0.2, 0.5, 0.5));
|
||||
GIVEN("c1 <-color(0.9, 0.6, 0.75)")
|
||||
{
|
||||
Color c1(0.9, 0.6, 0.75);
|
||||
AND_GIVEN("c2 <-color(0.7, 0.1, 0.25)")
|
||||
{
|
||||
Color c2(0.7, 0.1, 0.25);
|
||||
WHEN("color c3 = c1 - c2")
|
||||
{
|
||||
Color c3 = c1 - c2;
|
||||
THEN("c1 - c2 = color(0.2, 0.5, 0.5)")
|
||||
{
|
||||
REQUIRE((c1 - c2) == Color(0.2, 0.5, 0.5));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][01][Color] Multiplying a color by a scalar", "[Colors]")
|
||||
SCENARIO("Multiplying a color by a scalar", "[features/tuples.feature]")
|
||||
{
|
||||
Color c(0.2, 0.3, 0.4);
|
||||
|
||||
REQUIRE(c * 2 == Color(0.4, 0.6, 0.8));
|
||||
GIVEN("c <-color(0.2, 0.3, 0.4)")
|
||||
{
|
||||
Color c(0.2, 0.3, 0.4);
|
||||
THEN("c * 2 = color(0.4, 0.6, 0.8)")
|
||||
{
|
||||
REQUIRE(c * 2 == Color(0.4, 0.6, 0.8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][01][Color] Multiplying a color by a scalar without modify c", "[Colors]")
|
||||
SCENARIO("Multiplying a color by a scalar without modify c", "[features/tuples.feature]")
|
||||
{
|
||||
Color c(0.2, 0.3, 0.4);
|
||||
|
||||
Color c3 = c * 4;
|
||||
|
||||
REQUIRE(c * 2 == Color(0.4, 0.6, 0.8));
|
||||
GIVEN("c <-color(0.2, 0.3, 0.4)")
|
||||
{
|
||||
Color c(0.2, 0.3, 0.4);
|
||||
WHEN("color c3 = c * 4")
|
||||
{
|
||||
Color c3 = c * 4;
|
||||
THEN("c * 2 = color(0.4, 0.6, 0.8)")
|
||||
{
|
||||
REQUIRE(c * 2 == Color(0.4, 0.6, 0.8));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][01][Color] Multiplying a colors", "[Colors]")
|
||||
SCENARIO("Multiplying a colors", "[features/tuples.feature]")
|
||||
{
|
||||
Color c1(1, 0.2, 0.4);
|
||||
Color c2(0.9, 1, 0.1);
|
||||
|
||||
REQUIRE((c1 * c2) == Color(0.9, 0.2, 0.04));
|
||||
GIVEN("c1 <-color(1, 0.2, 0.4)")
|
||||
{
|
||||
Color c1(1, 0.2, 0.4);
|
||||
AND_GIVEN("c2 <-color(0.9, 1, 0.1)")
|
||||
{
|
||||
Color c2(0.9, 1, 0.1);
|
||||
THEN("c1 * c2 = color(0.9, 0.2, 0.04)")
|
||||
{
|
||||
REQUIRE((c1 * c2) == Color(0.9, 0.2, 0.04));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,80 +33,136 @@ using namespace Raytracer;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][02][Canvas] Creating a canvas", "[Canvas]")
|
||||
SCENARIO("Creating a canvas", "[features/canvas.feature]")
|
||||
{
|
||||
Canvas c(10, 20);
|
||||
|
||||
REQUIRE(c.width() == 10);
|
||||
REQUIRE(c.height() == 20);
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
GIVEN("c <-canvas(10, 20)")
|
||||
{
|
||||
for (int j = 0; j < 20; ++j)
|
||||
Canvas c(10, 20);
|
||||
THEN("c.width = 10")
|
||||
{
|
||||
REQUIRE(c.pixel_at(2, 3) == Color(0, 0, 0));
|
||||
REQUIRE(c.width() == 10);
|
||||
}
|
||||
AND_THEN("c.height = 20")
|
||||
{
|
||||
REQUIRE(c.height() == 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][02][Canvas] Writing pixels to a canvas", "[Canvas]")
|
||||
{
|
||||
Canvas c(10, 20);
|
||||
Color red(1, 0, 0);
|
||||
|
||||
c.write_pixel(2, 3, red);
|
||||
|
||||
REQUIRE(c.pixel_at(2, 3) == red);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][02][Canvas] Constructing the PPM pixel data", "[Canvas]")
|
||||
{
|
||||
std::string ppm, the_ref_ppm;
|
||||
Canvas c(5, 3);
|
||||
Color c1(1.5, 0, 0);
|
||||
Color c2(0, 0.5, 0);
|
||||
Color c3(-0.5, 0, 1);
|
||||
|
||||
c.write_pixel(0, 0, c1);
|
||||
c.write_pixel(2, 1, c2);
|
||||
c.write_pixel(4, 2, c3);
|
||||
|
||||
ppm = c.to_ppm();
|
||||
|
||||
the_ref_ppm = "P3\n5 3\n255\n";
|
||||
the_ref_ppm += "255 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
|
||||
the_ref_ppm += "0 0 0 0 0 0 0 128 0 0 0 0 0 0 0\n";
|
||||
the_ref_ppm += "0 0 0 0 0 0 0 0 0 0 0 0 0 0 255\n";
|
||||
|
||||
REQUIRE(ppm == the_ref_ppm);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[02][02][Canvas] Split long lines in PPM files", "[Canvas]")
|
||||
{
|
||||
std::string ppm, the_ref_ppm;
|
||||
Canvas c(10, 2);
|
||||
|
||||
for (int j = 0; j < 2; ++j)
|
||||
{
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
c.write_pixel(i, j, Color(1, 0.8, 0.6));
|
||||
for (int j = 0; j < 20; ++j)
|
||||
{
|
||||
AND_THEN("every pixel of c is color(0,0,0)")
|
||||
{
|
||||
REQUIRE(c.pixel_at(2, 3) == Color(0, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
SCENARIO("Writing pixels to a canvas", "[features/canvas.feature]")
|
||||
{
|
||||
GIVEN("c <-canvas(10, 20)")
|
||||
{
|
||||
Canvas c(10, 20);
|
||||
AND_GIVEN("red <-color(1, 0, 0)")
|
||||
{
|
||||
Color red(1, 0, 0);
|
||||
|
||||
WHEN("write_pixel(c,2,3,red)")
|
||||
{
|
||||
c.write_pixel(2, 3, red);
|
||||
THEN("pixel_at(c,2,3) = red")
|
||||
{
|
||||
REQUIRE(c.pixel_at(2, 3) == red);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
SCENARIO("Constructing the PPM pixel data", "[features/canvas.feature]")
|
||||
{
|
||||
std::string ppm, the_ref_ppm;
|
||||
GIVEN("c <-canvas(5, 3)")
|
||||
{
|
||||
Canvas c(5, 3);
|
||||
AND_GIVEN(" c1 color(1.5, 0, 0)")
|
||||
{
|
||||
Color c1(1.5, 0, 0);
|
||||
AND_GIVEN(" c2 color(0, 0.5, 0)")
|
||||
{
|
||||
Color c2(0, 0.5, 0);
|
||||
AND_GIVEN(" c3 color(-0.5, 0, 1))")
|
||||
{
|
||||
Color c3(-0.5, 0, 1);
|
||||
WHEN("write_pixel(c, 0, 0, c1)")
|
||||
{
|
||||
c.write_pixel(0, 0, c1);
|
||||
AND_WHEN("write_pixel(c, 2, 1, c2)")
|
||||
{
|
||||
c.write_pixel(2, 1, c2);
|
||||
AND_WHEN("write_pixel(c, 4, 2, c3)")
|
||||
{
|
||||
c.write_pixel(4, 2, c3);
|
||||
AND_WHEN("ppm <- canvas_to_ppm(c)")
|
||||
{
|
||||
ppm = c.to_ppm();
|
||||
|
||||
the_ref_ppm = "P3\n5 3\n255\n";
|
||||
the_ref_ppm += "255 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
|
||||
the_ref_ppm += "0 0 0 0 0 0 0 128 0 0 0 0 0 0 0\n";
|
||||
the_ref_ppm += "0 0 0 0 0 0 0 0 0 0 0 0 0 0 255\n";
|
||||
THEN("line 4-6 of ppm are 255 0 0 ....")
|
||||
{
|
||||
REQUIRE(ppm == the_ref_ppm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
SCENARIO("Split long lines in PPM files", "[features/canvas.feature]")
|
||||
{
|
||||
std::string ppm, the_ref_ppm;
|
||||
GIVEN("c <-canvas(10, 2)")
|
||||
{
|
||||
Canvas c(10, 2);
|
||||
WHEN("every pixel of c is set to color(1,0.8,0.6)")
|
||||
{
|
||||
for (int j = 0; j < 2; ++j)
|
||||
{
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
c.write_pixel(i, j, Color(1, 0.8, 0.6));
|
||||
}
|
||||
}
|
||||
|
||||
AND_WHEN("ppm <- canvas_to_ppm(c)")
|
||||
{
|
||||
ppm = c.to_ppm();
|
||||
|
||||
the_ref_ppm = "P3\n10 2\n255\n";
|
||||
the_ref_ppm += "255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204\n";
|
||||
the_ref_ppm += "153 255 204 153 255 204 153 255 204 153 255 204 153\n";
|
||||
the_ref_ppm += "255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204\n";
|
||||
the_ref_ppm += "153 255 204 153 255 204 153 255 204 153 255 204 153\n";
|
||||
|
||||
THEN("line 4-7 of ppm are 255 204 153 255 204 ...")
|
||||
{
|
||||
REQUIRE(ppm == the_ref_ppm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ppm = c.to_ppm();
|
||||
|
||||
the_ref_ppm = "P3\n10 2\n255\n";
|
||||
the_ref_ppm += "255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204\n";
|
||||
the_ref_ppm += "153 255 204 153 255 204 153 255 204 153 255 204 153\n";
|
||||
the_ref_ppm += "255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204\n";
|
||||
the_ref_ppm += "153 255 204 153 255 204 153 255 204 153 255 204 153\n";
|
||||
|
||||
REQUIRE(ppm == the_ref_ppm);
|
||||
}
|
||||
|
||||
@@ -33,431 +33,680 @@ using namespace Raytracer;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Constructing and inspecting a 4x4 matrix", "[Matrix]")
|
||||
SCENARIO("Constructing and inspecting a 4x4 matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix m = {
|
||||
{ 1, 2, 3, 4},
|
||||
{ 5.5, 6.5, 7.5, 8.5},
|
||||
{ 9, 10, 11, 12},
|
||||
{13.5, 14.5, 15.5, 16.5}
|
||||
};
|
||||
GIVEN("rgz following 4x4 matrix M")
|
||||
{
|
||||
Matrix M = {
|
||||
{ 1, 2, 3, 4},
|
||||
{ 5.5, 6.5, 7.5, 8.5},
|
||||
{ 9, 10, 11, 12},
|
||||
{13.5, 14.5, 15.5, 16.5}
|
||||
};
|
||||
|
||||
REQUIRE(m.rows() == 4);
|
||||
REQUIRE(m.cols() == 4);
|
||||
THEN("M.rows = 4")
|
||||
{
|
||||
REQUIRE(M.rows() == 4);
|
||||
}
|
||||
AND_THEN("M.cols = 4")
|
||||
{
|
||||
REQUIRE(M.cols() == 4);
|
||||
}
|
||||
|
||||
REQUIRE(m[0][0] == 1);
|
||||
REQUIRE(m[0][3] == 4);
|
||||
REQUIRE(m[1][0] == 5.5);
|
||||
REQUIRE(m[1][2] == 7.5);
|
||||
REQUIRE(m[2][2] == 11);
|
||||
REQUIRE(m[3][0] == 13.5);
|
||||
REQUIRE(m[3][2] == 15.5);
|
||||
AND_THEN("M[0][0] = 1")
|
||||
{
|
||||
REQUIRE(M[0][0] == 1);
|
||||
}
|
||||
AND_THEN("M[0][3] = 4")
|
||||
{
|
||||
REQUIRE(M[0][3] == 4);
|
||||
}
|
||||
AND_THEN("M[1][0] = 5.5")
|
||||
{
|
||||
REQUIRE(M[1][0] == 5.5);
|
||||
}
|
||||
AND_THEN("M[1][2] = 7.5")
|
||||
{
|
||||
REQUIRE(M[1][2] == 7.5);
|
||||
}
|
||||
AND_THEN("M[2][2] = 11")
|
||||
{
|
||||
REQUIRE(M[2][2] == 11);
|
||||
}
|
||||
AND_THEN("M[3][0] = 13.5")
|
||||
{
|
||||
REQUIRE(M[3][0] == 13.5);
|
||||
}
|
||||
AND_THEN("M[3][2] = 15.5")
|
||||
{
|
||||
REQUIRE(M[3][2] == 15.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] A 2x2 matrix ought to be representable", "[Matrix]")
|
||||
SCENARIO("A 2x2 matrix ought to be representable", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix m = {
|
||||
{-3, 5},
|
||||
{ 1, -2}
|
||||
};
|
||||
|
||||
REQUIRE(m.rows() == 2);
|
||||
REQUIRE(m.cols() == 2);
|
||||
|
||||
REQUIRE(m[0][0] == -3);
|
||||
REQUIRE(m[0][1] == 5);
|
||||
REQUIRE(m[1][0] == 1);
|
||||
REQUIRE(m[1][1] == -2);
|
||||
GIVEN("the following 2x2 matrix M")
|
||||
{
|
||||
Matrix M = {
|
||||
{-3, 5},
|
||||
{ 1, -2}
|
||||
};
|
||||
THEN("M.rows = 2")
|
||||
{
|
||||
REQUIRE(M.rows() == 2);
|
||||
}
|
||||
AND_THEN("M.cols = 2")
|
||||
{
|
||||
REQUIRE(M.cols() == 2);
|
||||
}
|
||||
AND_THEN("M[0][0] = -3")
|
||||
{
|
||||
REQUIRE(M[0][0] == -3);
|
||||
}
|
||||
AND_THEN("M[0][1] = 5")
|
||||
{
|
||||
REQUIRE(M[0][1] == 5);
|
||||
}
|
||||
AND_THEN("M[1][0] = 1")
|
||||
{
|
||||
REQUIRE(M[1][0] == 1);
|
||||
}
|
||||
AND_THEN("M[1][1] = -2")
|
||||
{
|
||||
REQUIRE(M[1][1] == -2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] A 3x3 matrix ought to be representable", "[Matrix]")
|
||||
SCENARIO("A 3x3 matrix ought to be representable", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix m = {
|
||||
{-3, 5, 0},
|
||||
{ 1, -2, -7},
|
||||
{ 0, 1, 1}
|
||||
};
|
||||
GIVEN("the following 3x3 matrix M")
|
||||
{
|
||||
Matrix M = {
|
||||
{-3, 5, 0},
|
||||
{ 1, -2, -7},
|
||||
{ 0, 1, 1}
|
||||
};
|
||||
THEN("M.rows = 3")
|
||||
{
|
||||
REQUIRE(M.rows() == 3);
|
||||
}
|
||||
AND_THEN("M.cols == 3")
|
||||
{
|
||||
REQUIRE(M.cols() == 3);
|
||||
}
|
||||
|
||||
REQUIRE(m.rows() == 3);
|
||||
REQUIRE(m.cols() == 3);
|
||||
|
||||
REQUIRE(m[0][0] == -3);
|
||||
REQUIRE(m[1][1] == -2);
|
||||
REQUIRE(m[2][2] == 1);
|
||||
AND_THEN("M[0][0] = -3")
|
||||
{
|
||||
REQUIRE(M[0][0] == -3);
|
||||
}
|
||||
AND_THEN("M[1][1] = -2")
|
||||
{
|
||||
REQUIRE(M[1][1] == -2);
|
||||
}
|
||||
AND_THEN("M[2][2] = 1")
|
||||
{
|
||||
REQUIRE(M[2][2] == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Matrix equality with identical matrices", "[Matrix]")
|
||||
SCENARIO("Matrix equality with identical matrices", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{1, 2, 3, 4},
|
||||
{5, 6, 7, 8},
|
||||
{9, 8, 7, 6},
|
||||
{5, 4, 3, 2}
|
||||
};
|
||||
Matrix b = {
|
||||
{1, 2, 3, 4},
|
||||
{5, 6, 7, 8},
|
||||
{9, 8, 7, 6},
|
||||
{5, 4, 3, 2}
|
||||
};
|
||||
|
||||
REQUIRE(a == b);
|
||||
GIVEN("the following matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{1, 2, 3, 4},
|
||||
{5, 6, 7, 8},
|
||||
{9, 8, 7, 6},
|
||||
{5, 4, 3, 2}
|
||||
};
|
||||
AND_GIVEN("the following matrix B")
|
||||
{
|
||||
Matrix B = {
|
||||
{1, 2, 3, 4},
|
||||
{5, 6, 7, 8},
|
||||
{9, 8, 7, 6},
|
||||
{5, 4, 3, 2}
|
||||
};
|
||||
THEN("A = B")
|
||||
{
|
||||
REQUIRE(A == B);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Matrix equality with different matrices", "[Matrix]")
|
||||
SCENARIO("Matrix equality with different matrices", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{1, 2, 3, 4},
|
||||
{5, 6, 7, 8},
|
||||
{9, 8, 7, 6},
|
||||
{5, 4, 3, 2}
|
||||
};
|
||||
Matrix b = {
|
||||
{2, 3, 4, 5},
|
||||
{6, 7, 8, 9},
|
||||
{8, 7, 6, 5},
|
||||
{4, 3, 2, 1}
|
||||
};
|
||||
|
||||
REQUIRE(a != b);
|
||||
GIVEN("the following matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{1, 2, 3, 4},
|
||||
{5, 6, 7, 8},
|
||||
{9, 8, 7, 6},
|
||||
{5, 4, 3, 2}
|
||||
};
|
||||
AND_GIVEN("the following matrix B")
|
||||
{
|
||||
Matrix B = {
|
||||
{2, 3, 4, 5},
|
||||
{6, 7, 8, 9},
|
||||
{8, 7, 6, 5},
|
||||
{4, 3, 2, 1}
|
||||
};
|
||||
THEN("A != B")
|
||||
{
|
||||
REQUIRE(A != B);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Multiplying two matrices", "[Matrix]")
|
||||
SCENARIO("Multiplying two matrices", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{1, 2, 3, 4},
|
||||
{5, 6, 7, 8},
|
||||
{9, 8, 7, 6},
|
||||
{5, 4, 3, 2}
|
||||
};
|
||||
Matrix b = {
|
||||
{-2, 1, 2, 3},
|
||||
{ 3, 2, 1, -1},
|
||||
{ 4, 3, 6, 5},
|
||||
{ 1, 2, 7, 8}
|
||||
};
|
||||
Matrix c = {
|
||||
{20, 22, 50, 48},
|
||||
{44, 54, 114, 108},
|
||||
{40, 58, 110, 102},
|
||||
{16, 26, 46, 42}
|
||||
};
|
||||
|
||||
REQUIRE((a * b) == c);
|
||||
GIVEN("the following matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{1, 2, 3, 4},
|
||||
{5, 6, 7, 8},
|
||||
{9, 8, 7, 6},
|
||||
{5, 4, 3, 2}
|
||||
};
|
||||
AND_GIVEN("the following matrix B")
|
||||
{
|
||||
Matrix B = {
|
||||
{-2, 1, 2, 3},
|
||||
{ 3, 2, 1, -1},
|
||||
{ 4, 3, 6, 5},
|
||||
{ 1, 2, 7, 8}
|
||||
};
|
||||
AND_GIVEN("the following matrix C")
|
||||
{
|
||||
Matrix C = {
|
||||
{20, 22, 50, 48},
|
||||
{44, 54, 114, 108},
|
||||
{40, 58, 110, 102},
|
||||
{16, 26, 46, 42}
|
||||
};
|
||||
THEN("A * B = C")
|
||||
REQUIRE((A * B) == C);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] a matrix multiplied by a tuple", "[Matrix]")
|
||||
SCENARIO("A matrix multiplied by a tuple", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{1, 2, 3, 4},
|
||||
{2, 4, 4, 2},
|
||||
{8, 6, 4, 1},
|
||||
{0, 0, 0, 1}
|
||||
};
|
||||
Tuple b(1, 2, 3, 1);
|
||||
|
||||
REQUIRE((a * b) == Tuple(18, 24, 33, 1));
|
||||
GIVEN("the following matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{1, 2, 3, 4},
|
||||
{2, 4, 4, 2},
|
||||
{8, 6, 4, 1},
|
||||
{0, 0, 0, 1}
|
||||
};
|
||||
AND_GIVEN("b <- tuple(1, 2, 3, 1)")
|
||||
{
|
||||
Tuple b(1, 2, 3, 1);
|
||||
THEN("A * b = tuple(18, 24, 33, 1)")
|
||||
{
|
||||
REQUIRE((A * b) == Tuple(18, 24, 33, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Multiplying a matrix by the identity matrix", "[Matrix]")
|
||||
SCENARIO("Multiplying a matrix by the identity matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{0, 1, 2, 4},
|
||||
{1, 2, 4, 8},
|
||||
{2, 4, 8, 16},
|
||||
{4, 8, 16, 32}
|
||||
};
|
||||
|
||||
REQUIRE((a * Matrix::identity()) == a);
|
||||
GIVEN("the following matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{0, 1, 2, 4},
|
||||
{1, 2, 4, 8},
|
||||
{2, 4, 8, 16},
|
||||
{4, 8, 16, 32}
|
||||
};
|
||||
THEN("A * identity_matrix = A")
|
||||
{
|
||||
REQUIRE((A * Matrix::identity()) == A);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Multiplying the identity matrix by a tuple", "[Matrix]")
|
||||
SCENARIO("Multiplying the identity matrix by a tuple", "[features/matrices.feature]")
|
||||
{
|
||||
Tuple a(1, 2, 3, 4);
|
||||
|
||||
REQUIRE((Matrix::identity() * a) == a);
|
||||
GIVEN("a <- tuple(1, 2, 3, 4)")
|
||||
{
|
||||
Tuple a(1, 2, 3, 4);
|
||||
THEN("identity_matrix * a = a")
|
||||
{
|
||||
REQUIRE((Matrix::identity() * a) == a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Transposing a matrix", "[Matrix]")
|
||||
SCENARIO("Transposing a matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{0, 9, 3, 0},
|
||||
{9, 8, 0, 8},
|
||||
{1, 8, 5, 3},
|
||||
{0, 0, 5, 8}
|
||||
};
|
||||
Matrix transposed = {
|
||||
{0, 9, 1, 0},
|
||||
{9, 8, 8, 0},
|
||||
{3, 0, 5, 5},
|
||||
{0, 8, 3, 8}
|
||||
};
|
||||
GIVEN("the following matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{0, 9, 3, 0},
|
||||
{9, 8, 0, 8},
|
||||
{1, 8, 5, 3},
|
||||
{0, 0, 5, 8}
|
||||
};
|
||||
THEN("transpose(A) is the following matrix")
|
||||
{
|
||||
Matrix transposed = {
|
||||
{0, 9, 1, 0},
|
||||
{9, 8, 8, 0},
|
||||
{3, 0, 5, 5},
|
||||
{0, 8, 3, 8}
|
||||
};
|
||||
|
||||
a.transpose();
|
||||
A.transpose();
|
||||
|
||||
REQUIRE(a == transposed);
|
||||
REQUIRE(A == transposed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Transposing the identity matrix", "[Matrix]")
|
||||
SCENARIO("Transposing the identity matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = Matrix::identity();
|
||||
GIVEN("A <- transpose(identity_matrix)")
|
||||
{
|
||||
Matrix A = Matrix::identity();
|
||||
|
||||
a.transpose();
|
||||
|
||||
REQUIRE(a == Matrix::identity());
|
||||
A.transpose();
|
||||
THEN("A = identity_matrix")
|
||||
{
|
||||
REQUIRE(A == Matrix::identity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Calculating the determinant of a 2x2 matrix", "[Matrix]")
|
||||
SCENARIO("Calculating the determinant of a 2x2 matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{ 1, 5},
|
||||
{-3, 2}
|
||||
};
|
||||
|
||||
REQUIRE(a.determinant() == 17);
|
||||
GIVEN("the following 2x2 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{ 1, 5},
|
||||
{-3, 2}
|
||||
};
|
||||
THEN("determinant(A) = 17")
|
||||
{
|
||||
REQUIRE(A.determinant() == 17);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] A submatrix of a 3x3 matrix is a 2x2 matrix", "[Matrix]")
|
||||
SCENARIO("A submatrix of a 3x3 matrix is a 2x2 matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{ 1, 5, 0},
|
||||
{-3, 2, 7},
|
||||
{ 0, 6, -3}
|
||||
};
|
||||
GIVEN("the following 3x3 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{ 1, 5, 0},
|
||||
{-3, 2, 7},
|
||||
{ 0, 6, -3}
|
||||
};
|
||||
|
||||
Matrix b = {
|
||||
{-3, 2},
|
||||
{ 0, 6}
|
||||
};
|
||||
|
||||
REQUIRE(a.sub_matrix(0, 2) == b);
|
||||
Matrix B = {
|
||||
{-3, 2},
|
||||
{ 0, 6}
|
||||
};
|
||||
THEN("submatrix(A,0,2) is the following 2x2 matrix")
|
||||
{
|
||||
REQUIRE(A.sub_matrix(0, 2) == B);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] A submatrix of a 4x4 matrix is a 3x3 matrix", "[Matrix]")
|
||||
SCENARIO("A submatrix of a 4x4 matrix is a 3x3 matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{-6, 1, 1, 6},
|
||||
{-8, 5, 8, 6},
|
||||
{-1, 0, 8, 2},
|
||||
{-7, 1, -1, 1}
|
||||
};
|
||||
GIVEN("the following 4x4 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{-6, 1, 1, 6},
|
||||
{-8, 5, 8, 6},
|
||||
{-1, 0, 8, 2},
|
||||
{-7, 1, -1, 1}
|
||||
};
|
||||
|
||||
Matrix b = {
|
||||
{-6, 1, 6},
|
||||
{-8, 8, 6},
|
||||
{-7, -1, 1}
|
||||
};
|
||||
|
||||
REQUIRE(a.sub_matrix(2, 1) == b);
|
||||
Matrix B = {
|
||||
{-6, 1, 6},
|
||||
{-8, 8, 6},
|
||||
{-7, -1, 1}
|
||||
};
|
||||
THEN("submatrix(B,2,1) is the following 3x3 matrix")
|
||||
{
|
||||
REQUIRE(A.sub_matrix(2, 1) == B);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Calculating a minor of a 3x3 matrix", "[Matrix]")
|
||||
SCENARIO("Calculating a minor of a 3x3 matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{3, 5, 0},
|
||||
{2, -1, -7},
|
||||
{6, -1, 5}
|
||||
};
|
||||
|
||||
Matrix b = a.sub_matrix(1, 0);
|
||||
|
||||
REQUIRE(b.determinant() == 25);
|
||||
|
||||
REQUIRE(a.minor(1, 0) == 25);
|
||||
GIVEN("the following 3x3 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{3, 5, 0},
|
||||
{2, -1, -7},
|
||||
{6, -1, 5}
|
||||
};
|
||||
AND_GIVEN("B <- submatrix(A,1,0)")
|
||||
{
|
||||
Matrix B = A.sub_matrix(1, 0);
|
||||
THEN("determinant(B) = 25")
|
||||
{
|
||||
REQUIRE(B.determinant() == 25);
|
||||
}
|
||||
AND_THEN("minor(A,1,0)=25")
|
||||
{
|
||||
REQUIRE(A.minor(1, 0) == 25);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Calculating a cofactor of a 3x3 matrix", "[Matrix]")
|
||||
SCENARIO("Calculating a cofactor of a 3x3 matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{3, 5, 0},
|
||||
{2, -1, -7},
|
||||
{6, -1, 5}
|
||||
};
|
||||
|
||||
REQUIRE(a.minor(0, 0) == -12);
|
||||
REQUIRE(a.cofactor(0, 0) == -12);
|
||||
REQUIRE(a.minor(1, 0) == 25);
|
||||
REQUIRE(a.cofactor(1, 0) == -25);
|
||||
GIVEN("the following 3x3 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{3, 5, 0},
|
||||
{2, -1, -7},
|
||||
{6, -1, 5}
|
||||
};
|
||||
THEN("minor(A, 0, 0) = -12")
|
||||
{
|
||||
REQUIRE(A.minor(0, 0) == -12);
|
||||
}
|
||||
AND_THEN("cofactor(A, 0, 0) = -12")
|
||||
{
|
||||
REQUIRE(A.cofactor(0, 0) == -12);
|
||||
}
|
||||
AND_THEN("minor(A, 1, 0) = 25")
|
||||
{
|
||||
REQUIRE(A.minor(1, 0) == 25);
|
||||
}
|
||||
AND_THEN("cofactor(A, 1, 0) = -25")
|
||||
{
|
||||
REQUIRE(A.cofactor(1, 0) == -25);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Calculating the determinant of a 3x3 matrix", "[Matrix]")
|
||||
SCENARIO("Calculating the determinant of a 3x3 matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{ 1, 2, 6},
|
||||
{-5, 8, -4},
|
||||
{ 2, 6, 4}
|
||||
};
|
||||
|
||||
REQUIRE(a.cofactor(0, 0) == 56);
|
||||
REQUIRE(a.cofactor(0, 1) == 12);
|
||||
REQUIRE(a.cofactor(0, 2) == -46);
|
||||
REQUIRE(a.determinant() == -196);
|
||||
GIVEN("the following 3x3 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{ 1, 2, 6},
|
||||
{-5, 8, -4},
|
||||
{ 2, 6, 4}
|
||||
};
|
||||
THEN("cofactor(A, 0, 0) = 56")
|
||||
{
|
||||
REQUIRE(A.cofactor(0, 0) == 56);
|
||||
}
|
||||
AND_THEN("cofactor(A, 0, 1) = 12")
|
||||
{
|
||||
REQUIRE(A.cofactor(0, 1) == 12);
|
||||
}
|
||||
AND_THEN("cofactor(A, 0, 2) = -46")
|
||||
{
|
||||
REQUIRE(A.cofactor(0, 2) == -46);
|
||||
}
|
||||
AND_THEN("determinant(A) = -196")
|
||||
{
|
||||
REQUIRE(A.determinant() == -196);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Calculating the determinant of a 4x4 matrix", "[Matrix]")
|
||||
SCENARIO("Calculating the determinant of a 4x4 matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{-2, -8, 3, 5},
|
||||
{-3, 1, 7, 3},
|
||||
{ 1, 2, -9, 6},
|
||||
{-6, 7, 7, -9}
|
||||
};
|
||||
|
||||
REQUIRE(a.cofactor(0, 0) == 690);
|
||||
REQUIRE(a.cofactor(0, 1) == 447);
|
||||
REQUIRE(a.cofactor(0, 2) == 210);
|
||||
REQUIRE(a.cofactor(0, 3) == 51);
|
||||
REQUIRE(a.determinant() == -4071);
|
||||
GIVEN("the following 4x4 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{-2, -8, 3, 5},
|
||||
{-3, 1, 7, 3},
|
||||
{ 1, 2, -9, 6},
|
||||
{-6, 7, 7, -9}
|
||||
};
|
||||
THEN("cofactor(A, 0, 0) = 690")
|
||||
{
|
||||
REQUIRE(A.cofactor(0, 0) == 690);
|
||||
}
|
||||
AND_THEN("cofactor(A, 0, 1) = 447")
|
||||
{
|
||||
REQUIRE(A.cofactor(0, 1) == 447);
|
||||
}
|
||||
AND_THEN("cofactor(A, 0, 2) = 210")
|
||||
{
|
||||
REQUIRE(A.cofactor(0, 2) == 210);
|
||||
}
|
||||
AND_THEN("cofactor(A, 0, 3) = 51")
|
||||
{
|
||||
REQUIRE(A.cofactor(0, 3) == 51);
|
||||
}
|
||||
AND_THEN("determinant(A) = -4071")
|
||||
{
|
||||
REQUIRE(A.determinant() == -4071);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Testing an invertible matrix for invertibility", "[Matrix]")
|
||||
SCENARIO("Testing an invertible matrix for invertibility", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{6, 4, 4, 4},
|
||||
{5, 5, 7, 6},
|
||||
{4, -9, 3, -7},
|
||||
{9, 1, 7, -6}
|
||||
};
|
||||
|
||||
REQUIRE(a.determinant() == -2120);
|
||||
REQUIRE(a.invertible() == true);
|
||||
GIVEN("the following 4x4 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{6, 4, 4, 4},
|
||||
{5, 5, 7, 6},
|
||||
{4, -9, 3, -7},
|
||||
{9, 1, 7, -6}
|
||||
};
|
||||
THEN("determinant(A) = -2120")
|
||||
{
|
||||
REQUIRE(A.determinant() == -2120);
|
||||
}
|
||||
AND_THEN("A is invertible")
|
||||
{
|
||||
REQUIRE(A.invertible() == true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Testing an noninvertible matrix for invertibility", "[Matrix]")
|
||||
SCENARIO("Testing an noninvertible matrix for invertibility", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{-4, 2, -2, -3},
|
||||
{ 9, 6, 2, 6},
|
||||
{ 0, -5, 1, -5},
|
||||
{ 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
REQUIRE(a.determinant() == 0);
|
||||
REQUIRE(a.invertible() == false);
|
||||
GIVEN("the following 4x4 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{-4, 2, -2, -3},
|
||||
{ 9, 6, 2, 6},
|
||||
{ 0, -5, 1, -5},
|
||||
{ 0, 0, 0, 0}
|
||||
};
|
||||
THEN("determinant(A) = 0")
|
||||
{
|
||||
REQUIRE(A.determinant() == 0);
|
||||
}
|
||||
AND_THEN("A is not invertible")
|
||||
{
|
||||
REQUIRE(A.invertible() == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Calculating the inverse of a matrix", "[Matrix]")
|
||||
SCENARIO("Calculating the inverse of a matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{-5, 2, 6, -8},
|
||||
{ 1, -5, 1, 8},
|
||||
{ 7, 7, -6, -7},
|
||||
{ 1, -3, 7, 4}
|
||||
};
|
||||
GIVEN("the following 4x4 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{-5, 2, 6, -8},
|
||||
{ 1, -5, 1, 8},
|
||||
{ 7, 7, -6, -7},
|
||||
{ 1, -3, 7, 4}
|
||||
};
|
||||
|
||||
Matrix a_inverted = {
|
||||
{ 0.21805, 0.45113, 0.24060, -0.04511},
|
||||
{-0.80827, -1.45677, -0.44361, 0.52068},
|
||||
{-0.07895, -0.22368, -0.05263, 0.19737},
|
||||
{-0.52256, -0.81391, -0.30075, 0.30639}
|
||||
};
|
||||
|
||||
Matrix b = a.inverse();
|
||||
|
||||
REQUIRE(a.determinant() == 532);
|
||||
REQUIRE(a.cofactor(2, 3) == -160);
|
||||
REQUIRE(b[3][2] == -160.0 / 532.0);
|
||||
REQUIRE(a.cofactor(3, 2) == 105);
|
||||
REQUIRE(b[2][3] == 105.0 / 532.0);
|
||||
REQUIRE(b == a_inverted);
|
||||
Matrix a_inverted = {
|
||||
{ 0.21805, 0.45113, 0.24060, -0.04511},
|
||||
{-0.80827, -1.45677, -0.44361, 0.52068},
|
||||
{-0.07895, -0.22368, -0.05263, 0.19737},
|
||||
{-0.52256, -0.81391, -0.30075, 0.30639}
|
||||
};
|
||||
AND_GIVEN("B <- inverse(A)")
|
||||
{
|
||||
Matrix B = A.inverse();
|
||||
THEN("determinant(A) = 532")
|
||||
{
|
||||
REQUIRE(A.determinant() == 532);
|
||||
}
|
||||
AND_THEN("cofactor(A, 2, 3) = -160")
|
||||
{
|
||||
REQUIRE(A.cofactor(2, 3) == -160);
|
||||
}
|
||||
AND_THEN("B[3][2] = -160.0 / 532.0")
|
||||
{
|
||||
REQUIRE(B[3][2] == -160.0 / 532.0);
|
||||
}
|
||||
AND_THEN("cofactor(A, 3, 2) = 105")
|
||||
{
|
||||
REQUIRE(A.cofactor(3, 2) == 105);
|
||||
}
|
||||
AND_THEN("B[2][3] = 105.0 / 532.0")
|
||||
{
|
||||
REQUIRE(B[2][3] == 105.0 / 532.0);
|
||||
}
|
||||
AND_THEN("B is the following 4x4 matrix")
|
||||
{
|
||||
REQUIRE(B == a_inverted);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Calculating the inverse of another matrix", "[Matrix]")
|
||||
SCENARIO("Calculating the inverse of another matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{ 8, -5, 9, 2},
|
||||
{ 7, 5, 6, 1},
|
||||
{-6, 0, 9, 6},
|
||||
{-3, 0, -9, -4}
|
||||
};
|
||||
Matrix a_inverted = {
|
||||
{-0.15385, -0.15385, -0.28205, -0.53846},
|
||||
{-0.07692, 0.12308, 0.02564, 0.03077},
|
||||
{ 0.35897, 0.35897, 0.43590, 0.92308},
|
||||
{-0.69231, -0.69231, -0.76923, -1.92308}
|
||||
};
|
||||
|
||||
REQUIRE(a.inverse() == a_inverted);
|
||||
GIVEN("the following 4x4 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{ 8, -5, 9, 2},
|
||||
{ 7, 5, 6, 1},
|
||||
{-6, 0, 9, 6},
|
||||
{-3, 0, -9, -4}
|
||||
};
|
||||
Matrix a_inverted = {
|
||||
{-0.15385, -0.15385, -0.28205, -0.53846},
|
||||
{-0.07692, 0.12308, 0.02564, 0.03077},
|
||||
{ 0.35897, 0.35897, 0.43590, 0.92308},
|
||||
{-0.69231, -0.69231, -0.76923, -1.92308}
|
||||
};
|
||||
THEN("inverse(A) is the following matrix")
|
||||
{
|
||||
REQUIRE(A.inverse() == a_inverted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Calculating the inverse of third matrix", "[Matrix]")
|
||||
SCENARIO("Calculating the inverse of third matrix", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{ 9, 3, 0, 9},
|
||||
{-5, -2, -6, -3},
|
||||
{-4, 9, 6, 4},
|
||||
{-7, 6, 6, 2}
|
||||
};
|
||||
Matrix a_inverted = {
|
||||
{-0.04074, -0.07778, 0.14444, -0.22222},
|
||||
{-0.07778, 0.03333, 0.36667, -0.33333},
|
||||
{-0.02901, -0.14630, -0.10926, 0.12963},
|
||||
{ 0.17778, 0.06667, -0.26667, 0.33333}
|
||||
};
|
||||
|
||||
REQUIRE(a.inverse() == a_inverted);
|
||||
GIVEN("the following 4x4 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{ 9, 3, 0, 9},
|
||||
{-5, -2, -6, -3},
|
||||
{-4, 9, 6, 4},
|
||||
{-7, 6, 6, 2}
|
||||
};
|
||||
Matrix a_inverted = {
|
||||
{-0.04074, -0.07778, 0.14444, -0.22222},
|
||||
{-0.07778, 0.03333, 0.36667, -0.33333},
|
||||
{-0.02901, -0.14630, -0.10926, 0.12963},
|
||||
{ 0.17778, 0.06667, -0.26667, 0.33333}
|
||||
};
|
||||
THEN("inverse(A) is the following matrix")
|
||||
{
|
||||
REQUIRE(A.inverse() == a_inverted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[03][Matrix] Multiplying a product by its inverse", "[Matrix]")
|
||||
SCENARIO("Multiplying a product by its inverse", "[features/matrices.feature]")
|
||||
{
|
||||
Matrix a = {
|
||||
{ 3, -9, 7, 3},
|
||||
{ 3, -8, 2, -9},
|
||||
{-4, 4, 4, 1},
|
||||
{-6, 5, -1, 1}
|
||||
};
|
||||
Matrix b = {
|
||||
{8, 2, 2, 2},
|
||||
{3, -1, 7, 0},
|
||||
{7, 0, 5, 4},
|
||||
{6, -2, 0, 5}
|
||||
};
|
||||
Matrix c = a * b;
|
||||
REQUIRE(c * b.inverse() == a);
|
||||
GIVEN("the following 4x4 matrix A")
|
||||
{
|
||||
Matrix A = {
|
||||
{ 3, -9, 7, 3},
|
||||
{ 3, -8, 2, -9},
|
||||
{-4, 4, 4, 1},
|
||||
{-6, 5, -1, 1}
|
||||
};
|
||||
AND_GIVEN("the following 4x4 matrix B")
|
||||
{
|
||||
Matrix B = {
|
||||
{8, 2, 2, 2},
|
||||
{3, -1, 7, 0},
|
||||
{7, 0, 5, 4},
|
||||
{6, -2, 0, 5}
|
||||
};
|
||||
AND_GIVEN("C <- A * B")
|
||||
{
|
||||
Matrix C = A * B;
|
||||
THEN("C * inverse(B) = A")
|
||||
{
|
||||
REQUIRE(C * B.inverse() == A);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,204 +33,408 @@ using namespace Raytracer;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] Multiplying by a translation matrix", "[Matrix]")
|
||||
SCENARIO("Multiplying by a translation matrix", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::translation(5, -3, 2);
|
||||
Tuple p = Tuple::Point(-3, 4, 5);
|
||||
|
||||
REQUIRE(transform * p == Tuple::Point(2, 1, 7));
|
||||
GIVEN("transform <- translation(5, -3, 2)")
|
||||
{
|
||||
Matrix transform = Matrix::translation(5, -3, 2);
|
||||
AND_GIVEN("p <- point(-3, 4, 5)")
|
||||
{
|
||||
Tuple p = Tuple::Point(-3, 4, 5);
|
||||
THEN("transform * p = point(2, 1, 7)")
|
||||
{
|
||||
REQUIRE(transform * p == Tuple::Point(2, 1, 7));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] Multiplying by the inverse of a translation matrix", "[Matrix]")
|
||||
SCENARIO("Multiplying by the inverse of a translation matrix", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::translation(5, -3, 2);
|
||||
Matrix inv = transform.inverse();
|
||||
Tuple p = Tuple::Point(-3, 4, 5);
|
||||
|
||||
REQUIRE(inv * p == Tuple::Point(-8, 7, 3));
|
||||
GIVEN("transform <- translation(5, -3, 2)")
|
||||
{
|
||||
Matrix transform = Matrix::translation(5, -3, 2);
|
||||
AND_GIVEN("inv <- inverse(transform)")
|
||||
{
|
||||
Matrix inv = transform.inverse();
|
||||
AND_GIVEN("p <- point(-3, 4, 5)")
|
||||
{
|
||||
Tuple p = Tuple::Point(-3, 4, 5);
|
||||
THEN("inv * p = point(-8, 7, 3)")
|
||||
{
|
||||
REQUIRE(inv * p == Tuple::Point(-8, 7, 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] Translation does not affect vectors", "[Matrix]")
|
||||
SCENARIO("Translation does not affect vectors", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::translation(5, -3, 2);
|
||||
Tuple v = Tuple::Vector(-3, 4, 5);
|
||||
|
||||
REQUIRE(transform * v == v);
|
||||
GIVEN("transform <- translation(5, -3, 2)")
|
||||
{
|
||||
Matrix transform = Matrix::translation(5, -3, 2);
|
||||
AND_GIVEN("v <- vector(-3, 4, 5)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(-3, 4, 5);
|
||||
THEN("transform * v = v")
|
||||
{
|
||||
REQUIRE(transform * v == v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] A scaling matrix applied to a point", "[Matrix]")
|
||||
SCENARIO("A scaling matrix applied to a point", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::scaling(2, 3, 4);
|
||||
Tuple p = Tuple::Point(-4, 6, 8);
|
||||
|
||||
REQUIRE(transform * p == Tuple::Point(-8, 18, 32));
|
||||
GIVEN("transform <- scaling(2, 3, 4)")
|
||||
{
|
||||
Matrix transform = Matrix::scaling(2, 3, 4);
|
||||
AND_GIVEN("p <- point(-4, 6, 8)")
|
||||
{
|
||||
Tuple p = Tuple::Point(-4, 6, 8);
|
||||
THEN("transform * p = point(-8, 18, 32)")
|
||||
{
|
||||
REQUIRE(transform * p == Tuple::Point(-8, 18, 32));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] A scaling matrix applied to a vector", "[Matrix]")
|
||||
SCENARIO("A scaling matrix applied to a vector", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::scaling(2, 3, 4);
|
||||
Tuple v = Tuple::Vector(-4, 6, 8);
|
||||
|
||||
REQUIRE(transform * v == Tuple::Vector(-8, 18, 32));
|
||||
GIVEN("transform <- scaling(2, 3, 4)")
|
||||
{
|
||||
Matrix transform = Matrix::scaling(2, 3, 4);
|
||||
AND_GIVEN("v <- vector(-4, 6, 8)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(-4, 6, 8);
|
||||
THEN("transform * p = vector(-8, 18, 32)")
|
||||
{
|
||||
REQUIRE(transform * v == Tuple::Vector(-8, 18, 32));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] Multiplying by the inverse of a scaling matrix", "[Matrix]")
|
||||
SCENARIO("Multiplying by the inverse of a scaling matrix", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::scaling(2, 3, 4);
|
||||
Matrix inv = transform.inverse();
|
||||
Tuple v = Tuple::Vector(-4, 6, 8);
|
||||
|
||||
REQUIRE(inv * v == Tuple::Vector(-2, 2, 2));
|
||||
GIVEN("transform <- scaling(2, 3, 4)")
|
||||
{
|
||||
Matrix transform = Matrix::scaling(2, 3, 4);
|
||||
AND_GIVEN("inv <- inverse(transform)")
|
||||
{
|
||||
Matrix inv = transform.inverse();
|
||||
AND_GIVEN("v <- vector(-4, 6, 8)")
|
||||
{
|
||||
Tuple v = Tuple::Vector(-4, 6, 8);
|
||||
THEN("inv * v = vector(-2, 2, 2)")
|
||||
{
|
||||
REQUIRE(inv * v == Tuple::Vector(-2, 2, 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] Reflection is scaling by a negative value", "[Matrix]")
|
||||
SCENARIO("Reflection is scaling by a negative value", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::scaling(-1, 1, 1);
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
|
||||
REQUIRE(transform * p == Tuple::Point(-2, 3, 4));
|
||||
GIVEN("transform <- scaling(-1, 1, 1)")
|
||||
{
|
||||
Matrix transform = Matrix::scaling(-1, 1, 1);
|
||||
AND_GIVEN("p <- point(2, 3, 4)")
|
||||
{
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
THEN("transform * p = point(-2, 3, 4)")
|
||||
{
|
||||
REQUIRE(transform * p == Tuple::Point(-2, 3, 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] Rotating a point around the x axis", "[Matrix]")
|
||||
SCENARIO("Rotating a point around the x axis", "[features/transformations.feature]")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 1, 0);
|
||||
Matrix half_quarter = Matrix::rotation_x(std::numbers::pi / 4);
|
||||
Matrix full_quarter = Matrix::rotation_x(std::numbers::pi / 2);
|
||||
|
||||
REQUIRE(half_quarter * p == Tuple::Point(0, sqrt(2) / 2, sqrt(2) / 2));
|
||||
REQUIRE(full_quarter * p == Tuple::Point(0, 0, 1));
|
||||
GIVEN("p <- point(0, 1, 0)")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 1, 0);
|
||||
AND_GIVEN("half_quarter <- rotation_x(pi/4)")
|
||||
{
|
||||
Matrix half_quarter = Matrix::rotation_x(std::numbers::pi / 4);
|
||||
AND_GIVEN("full_quarter <- rotation_x(pi/2)")
|
||||
{
|
||||
Matrix full_quarter = Matrix::rotation_x(std::numbers::pi / 2);
|
||||
THEN("half_quarter * p = point(0, sqrt(2) / 2, sqrt(2) / 2)")
|
||||
{
|
||||
REQUIRE(half_quarter * p == Tuple::Point(0, sqrt(2) / 2, sqrt(2) / 2));
|
||||
}
|
||||
AND_THEN("full_quarter * p == point(0, 0, 1)")
|
||||
{
|
||||
REQUIRE(full_quarter * p == Tuple::Point(0, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] The inverse of an x-rotation rotates in the opposite direction", "[Matrix]")
|
||||
SCENARIO("The inverse of an x-rotation rotates in the opposite direction", "[features/transformations.feature]")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 1, 0);
|
||||
Matrix half_quarter = Matrix::rotation_x(std::numbers::pi / 4);
|
||||
Matrix inv = half_quarter.inverse();
|
||||
|
||||
REQUIRE(inv * p == Tuple::Point(0, sqrt(2) / 2, -sqrt(2) / 2));
|
||||
GIVEN("p <- point(0, 1, 0)")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 1, 0);
|
||||
AND_GIVEN("half_quarter <- rotation_x(pi/4)")
|
||||
{
|
||||
Matrix half_quarter = Matrix::rotation_x(std::numbers::pi / 4);
|
||||
AND_GIVEN("inv <- inverse(half_quarter)")
|
||||
{
|
||||
Matrix inv = half_quarter.inverse();
|
||||
THEN("inv * p = point(0, sqrt(2) / 2, -sqrt(2) / 2)")
|
||||
{
|
||||
REQUIRE(inv * p == Tuple::Point(0, sqrt(2) / 2, -sqrt(2) / 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] Rotating a point around the y axis", "[Matrix]")
|
||||
SCENARIO("Rotating a point around the y axis", "[features/transformations.feature]")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 0, 1);
|
||||
Matrix half_quarter = Matrix::rotation_y(std::numbers::pi / 4);
|
||||
Matrix full_quarter = Matrix::rotation_y(std::numbers::pi / 2);
|
||||
|
||||
REQUIRE(half_quarter * p == Tuple::Point(sqrt(2) / 2, 0, sqrt(2) / 2));
|
||||
REQUIRE(full_quarter * p == Tuple::Point(1, 0, 0));
|
||||
GIVEN("p <- point(0, 1, 0)")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 0, 1);
|
||||
AND_GIVEN("half_quarter <- rotation_y(pi/4)")
|
||||
{
|
||||
Matrix half_quarter = Matrix::rotation_y(std::numbers::pi / 4);
|
||||
AND_GIVEN("full_quarter <- rotation_y(pi/2)")
|
||||
{
|
||||
Matrix full_quarter = Matrix::rotation_y(std::numbers::pi / 2);
|
||||
THEN("half_quarter * p = point(sqrt(2) / 2, 0, sqrt(2) / 2)")
|
||||
{
|
||||
REQUIRE(half_quarter * p == Tuple::Point(sqrt(2) / 2, 0, sqrt(2) / 2));
|
||||
}
|
||||
AND_THEN("full_quarter * p = point(1, 0, 0)")
|
||||
{
|
||||
REQUIRE(full_quarter * p == Tuple::Point(1, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] Rotating a point around the z axis", "[Matrix]")
|
||||
SCENARIO("Rotating a point around the z axis", "[features/transformations.feature]")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 1, 0);
|
||||
Matrix half_quarter = Matrix::rotation_z(std::numbers::pi / 4);
|
||||
Matrix full_quarter = Matrix::rotation_z(std::numbers::pi / 2);
|
||||
GIVEN("p <- point(0, 1, 0)")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 1, 0);
|
||||
AND_GIVEN("full_quarter <- rotation_z(pi/4)")
|
||||
{
|
||||
Matrix half_quarter = Matrix::rotation_z(std::numbers::pi / 4);
|
||||
AND_GIVEN("full_quarter <- rotation_z(pi/2)")
|
||||
{
|
||||
Matrix full_quarter = Matrix::rotation_z(std::numbers::pi / 2);
|
||||
|
||||
Tuple z = half_quarter * p;
|
||||
|
||||
REQUIRE(half_quarter * p == Tuple::Point(-sqrt(2) / 2, sqrt(2) / 2, 0));
|
||||
REQUIRE(full_quarter * p == Tuple::Point(-1, 0, 0));
|
||||
Tuple z = half_quarter * p;
|
||||
THEN("half_quarter * p = point(-sqrt(2) / 2, sqrt(2) / 2, 0)")
|
||||
{
|
||||
REQUIRE(half_quarter * p == Tuple::Point(-sqrt(2) / 2, sqrt(2) / 2, 0));
|
||||
}
|
||||
AND_THEN("full_quarter * p = point(-1, 0, 0)")
|
||||
{
|
||||
REQUIRE(full_quarter * p == Tuple::Point(-1, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] A shearing transformation moves x in proportion to y", "[Matrix]")
|
||||
SCENARIO("A shearing transformation moves x in proportion to y", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::shearing(1, 0, 0, 0, 0, 0);
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
|
||||
REQUIRE(transform * p == Tuple::Point(5, 3, 4));
|
||||
GIVEN("transform <- shearing(1, 0, 0, 0, 0, 0)")
|
||||
{
|
||||
Matrix transform = Matrix::shearing(1, 0, 0, 0, 0, 0);
|
||||
AND_GIVEN("p <- point(2, 3, 4)")
|
||||
{
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
THEN("transform * p == point(5, 3, 4)")
|
||||
{
|
||||
REQUIRE(transform * p == Tuple::Point(5, 3, 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] A shearing transformation moves y in proportion to x", "[Matrix]")
|
||||
SCENARIO("A shearing transformation moves y in proportion to x", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::shearing(0, 0, 1, 0, 0, 0);
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
|
||||
REQUIRE(transform * p == Tuple::Point(2, 5, 4));
|
||||
GIVEN("transform <- shearing(0, 0, 1, 0, 0, 0)")
|
||||
{
|
||||
Matrix transform = Matrix::shearing(0, 0, 1, 0, 0, 0);
|
||||
AND_GIVEN("p <- point(2, 3, 4)")
|
||||
{
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
THEN("transform * p == point(2, 5, 4)")
|
||||
{
|
||||
REQUIRE(transform * p == Tuple::Point(2, 5, 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] A shearing transformation moves y in proportion to z", "[Matrix]")
|
||||
SCENARIO("A shearing transformation moves y in proportion to z", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::shearing(0, 0, 0, 1, 0, 0);
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
|
||||
REQUIRE(transform * p == Tuple::Point(2, 7, 4));
|
||||
GIVEN("transform <- shearing(0, 0, 0, 1, 0, 0)")
|
||||
{
|
||||
Matrix transform = Matrix::shearing(0, 0, 0, 1, 0, 0);
|
||||
AND_GIVEN("p <- point(2, 3, 4)")
|
||||
{
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
THEN("transform * p == point(2, 7, 4)")
|
||||
{
|
||||
REQUIRE(transform * p == Tuple::Point(2, 7, 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] A shearing transformation moves z in proportion to x", "[Matrix]")
|
||||
SCENARIO("A shearing transformation moves z in proportion to x", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::shearing(0, 0, 0, 0, 1, 0);
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
|
||||
REQUIRE(transform * p == Tuple::Point(2, 3, 6));
|
||||
GIVEN("transform <- shearing(0, 0, 0, 0, 1, 0)")
|
||||
{
|
||||
Matrix transform = Matrix::shearing(0, 0, 0, 0, 1, 0);
|
||||
AND_GIVEN("p <- point(2, 3, 4)")
|
||||
{
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
THEN("transform * p == point(2, 3, 6)")
|
||||
{
|
||||
REQUIRE(transform * p == Tuple::Point(2, 3, 6));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] A shearing transformation moves z in proportion to y", "[Matrix]")
|
||||
SCENARIO("A shearing transformation moves z in proportion to y", "[features/transformations.feature]")
|
||||
{
|
||||
Matrix transform = Matrix::shearing(0, 0, 0, 0, 0, 1);
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
|
||||
REQUIRE(transform * p == Tuple::Point(2, 3, 7));
|
||||
GIVEN("transform <- shearing(0, 0, 0, 0, 0, 1)")
|
||||
{
|
||||
Matrix transform = Matrix::shearing(0, 0, 0, 0, 0, 1);
|
||||
AND_GIVEN("p <- point(2, 3, 4)")
|
||||
{
|
||||
Tuple p = Tuple::Point(2, 3, 4);
|
||||
THEN("transform * p == point(2, 3, 7)")
|
||||
{
|
||||
REQUIRE(transform * p == Tuple::Point(2, 3, 7));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] Individual transformations are applied in sequence", "[Matrix]")
|
||||
SCENARIO("Individual transformations are applied in sequence", "[features/transformations.feature]")
|
||||
{
|
||||
Tuple p = Tuple::Point(1, 0, 1);
|
||||
Matrix a = Matrix::rotation_x(std::numbers::pi / 2);
|
||||
Matrix b = Matrix::scaling(5, 5, 5);
|
||||
Matrix c = Matrix::translation(10, 5, 7);
|
||||
GIVEN("p <- point(1, 0, 1)")
|
||||
{
|
||||
Tuple p = Tuple::Point(1, 0, 1);
|
||||
AND_GIVEN("A <- rotation_x(pi/2)")
|
||||
{
|
||||
Matrix A = Matrix::rotation_x(std::numbers::pi / 2);
|
||||
AND_GIVEN("B <- scaling(5, 5, 5)")
|
||||
{
|
||||
Matrix B = Matrix::scaling(5, 5, 5);
|
||||
AND_GIVEN("C <- translation(10, 5, 7))")
|
||||
{
|
||||
Matrix C = Matrix::translation(10, 5, 7);
|
||||
|
||||
// Appply rotation first.
|
||||
Tuple p2 = a * p;
|
||||
REQUIRE(p2 == Tuple::Point(1, -1, 0));
|
||||
// Then Apply scaling
|
||||
Tuple p3 = b * p2;
|
||||
REQUIRE(p3 == Tuple::Point(5, -5, 0));
|
||||
// Then Apply translation
|
||||
Tuple p4 = c * p3;
|
||||
REQUIRE(p4 == Tuple::Point(15, 0, 7));
|
||||
// Apply rotation first.
|
||||
WHEN("p2 <- A * p")
|
||||
{
|
||||
Tuple p2 = A * p;
|
||||
THEN("p2 = point(1, -1, 0)")
|
||||
{
|
||||
REQUIRE(p2 == Tuple::Point(1, -1, 0));
|
||||
}
|
||||
|
||||
// Then Apply scaling
|
||||
WHEN("p3 <- B * p2")
|
||||
{
|
||||
Tuple p3 = B * p2;
|
||||
THEN("p3 = point(5, -5, 0)")
|
||||
{
|
||||
REQUIRE(p3 == Tuple::Point(5, -5, 0));
|
||||
}
|
||||
// Then Apply translation
|
||||
WHEN("p4 = C * p3")
|
||||
|
||||
{
|
||||
Tuple p4 = C * p3;
|
||||
THEN("p4 = point(15, 0, 7)")
|
||||
{
|
||||
REQUIRE(p4 == Tuple::Point(15, 0, 7));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][Trans] Chained transformation must be applied in rever order", "[Matrix]")
|
||||
SCENARIO("Chained transformation must be applied in revert order", "[features/transformations.feature]")
|
||||
{
|
||||
Tuple p = Tuple::Point(1, 0, 1);
|
||||
Matrix a = Matrix::rotation_x(std::numbers::pi / 2);
|
||||
Matrix b = Matrix::scaling(5, 5, 5);
|
||||
Matrix c = Matrix::translation(10, 5, 7);
|
||||
Matrix t = c * b * a;
|
||||
|
||||
REQUIRE(t * p == Tuple::Point(15, 0, 7));
|
||||
GIVEN("p <- point(1, 0, 1)")
|
||||
{
|
||||
Tuple p = Tuple::Point(1, 0, 1);
|
||||
AND_GIVEN("A <- rotation_x(pi/2)")
|
||||
{
|
||||
Matrix A = Matrix::rotation_x(std::numbers::pi / 2);
|
||||
AND_GIVEN("B <- scaling(5, 5, 5)")
|
||||
{
|
||||
Matrix B = Matrix::scaling(5, 5, 5);
|
||||
AND_GIVEN("C <- translation(10, 5, 7))")
|
||||
{
|
||||
Matrix C = Matrix::translation(10, 5, 7);
|
||||
WHEN("t <- C * B * A")
|
||||
{
|
||||
Matrix T = C * B * A;
|
||||
THEN("T * p == point(15, 0, 7)")
|
||||
{
|
||||
REQUIRE(T * p == Tuple::Point(15, 0, 7));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,31 +35,59 @@ using namespace Raytracer;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] Creating and querying a ray", "[Rays]")
|
||||
SCENARIO("Creating and querying a ray", "[features/rays.feature]")
|
||||
{
|
||||
Tuple origin = Tuple::Point(1, 2, 3);
|
||||
Tuple direction = Tuple::Vector(4, 5, 6);
|
||||
Ray r(origin, direction);
|
||||
|
||||
REQUIRE(r.origin() == origin);
|
||||
REQUIRE(r.direction() == direction);
|
||||
GIVEN("origin <- point(1, 2, 3)")
|
||||
{
|
||||
Tuple origin = Tuple::Point(1, 2, 3);
|
||||
AND_GIVEN("direction <- vector(4, 5, 6)")
|
||||
{
|
||||
Tuple direction = Tuple::Vector(4, 5, 6);
|
||||
WHEN("r <- ray(origin, direction)")
|
||||
{
|
||||
Ray r(origin, direction);
|
||||
THEN("r.origin = origin")
|
||||
{
|
||||
REQUIRE(r.origin() == origin);
|
||||
}
|
||||
AND_THEN("r.direction = direction")
|
||||
{
|
||||
REQUIRE(r.direction() == direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] Computing a point from a distance", "[Rays]")
|
||||
SCENARIO("Computing a point from a distance", "[features/rays.feature]")
|
||||
{
|
||||
Ray r(Tuple::Point(2, 3, 4), Tuple::Vector(1, 0, 0));
|
||||
|
||||
REQUIRE(r.position(0) == Tuple::Point(2, 3, 4));
|
||||
REQUIRE(r.position(1) == Tuple::Point(3, 3, 4));
|
||||
REQUIRE(r.position(-1) == Tuple::Point(1, 3, 4));
|
||||
REQUIRE(r.position(2.5) == Tuple::Point(4.5, 3, 4));
|
||||
GIVEN("r <- ray(point(2, 3, 4), vector(1, 0, 0))")
|
||||
{
|
||||
Ray r(Tuple::Point(2, 3, 4), Tuple::Vector(1, 0, 0));
|
||||
THEN("position(r,0) = point(2, 3, 4)")
|
||||
{
|
||||
REQUIRE(r.position(0) == Tuple::Point(2, 3, 4));
|
||||
}
|
||||
AND_THEN("position(r,1) == point(3, 3, 4)")
|
||||
{
|
||||
REQUIRE(r.position(1) == Tuple::Point(3, 3, 4));
|
||||
}
|
||||
AND_THEN("position(r,-1) = point(1, 3, 4)")
|
||||
{
|
||||
REQUIRE(r.position(-1) == Tuple::Point(1, 3, 4));
|
||||
}
|
||||
AND_THEN("position(r,2.5) == point(4.5, 3, 4)")
|
||||
{
|
||||
REQUIRE(r.position(2.5) == Tuple::Point(4.5, 3, 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] a ray intersects a sphere at two points", "[Sphere]")
|
||||
SCENARIO("A ray intersects a sphere at two points", "[features/spheres.feature]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, -5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
@@ -72,7 +100,7 @@ TEST_CASE("[05][Rays] a ray intersects a sphere at two points", "[Sphere]")
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] a ray intersects a sphere at a tangent", "[Sphere]")
|
||||
SCENARIO("A ray intersects a sphere at a tangent", "[features/spheres.feature]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 1, -5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
@@ -85,7 +113,7 @@ TEST_CASE("[05][Rays] a ray intersects a sphere at a tangent", "[Sphere]")
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] a ray misses a sphere", "[Sphere]")
|
||||
SCENARIO("A ray misses a sphere", "[features/spheres.feature]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 2, -5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
@@ -96,7 +124,7 @@ TEST_CASE("[05][Rays] a ray misses a sphere", "[Sphere]")
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] a originates inside a sphere", "[Sphere]")
|
||||
SCENARIO("A originates inside a sphere", "[features/spheres.feature]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, 0), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
@@ -109,7 +137,7 @@ TEST_CASE("[05][Rays] a originates inside a sphere", "[Sphere]")
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] a sphere is behind a ray", "[Sphere]")
|
||||
SCENARIO("A sphere is behind a ray", "[features/spheres.feature]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, 5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
@@ -122,7 +150,7 @@ TEST_CASE("[05][Rays] a sphere is behind a ray", "[Sphere]")
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] Test Sphere Object", "[Sphere]")
|
||||
SCENARIO("Test Sphere Object", "[features/spheres.feature]")
|
||||
{
|
||||
Sphere s1;
|
||||
Sphere s2 = s1;
|
||||
@@ -134,7 +162,7 @@ TEST_CASE("[05][Rays] Test Sphere Object", "[Sphere]")
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] An intersection encapsulates t and object", "[Intersections]")
|
||||
SCENARIO("An intersection encapsulates t and object", "[features/intersections.feature]")
|
||||
{
|
||||
Sphere s;
|
||||
Intersection i(3.5, s);
|
||||
@@ -145,7 +173,7 @@ TEST_CASE("[05][Rays] An intersection encapsulates t and object", "[Intersection
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] Aggregating intersections", "[Intersections]")
|
||||
SCENARIO("Aggregating intersections", "[features/intersections.feature]")
|
||||
{
|
||||
Sphere s;
|
||||
Intersection i1(1, s);
|
||||
@@ -159,7 +187,7 @@ TEST_CASE("[05][Rays] Aggregating intersections", "[Intersections]")
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] Intersect set the object on the intersection", "[Intersections]")
|
||||
SCENARIO("Intersect sets the object on the intersection", "[features/spheres.feature]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, 5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
@@ -172,7 +200,7 @@ TEST_CASE("[05][Rays] Intersect set the object on the intersection", "[Intersect
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] The hit, when all intersections have positive t", "[Intersections]")
|
||||
SCENARIO("The hit, when all intersections have positive t", "[features/intersections.feature]")
|
||||
{
|
||||
Sphere s;
|
||||
Intersection i1(1, s);
|
||||
@@ -186,7 +214,7 @@ TEST_CASE("[05][Rays] The hit, when all intersections have positive t", "[Inters
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] The hit, when some intersections have negative t", "[Intersections]")
|
||||
SCENARIO("The hit, when some intersections have negative t", "[features/intersections.feature]")
|
||||
{
|
||||
Sphere s;
|
||||
Intersection i1(-1, s);
|
||||
@@ -200,7 +228,7 @@ TEST_CASE("[05][Rays] The hit, when some intersections have negative t", "[Inter
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] The hit, when all intersections have negative t", "[Intersections]")
|
||||
SCENARIO("The hit, when all intersections have negative t", "[features/intersections.feature]")
|
||||
{
|
||||
Sphere s;
|
||||
Intersection i1(-2, s);
|
||||
@@ -214,7 +242,7 @@ TEST_CASE("[05][Rays] The hit, when all intersections have negative t", "[Inters
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] The hit is always the lowest nonnegative intersection", "[Intersections]")
|
||||
SCENARIO("The hit is always the lowest nonnegative intersection", "[features/intersections.feature]")
|
||||
{
|
||||
Sphere s;
|
||||
Intersection i1(5, s);
|
||||
@@ -230,7 +258,7 @@ TEST_CASE("[05][Rays] The hit is always the lowest nonnegative intersection", "[
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] Translating a ray", "[Rays]")
|
||||
SCENARIO("Translating a ray", "[features/rays.feature]")
|
||||
{
|
||||
Ray r(Tuple::Point(1, 2, 3), Tuple::Vector(0, 1, 0));
|
||||
Matrix m = Matrix::translation(3, 4, 5);
|
||||
@@ -242,7 +270,7 @@ TEST_CASE("[05][Rays] Translating a ray", "[Rays]")
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] Scaling a ray", "[Rays]")
|
||||
SCENARIO("Scaling a ray", "[features/rays.feature]")
|
||||
{
|
||||
Ray r(Tuple::Point(1, 2, 3), Tuple::Vector(0, 1, 0));
|
||||
Matrix m = Matrix::scaling(2, 3, 4);
|
||||
@@ -254,15 +282,21 @@ TEST_CASE("[05][Rays] Scaling a ray", "[Rays]")
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] A sphere's default transformation", "[Sphere]")
|
||||
SCENARIO("A sphere's default transformation", "[features/spheres.feature]")
|
||||
{
|
||||
Sphere s;
|
||||
REQUIRE(s.transform() == Matrix::identity());
|
||||
GIVEN("s <- Sphere()")
|
||||
{
|
||||
Sphere s;
|
||||
THEN("s.transform = identity_matrix")
|
||||
{
|
||||
REQUIRE(s.transform() == Matrix::identity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] Changing a sphere's transformation", "[Sphere]")
|
||||
SCENARIO("Changing a sphere's transformation", "[features/spheres.feature]")
|
||||
{
|
||||
Sphere s;
|
||||
Matrix t = Matrix::translation(2, 3, 4);
|
||||
@@ -271,8 +305,8 @@ TEST_CASE("[05][Rays] Changing a sphere's transformation", "[Sphere]")
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
#if 0
|
||||
TEST_CASE("[05][Rays] Intersecting a scaled sphere with a ray", "[Sphere]")
|
||||
|
||||
SCENARIO("Intersecting a scaled sphere with a ray", "[features/spheres.feature]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, -5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
@@ -283,10 +317,10 @@ TEST_CASE("[05][Rays] Intersecting a scaled sphere with a ray", "[Sphere]")
|
||||
REQUIRE(xs[0].distance_t() == 3);
|
||||
REQUIRE(xs[1].distance_t() == 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] Intersecting a translated sphere with a ray", "[Sphere]")
|
||||
SCENARIO("Intersecting a translated sphere with a ray", "[features/spheres.feature]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, -5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
|
||||
Reference in New Issue
Block a user