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

View File

@ -14,39 +14,18 @@ main (int, char**)
{
// Test contraction
AABB2f box {
{ 2, 2 },
{ 8, 8 }
};
const AABB2f val { { 2, 2 }, { 8, 8 } };
const AABB2f res { { 3, 3 }, { 7, 7 } };
box.contract (2.f);
tap.expect_eq<AABB2f, AABB2f> (box, { { 3, 3 }, { 7, 7 }}, "over contraction");
tap.expect_eq (val.contracted (2.f), res, "over contraction");
}
{
// Test expansion
AABB2f box {
{ 2, 2 },
{ 8, 8 }
};
const AABB2f val { { 2, 2 }, { 8, 8 } };
const AABB2f res { { 1, 1 }, { 9, 9 } };
box.expand (2.f);
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");
tap.expect_eq (val.expanded (2.f), res, "expansion");
}
return tap.status ();