region: add intersection operation

This commit is contained in:
Danny Robson 2020-03-12 12:45:05 +11:00
parent 7550ad7c23
commit 8697c103d6
2 changed files with 65 additions and 0 deletions

View File

@ -226,6 +226,24 @@ namespace cruft {
}
///////////////////////////////////////////////////////////////////////////
/// Construct a region that consists of the overlapping portions of two
/// supplied regions.
///
/// The behaviour is undefined if there is no overlap. The caller should
/// test using `intersects` if required beforehand.
template <typename T, std::size_t S>
region<S,T>
intersection (region<S,T> const a, region<S,T> const b)
{
// Find the two corners of the new region.
auto const lo = cruft::max (a.base (), b.base ());
auto const hi = cruft::min (a.away (), b.away ());
CHECK (all (lo <= hi));
return { lo, hi };
}
///////////////////////////////////////////////////////////////////////////
/// returns the squared minimum distance from a region to a given point
template <size_t S, typename T>

View File

@ -136,5 +136,52 @@ main (int, char **)
}
};
// Test expected results of 2 region interesection
{
using p_t = cruft::point2i;
struct {
cruft::region2i a;
cruft::region2i b;
cruft::region2i res;
char const *msg;
} const TESTS[] = {
{
.a = { p_t { 0, 0 }, p_t { 1, 1 } },
.b = { p_t { 0, 0 }, p_t { 1, 1 } },
.res = { p_t { 0, 0 }, p_t { 1, 1 } },
.msg = "identical, unit sizes",
},
{
.a = { p_t { 0, 0 }, p_t { 1, 1 } },
.b = { p_t { 1, 1 }, p_t { 2, 2 } },
.res = { p_t { 1, 1 }, p_t { 1, 1 } },
.msg = "unit sized, shared corner",
},
{
.a = { p_t { -4, -5 }, p_t { 5, 3 } },
.b = { p_t { -1, -2 }, p_t { 2, 1 } },
.res = { p_t { -1, -2 }, p_t { 2, 1 } },
.msg = "a contains b",
},
{
.a = { p_t { -1, -2 }, p_t { 2, 1 } },
.b = { p_t { -4, -5 }, p_t { 5, 3 } },
.res = { p_t { -1, -2 }, p_t { 2, 1 } },
.msg = "b contains a",
},
{
.a = { p_t { -3, -1 }, p_t { 4, 8 } },
.b = { p_t { -1, -4 }, p_t { 6, 2 } },
.res = { p_t { -1, -1 }, p_t { 4, 2 } },
.msg = "partial overlap",
},
};
for (auto const &[a, b, res, message]: TESTS)
tap.expect_eq (intersection (a, b), res, "region-region interesection: %!", message);
}
return tap.status ();
}