#include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// void test_intersection (cruft::TAP::logger &tap) { static struct { cruft::geom::ellipse3f shape; cruft::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 = cruft::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 = cruft::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 (cruft::TAP::logger &tap) { static struct { cruft::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 (cruft::relatively_equal (found, t.value, 1.08e-2f), "{}", t.message); } } void test_cover (cruft::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 = cruft::geom::cover (cruft::view {t.cloud}); auto const success = std::all_of ( t.cloud.begin (), t.cloud.end (), [shape] (auto p) { return intersects (shape, p); }); tap.expect (success, "{}", t.message); } } /////////////////////////////////////////////////////////////////////////////// int main () { cruft::TAP::logger tap; test_intersection (tap); test_area (tap); test_cover (tap); return tap.status (); }