libcruft-util/test/geom/ellipse.cpp

125 lines
3.1 KiB
C++
Raw Permalink Normal View History

#include <cruft/util/tap.hpp>
2018-04-16 15:59:39 +10:00
#include <cruft/util/geom/ellipse.hpp>
#include <cruft/util/geom/ray.hpp>
#include <cruft/util/point.hpp>
#include <cruft/util/vector.hpp>
2018-04-16 15:59:39 +10:00
2018-04-17 17:11:41 +10:00
///////////////////////////////////////////////////////////////////////////////
void
test_intersection (cruft::TAP::logger &tap)
2018-04-17 17:11:41 +10:00
{
2018-04-16 15:59:39 +10:00
static struct {
cruft::geom::ellipse3f shape;
cruft::geom::ray3f caster;
2018-04-16 15:59:39 +10:00
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 } },
2018-04-16 15:59:39 +10:00
.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} },
2018-04-16 15:59:39 +10:00
.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",
}
2018-04-16 15:59:39 +10:00
};
for (auto const& t: TESTS) {
2021-04-13 16:05:08 +10:00
tap.expect_eq (t.distance, distance (t.caster, t.shape), "{:s}", t.message);
2018-04-16 15:59:39 +10:00
}
2018-04-17 17:11:41 +10:00
}
void
test_area (cruft::TAP::logger &tap)
2018-04-17 17:11:41 +10:00
{
static struct {
cruft::geom::ellipse3f shape;
2018-04-17 17:11:41 +10:00
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);
2021-04-13 16:05:08 +10:00
tap.expect (cruft::relatively_equal (found, t.value, 1.08e-2f), "{}", t.message);
2018-04-17 17:11:41 +10:00
}
}
void
test_cover (cruft::TAP::logger &tap)
{
static struct {
std::vector<cruft::point3f> 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<const cruft::point3f*> {t.cloud});
auto const success = std::all_of (
t.cloud.begin (),
t.cloud.end (),
[shape] (auto p) {
return intersects (shape, p);
});
2021-04-13 16:05:08 +10:00
tap.expect (success, "{}", t.message);
}
}
2018-04-17 17:11:41 +10:00
///////////////////////////////////////////////////////////////////////////////
int
main ()
{
cruft::TAP::logger tap;
2018-04-17 17:11:41 +10:00
test_intersection (tap);
test_area (tap);
test_cover (tap);
2018-04-16 15:59:39 +10:00
return tap.status ();
}