#include #include #include "rays.h" #include "spheres.h" #include "intersections_shapes.h" #include "runner.h" #include "matrices.h" #include "transformations.h" static bool spheres_test_0(const char ** scenario) { *scenario = "A ray intersects a sphere at two points"; struct ray r = ray(point(0.0f, 0.0f, -5.0f), vector(0.0f, 0.0f, 1.0f)); struct shape s = sphere(); struct intersections xs; xs.count = 0; intersect(&s, r, &xs); return xs.count == 2 && float_equal(xs.i[0].t, 4.0f) && float_equal(xs.i[1].t, 6.0f); } static bool spheres_test_1(const char ** scenario) { *scenario = "A ray intersects a sphere at a tangent"; struct ray r = ray(point(0.0f, 1.0f, -5.0f), vector(0.0f, 0.0f, 1.0f)); struct shape s = sphere(); struct intersections xs; xs.count = 0; intersect(&s, r, &xs); return xs.count == 2 && float_equal(xs.i[0].t, 5.0f) && float_equal(xs.i[1].t, 5.0f); } static bool spheres_test_2(const char ** scenario) { *scenario = "A ray misses a sphere"; struct ray r = ray(point(0.0f, 2.0f, -5.0f), vector(0.0f, 0.0f, 1.0f)); struct shape s = sphere(); struct intersections xs; xs.count = 0; intersect(&s, r, &xs); return xs.count == 0; } static bool spheres_test_3(const char ** scenario) { *scenario = "A ray originates in a sphere"; struct ray r = ray(point(0.0f, 0.0f, 0.0f), vector(0.0f, 0.0f, 1.0f)); struct shape s = sphere(); struct intersections xs; xs.count = 0; intersect(&s, r, &xs); return xs.count == 2 && float_equal(xs.i[0].t, -1.0f) && float_equal(xs.i[1].t, 1.0f); } static bool spheres_test_4(const char ** scenario) { *scenario = "A sphere is behind a ray"; struct ray r = ray(point(0.0f, 0.0f, 5.0f), vector(0.0f, 0.0f, 1.0f)); struct shape s = sphere(); struct intersections xs; xs.count = 0; intersect(&s, r, &xs); return xs.count == 2 && float_equal(xs.i[0].t, -6.0f) && float_equal(xs.i[1].t, -4.0f); } static bool spheres_test_5(const char ** scenario) { *scenario = "Intersect sets the object on the intersection"; struct ray r = ray(point(0.0f, 0.0f, -5.0f), vector(0.0f, 0.0f, 1.0f)); struct shape s = sphere(); struct intersections xs; xs.count = 0; intersect(&s, r, &xs); return xs.count == 2 && xs.i[0].object == &s && xs.i[1].object == &s; } static bool spheres_test_6(const char ** scenario) { *scenario = "Intersecting a scaled sphere with a ray"; struct ray r = ray(point(0.0f, 0.0f, -5.0f), vector(0.0f, 0.0f, 1.0f)); struct shape s = sphere(); s.transform = scaling(2.0f, 2.0f, 2.0f); struct intersections xs; xs.count = 0; intersect(&s, r, &xs); return xs.count == 2 && float_equal(xs.i[0].t, 3.0f) && float_equal(xs.i[1].t, 7.0f); } static bool spheres_test_7(const char ** scenario) { *scenario = "Intersecting a translated sphere with a ray"; struct ray r = ray(point(0.0f, 0.0f, 5.0f), vector(0.0f, 0.0f, 1.0f)); struct shape s = sphere(); s.transform = translation(5.0f, 0.0f, 0.0f); struct intersections xs; xs.count = 0; intersect(&s, r, &xs); return xs.count == 0; } static bool spheres_test_8(const char ** scenario) { *scenario = "The normal on a sphere at a point on the x axis"; struct shape s = sphere(); struct tuple n = normal_at(&s, point(1.0f, 0.0f, 0.0f)); return tuple_equal(n, vector(1.0f, 0.0f, 0.0f)); } static bool spheres_test_9(const char ** scenario) { *scenario = "The normal on a sphere at a point on the y axis"; struct shape s = sphere(); struct tuple n = normal_at(&s, point(0.0f, 1.0f, 0.0f)); return tuple_equal(n, vector(0.0f, 1.0f, 0.0f)); } static bool spheres_test_10(const char ** scenario) { *scenario = "The normal on a sphere at a point on the z axis"; struct shape s = sphere(); struct tuple n = normal_at(&s, point(0.0f, 0.0f, 1.0f)); return tuple_equal(n, vector(0.0f, 0.0f, 1.0f)); } static bool spheres_test_11(const char ** scenario) { *scenario = "The normal on a sphere at a nonaxial point"; struct shape s = sphere(); struct tuple n = normal_at(&s, point(0.5773502691896257, 0.5773502691896257, 0.5773502691896257)); return tuple_equal(n, vector(0.5773502691896257, 0.5773502691896257, 0.5773502691896257)); } static bool spheres_test_12(const char ** scenario) { *scenario = "The normal is a normalized vector"; struct shape s = sphere(); struct tuple n = normal_at(&s, point(0.5773502691896257, 0.5773502691896257, 0.5773502691896257)); return tuple_equal(n, tuple_normalize(n)); } static bool spheres_test_13(const char ** scenario) { *scenario = "Computing the normal on a translated sphere"; struct shape s = sphere(); s.transform = translation(0.0f, 1.0f, 0.0f); struct tuple n = normal_at(&s, point(0.0f, 1.70711f, -0.70711)); return tuple_equal(n, vector(0.0f, 0.70711f, -0.70711f)); } static bool spheres_test_14(const char ** scenario) { *scenario = "Computing the normal on a transformed sphere"; struct shape s = sphere(); struct mat4x4 scale = scaling(1.0f, 0.5f, 1.0f); struct mat4x4 rotate = rotation_z(pi / 5.0f); struct mat4x4 m = mat4x4_mul_m(scale, rotate); s.transform = m; struct tuple n = normal_at(&s, point(0.0f, 0.7071067811865476, -0.7071067811865476)); return tuple_equal(n, vector(0.0f, 0.97014f, -0.24254f)); } test_t spheres_tests[] = { spheres_test_0, spheres_test_1, spheres_test_2, spheres_test_3, spheres_test_4, spheres_test_5, spheres_test_6, spheres_test_7, spheres_test_8, spheres_test_9, spheres_test_10, spheres_test_11, spheres_test_12, spheres_test_13, spheres_test_14, }; RUNNER(spheres_tests);