2018-04-16 15:59:39 +10:00
|
|
|
#include "tap.hpp"
|
|
|
|
|
|
|
|
#include "geom/ellipse.hpp"
|
|
|
|
#include "geom/ray.hpp"
|
|
|
|
#include "point.hpp"
|
|
|
|
#include "vector.hpp"
|
|
|
|
|
|
|
|
|
2018-04-17 17:11:41 +10:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void
|
|
|
|
test_intersection (util::TAP::logger &tap)
|
|
|
|
{
|
2018-04-16 15:59:39 +10:00
|
|
|
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",
|
|
|
|
},
|
2018-04-17 14:26:23 +10:00
|
|
|
|
|
|
|
{
|
|
|
|
.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) {
|
|
|
|
tap.expect_eq (t.distance, distance (t.caster, t.shape), "%s", t.message);
|
|
|
|
}
|
2018-04-17 17:11:41 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-18 21:47:53 +10:00
|
|
|
void
|
|
|
|
test_cover (util::TAP::logger &tap)
|
|
|
|
{
|
|
|
|
static struct {
|
|
|
|
std::vector<util::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 = util::geom::cover (util::view<const util::point3f*> {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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-17 17:11:41 +10:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
int
|
|
|
|
main ()
|
|
|
|
{
|
|
|
|
util::TAP::logger tap;
|
|
|
|
|
|
|
|
test_intersection (tap);
|
|
|
|
test_area (tap);
|
2018-04-18 21:47:53 +10:00
|
|
|
test_cover (tap);
|
2018-04-16 15:59:39 +10:00
|
|
|
|
|
|
|
return tap.status ();
|
|
|
|
}
|