#include "tap.hpp" #include "geom/ellipse.hpp" #include "geom/ray.hpp" #include "point.hpp" #include "vector.hpp" /////////////////////////////////////////////////////////////////////////////// void test_intersection (util::TAP::logger &tap) { static struct { util::geom::ellipse3f shape; util::geom::ray3f caster; float distance; const char *message; } const TESTS[] = { { .shape = { .origin = {0}, .radius = {1}, .up = {0,1,0} }, .caster = { .origin = { 0, 0, -2 }, .direction = util::vector3f{ 0, 0, 1 } }, .distance = 1, .message = "sphere on origin, ray mostly on origin" }, { .shape = { .origin = {0}, .radius = {1,1,1.5}, .up = {0,1,0} }, .caster = { .origin = {0,0,-2}, .direction = util::vector3f{0,0,1} }, .distance = .5f, .message = "ellipse on origin, extended on z, ray along z", }, { .shape = { .origin = 1, .radius = 1, .up = { 0, 1, 0 } }, .caster = { .origin = {1,1,3}, .direction = {0,0,-1} }, .distance = 1.f, .message = "ellipse at 1,1,1, ray along -z", } }; for (auto const& t: TESTS) { tap.expect_eq (t.distance, distance (t.caster, t.shape), "%s", t.message); } } void test_area (util::TAP::logger &tap) { static struct { util::geom::ellipse3f shape; float value; const char *message; } const TESTS[] = { { .shape = { .origin = {0}, .radius = {1}, .up = {0} }, .value = 12.57f, .message = "unit radius" }, }; for (auto const& t: TESTS) { auto found = area (t.shape); tap.expect (util::relatively_equal (found, t.value, 1.08e-2f), "%!", t.message); } } void test_cover (util::TAP::logger &tap) { static struct { std::vector cloud; const char *message; } const TESTS[] = { { { {-1, 0, 0}, { 0, 0, 0}, { 1, 0, 0}, }, "three spaced across x" }, { { {-1, 0, 0}, { 0, 0, 0}, { 1, 0, 0}, { 0,-1, 0}, { 0, 1, 0}, }, "planar circle about origin" }, { { {-1, 0, 0}, { 0, 0, 0}, { 1, 0, 0}, { 0,-1, 0}, { 0, 1, 0}, { 0, 0,-1}, { 0, 0, 1}, }, "sphere about origin" }, }; for (auto const &t: TESTS) { auto const shape = util::geom::cover (util::view {t.cloud}); auto const success = std::all_of ( t.cloud.begin (), t.cloud.end (), [shape] (auto p) { return intersects (shape, p); }); std::cout << shape << '\n'; tap.expect (success, "%!", t.message); } } /////////////////////////////////////////////////////////////////////////////// int main () { util::TAP::logger tap; test_intersection (tap); test_area (tap); test_cover (tap); return tap.status (); }