geom/aabb: remove mutating operators

This commit is contained in:
Danny Robson 2017-08-24 16:25:57 +10:00
parent dba4e673ca
commit 359702fb86
3 changed files with 42 additions and 93 deletions

View File

@ -85,91 +85,65 @@ AABB<S,T>::closest (point<S,T> q) const
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T> template <size_t S, typename T>
AABB<S,T>& AABB<S,T>
AABB<S,T>::expand (util::vector<S,T> mag) AABB<S,T>::expanded (vector<S,T> mag) const noexcept
{ {
p0 -= mag / T{2}; CHECK (all (mag >= T{0}));
p1 += mag / T{2}; CHECK (all (mag < p1 - p0));
return *this; return {
} p0 - mag / T{2},
p1 + mag / T{2}
};
//-----------------------------------------------------------------------------
template <size_t S, typename T>
AABB<S,T>&
AABB<S,T>::expand (T t)
{
return expand (vector<S,T> {t});
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <size_t S, typename T> template <size_t S, typename T>
AABB<S,T> AABB<S,T>
AABB<S,T>::expanded (vector<S,T> mag) AABB<S,T>::expanded (T t) const noexcept
{ {
auto ret = *this; CHECK_GE (t, T{0});
ret.expand (mag); CHECK (all (t < p1 - p0));
return ret;
}
return {
//----------------------------------------------------------------------------- p0 - t / T{2},
template <size_t S, typename T> p1 + t / T{2}
AABB<S,T> };
AABB<S,T>::expanded (T t)
{
return expanded (vector<S,T> {t});
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T> template <size_t S, typename T>
AABB<S,T>& AABB<S,T>
AABB<S,T>::contract (util::vector<S,T> mag) AABB<S,T>::contracted (util::vector<S,T> mag) const noexcept
{ {
// Avoid contracting magnitudes larger than our extent CHECK (all (mag > T{0}));
auto diff = p1 - p0; CHECK (all (mag <= p1 - p0));
auto delta = min (diff, mag);
p0 += delta / T{2}; return {
p1 -= delta / T{2}; p0 + mag / T{2},
p1 - mag / T{2}
return *this; };
}
//-----------------------------------------------------------------------------
template <size_t S, typename T>
AABB<S,T>&
AABB<S,T>::contract (T mag)
{
return contract (util::vector<S,T> {mag});
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <size_t S, typename T> template <size_t S, typename T>
AABB<S,T> AABB<S,T>
AABB<S,T>::contracted (util::vector<S,T> mag) const AABB<S,T>::contracted (T mag) const noexcept
{ {
AABB<S,T> res = *this; CHECK_GE (mag, T{0});
res.contract (mag); CHECK (all (mag <= p1 - p0));
return res;
return {
p0 + mag / T{2},
p1 - mag / T{2}
};
} }
//----------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T>
AABB<S,T>
AABB<S,T>::contracted (T mag) const
{
return contracted (vector<S,T> {mag});
}
//-----------------------------------------------------------------------------
template <size_t S, typename T> template <size_t S, typename T>
void void
AABB<S,T>::cover (point<S,T> p) AABB<S,T>::cover (point<S,T> p)

View File

@ -36,15 +36,11 @@ namespace util::geom {
point<S,T> closest (point<S,T>) const; point<S,T> closest (point<S,T>) const;
AABB<S,T>& expand (util::vector<S,T>); AABB<S,T> expanded (util::vector<S,T>) const noexcept;
AABB<S,T>& expand (T); AABB<S,T> expanded (T) const noexcept;
AABB<S,T> expanded (util::vector<S,T>);
AABB<S,T> expanded (T);
AABB<S,T>& contract (util::vector<S,T>); AABB<S,T> contracted (util::vector<S,T>) const noexcept;
AABB<S,T>& contract (T); AABB<S,T> contracted (T) const noexcept;
AABB<S,T> contracted (util::vector<S,T>) const;
AABB<S,T> contracted (T) const;
void cover (point<S,T>); void cover (point<S,T>);

View File

@ -14,39 +14,18 @@ main (int, char**)
{ {
// Test contraction // Test contraction
AABB2f box { const AABB2f val { { 2, 2 }, { 8, 8 } };
{ 2, 2 }, const AABB2f res { { 3, 3 }, { 7, 7 } };
{ 8, 8 }
};
box.contract (2.f); tap.expect_eq (val.contracted (2.f), res, "over contraction");
tap.expect_eq<AABB2f, AABB2f> (box, { { 3, 3 }, { 7, 7 }}, "over contraction");
} }
{ {
// Test expansion // Test expansion
AABB2f box { const AABB2f val { { 2, 2 }, { 8, 8 } };
{ 2, 2 }, const AABB2f res { { 1, 1 }, { 9, 9 } };
{ 8, 8 }
};
box.expand (2.f); tap.expect_eq (val.expanded (2.f), res, "expansion");
tap.expect_eq<AABB2f, AABB2f> (box, { { 1, 1 }, { 9, 9 }}, "expansion");
}
{
// Ensure we don't wrap-around on unsigned position types when contracting
AABB2f small {
{ 0, 0 },
{ 1, 1 }
};
small.contract (10);
tap.expect_eq<AABB2f, AABB2f> (small, { { 0.5f, 0.5f }, { 0.5f, 0.5f }}, "unsigned over-contract");
} }
return tap.status (); return tap.status ();