extent/region: update to use size parameters
This commit is contained in:
parent
e5d99b3370
commit
31d1d741e9
23
debug.hpp
23
debug.hpp
@ -304,15 +304,23 @@ namespace debug {
|
||||
bool valid (const T&);
|
||||
|
||||
|
||||
template <template<typename> class T, typename ...Args>
|
||||
template <
|
||||
template<size_t, typename...> class T,
|
||||
size_t S,
|
||||
typename ...Args
|
||||
>
|
||||
struct validator {
|
||||
static bool is_valid (const T<Args...>&);
|
||||
static bool is_valid (const T<S,Args...>&);
|
||||
};
|
||||
|
||||
|
||||
template <template<typename> class T, typename ...Args>
|
||||
bool valid (const T<Args...> &v)
|
||||
{ return validator<T,Args...>::is_valid (v); }
|
||||
template <
|
||||
template<size_t,typename...> class T,
|
||||
size_t S,
|
||||
typename ...Args
|
||||
>
|
||||
bool valid (const T<S,Args...> &v)
|
||||
{ return validator<T,S,Args...>::is_valid (v); }
|
||||
|
||||
|
||||
template <typename T>
|
||||
@ -320,7 +328,10 @@ namespace debug {
|
||||
{ CHECK (valid (t)); }
|
||||
|
||||
|
||||
template <template<typename> class T, typename ...Args>
|
||||
template <
|
||||
template<typename...> class T,
|
||||
typename ...Args
|
||||
>
|
||||
void sanity (const T<Args...> &t)
|
||||
{ CHECK (valid (t)); }
|
||||
}
|
||||
|
118
extent.cpp
118
extent.cpp
@ -25,42 +25,44 @@
|
||||
#include <cmath>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
util::extent<T>::extent (const T _width, const T _height):
|
||||
template <size_t S, typename T>
|
||||
util::extent<S,T>::extent (const T _width, const T _height):
|
||||
w (_width),
|
||||
h (_height)
|
||||
{
|
||||
static_assert (S == 2, "extents currently only support 2 dimensions");
|
||||
|
||||
CHECK_GE (w, 0);
|
||||
CHECK_GE (h, 0);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::extent<T>::extent (T t):
|
||||
template <size_t S, typename T>
|
||||
util::extent<S,T>::extent (T t):
|
||||
extent (t, t)
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::extent<T>::extent (vector<2,T> _v):
|
||||
template <size_t S, typename T>
|
||||
util::extent<S,T>::extent (vector<S,T> _v):
|
||||
extent (_v.x, _v.y)
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::extent<T>::extent (const util::extent<T> &rhs):
|
||||
template <size_t S, typename T>
|
||||
util::extent<S,T>::extent (const util::extent<S,T> &rhs):
|
||||
w (rhs.w),
|
||||
h (rhs.h)
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::extent<T>&
|
||||
util::extent<T>::operator= (const util::extent<T> &rhs)
|
||||
template <size_t S, typename T>
|
||||
util::extent<S,T>&
|
||||
util::extent<S,T>::operator= (extent<S,T> rhs)
|
||||
{
|
||||
w = rhs.w;
|
||||
h = rhs.h;
|
||||
@ -70,27 +72,27 @@ util::extent<T>::operator= (const util::extent<T> &rhs)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
T
|
||||
util::extent<T>::diameter (void) const
|
||||
util::extent<S,T>::diameter (void) const
|
||||
{
|
||||
return static_cast<T> (sqrt (w * w + h * h));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
T
|
||||
util::extent<T>::area (void) const
|
||||
util::extent<S,T>::area (void) const
|
||||
{
|
||||
return w * h;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
util::extent<T>
|
||||
util::extent<T>::expanded (util::vector<2,T> mag) const
|
||||
template <size_t S, typename T>
|
||||
util::extent<S,T>
|
||||
util::extent<S,T>::expanded (util::vector<S,T> mag) const
|
||||
{
|
||||
return {
|
||||
w + mag.x,
|
||||
@ -100,36 +102,36 @@ util::extent<T>::expanded (util::vector<2,T> mag) const
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::extent<T>
|
||||
util::extent<T>::expanded (T t) const
|
||||
template <size_t S, typename T>
|
||||
util::extent<S,T>
|
||||
util::extent<S,T>::expanded (T t) const
|
||||
{
|
||||
return expanded (util::vector<2,T> {t});
|
||||
return expanded (util::vector<S,T> {t});
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
float
|
||||
util::extent<T>::aspect (void) const
|
||||
util::extent<S,T>::aspect (void) const
|
||||
{
|
||||
return static_cast<float> (w) / static_cast<float> (h);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
bool
|
||||
util::extent<T>::empty (void) const
|
||||
util::extent<S,T>::empty (void) const
|
||||
{
|
||||
return almost_equal (area(), 0);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
T&
|
||||
util::extent<T>::operator[] (size_t idx)
|
||||
util::extent<S,T>::operator[] (size_t idx)
|
||||
{
|
||||
switch (idx) {
|
||||
case 0: return w;
|
||||
@ -142,9 +144,9 @@ util::extent<T>::operator[] (size_t idx)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
const T&
|
||||
util::extent<T>::operator[] (size_t idx) const
|
||||
util::extent<S,T>::operator[] (size_t idx) const
|
||||
{
|
||||
switch (idx) {
|
||||
case 0: return w;
|
||||
@ -157,18 +159,18 @@ util::extent<T>::operator[] (size_t idx) const
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
size_t
|
||||
util::extent<T>::size (void) const
|
||||
util::extent<S,T>::size (void) const
|
||||
{
|
||||
return 2u;
|
||||
return S;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
bool
|
||||
util::extent<T>::operator ==(const extent& rhs) const
|
||||
util::extent<S,T>::operator ==(const extent& rhs) const
|
||||
{
|
||||
return almost_equal (w, rhs.w) &&
|
||||
almost_equal (h, rhs.h);
|
||||
@ -176,15 +178,15 @@ util::extent<T>::operator ==(const extent& rhs) const
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
const util::extent<T> util::extent<T>::MIN {
|
||||
template <size_t S, typename T>
|
||||
const util::extent<S,T> util::extent<S,T>::MIN {
|
||||
0, 0
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
const util::extent<T> util::extent<T>::MAX {
|
||||
template <size_t S, typename T>
|
||||
const util::extent<S,T> util::extent<S,T>::MAX {
|
||||
std::numeric_limits<T>::max (),
|
||||
std::numeric_limits<T>::max ()
|
||||
};
|
||||
@ -192,43 +194,43 @@ const util::extent<T> util::extent<T>::MAX {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace debug {
|
||||
template <typename T>
|
||||
struct validator<util::extent,T> {
|
||||
static bool is_valid (const util::extent<T> &e)
|
||||
template <size_t S, typename T>
|
||||
struct validator<util::extent,S,T> {
|
||||
static bool is_valid (const util::extent<S,T> &e)
|
||||
{
|
||||
return e.w >= 0 && e.h >= 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template bool debug::valid (const util::extent<float>&);
|
||||
template bool debug::valid (const util::extent<double>&);
|
||||
template bool debug::valid (const util::extent<uint16_t>&);
|
||||
template bool debug::valid (const util::extent<uint32_t>&);
|
||||
template bool debug::valid (const util::extent<uint64_t>&);
|
||||
template bool debug::valid (const util::extent<2,float>&);
|
||||
template bool debug::valid (const util::extent<2,double>&);
|
||||
template bool debug::valid (const util::extent<2,uint16_t>&);
|
||||
template bool debug::valid (const util::extent<2,uint32_t>&);
|
||||
template bool debug::valid (const util::extent<2,uint64_t>&);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
std::ostream&
|
||||
util::operator<< (std::ostream &os, util::extent<T> e)
|
||||
util::operator<< (std::ostream &os, util::extent<S,T> e)
|
||||
{
|
||||
os << "[" << e.w << ", " << e.h << "]";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
template std::ostream& util::operator<< (std::ostream&, util::extent<uint16_t>);
|
||||
template std::ostream& util::operator<< (std::ostream&, util::extent<uint32_t>);
|
||||
template std::ostream& util::operator<< (std::ostream&, util::extent<uint64_t>);
|
||||
template std::ostream& util::operator<< (std::ostream&, util::extent<float>);
|
||||
template std::ostream& util::operator<< (std::ostream&, util::extent<double>);
|
||||
template std::ostream& util::operator<< (std::ostream&, util::extent<2,uint16_t>);
|
||||
template std::ostream& util::operator<< (std::ostream&, util::extent<2,uint32_t>);
|
||||
template std::ostream& util::operator<< (std::ostream&, util::extent<2,uint64_t>);
|
||||
template std::ostream& util::operator<< (std::ostream&, util::extent<2,float>);
|
||||
template std::ostream& util::operator<< (std::ostream&, util::extent<2,double>);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace util {
|
||||
template struct extent<uint32_t>;
|
||||
template struct extent<uint64_t>;
|
||||
template struct extent<float>;
|
||||
template struct extent<double>;
|
||||
template struct extent<2,uint32_t>;
|
||||
template struct extent<2,uint64_t>;
|
||||
template struct extent<2,float>;
|
||||
template struct extent<2,double>;
|
||||
}
|
||||
|
26
extent.hpp
26
extent.hpp
@ -29,22 +29,22 @@ namespace util {
|
||||
/**
|
||||
* A pure two-dimensional size, without positioning
|
||||
*/
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
struct extent {
|
||||
T w, h;
|
||||
|
||||
extent (const T _width, const T _height);
|
||||
extent (T);
|
||||
extent (vector<2,T>);
|
||||
extent (vector<S,T>);
|
||||
extent (const extent&);
|
||||
extent& operator= (const extent&);
|
||||
extent& operator= (extent);
|
||||
extent () = default;
|
||||
|
||||
T area (void) const;
|
||||
T diameter (void) const;
|
||||
|
||||
extent<T> expanded (util::vector<2,T>) const;
|
||||
extent<T> expanded (T) const;
|
||||
extent expanded (vector<S,T>) const;
|
||||
extent expanded (T) const;
|
||||
|
||||
float aspect (void) const;
|
||||
|
||||
@ -60,18 +60,18 @@ namespace util {
|
||||
{ return !(*this == rhs); }
|
||||
|
||||
template <typename U>
|
||||
extent<U> cast (void) const;
|
||||
extent<S,U> cast (void) const;
|
||||
|
||||
static const extent<T> MAX;
|
||||
static const extent<T> MIN;
|
||||
static const extent MAX;
|
||||
static const extent MIN;
|
||||
};
|
||||
|
||||
typedef extent<int> extent2i;
|
||||
typedef extent<size_t> extent2u;
|
||||
typedef extent<float> extent2f;
|
||||
typedef extent<2,int> extent2i;
|
||||
typedef extent<2,size_t> extent2u;
|
||||
typedef extent<2,float> extent2f;
|
||||
|
||||
template <typename T>
|
||||
std::ostream& operator<< (std::ostream&, util::extent<T>);
|
||||
template <size_t S, typename T>
|
||||
std::ostream& operator<< (std::ostream&, util::extent<S,T>);
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,10 +25,10 @@
|
||||
#define __UTIL_EXTENT_IPP
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
template <typename U>
|
||||
util::extent<U>
|
||||
util::extent<T>::cast (void) const
|
||||
util::extent<S,U>
|
||||
util::extent<S,T>::cast (void) const
|
||||
{
|
||||
return {
|
||||
static_cast<U> (w),
|
||||
|
210
region.cpp
210
region.cpp
@ -28,16 +28,16 @@
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::region<T>::region (util::extent<size_type> _extent):
|
||||
region (util::point<2,T>::ORIGIN, _extent)
|
||||
template <size_t S, typename T>
|
||||
util::region<S,T>::region (extent_t _extent):
|
||||
region (point_t::ORIGIN, _extent)
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::region<T>::region (point<2,T> _point,
|
||||
extent<size_type> _size):
|
||||
template <size_t S, typename T>
|
||||
util::region<S,T>::region (point_t _point,
|
||||
extent_t _size):
|
||||
x (_point.x),
|
||||
y (_point.y),
|
||||
w (_size.w),
|
||||
@ -46,9 +46,9 @@ util::region<T>::region (point<2,T> _point,
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::region<T>::region (point<2,T> _a,
|
||||
point<2,T> _b):
|
||||
template <size_t S, typename T>
|
||||
util::region<S,T>::region (point_t _a,
|
||||
point_t _b):
|
||||
region (_a, _b - _a)
|
||||
{
|
||||
CHECK_GE (_b.x, _a.x);
|
||||
@ -56,46 +56,46 @@ util::region<T>::region (point<2,T> _a,
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::region<T>::region (position_type _x,
|
||||
template <size_t S, typename T>
|
||||
util::region<S,T>::region (position_type _x,
|
||||
position_type _y,
|
||||
size_type _w,
|
||||
size_type _h):
|
||||
region (point<2,T> {_x, _y}, extent<T> {_w, _h})
|
||||
region (point_t {_x, _y}, extent<S,T> {_w, _h})
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
typename util::region<T>::size_type
|
||||
util::region<T>::area (void) const
|
||||
template <size_t S, typename T>
|
||||
typename util::region<S,T>::size_type
|
||||
util::region<S,T>::area (void) const
|
||||
{
|
||||
return w * h;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
typename util::region<T>::size_type
|
||||
util::region<T>::diameter (void) const
|
||||
template <size_t S, typename T>
|
||||
typename util::region<S,T>::size_type
|
||||
util::region<S,T>::diameter (void) const
|
||||
{
|
||||
return static_cast<size_type> (std::sqrt (w * w + h * h));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
typename util::region<T>::extent_t
|
||||
util::region<T>::magnitude (void) const
|
||||
template <size_t S, typename T>
|
||||
typename util::region<S,T>::extent_t
|
||||
util::region<S,T>::magnitude (void) const
|
||||
{
|
||||
return { w, h };
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
typename util::region<T>::extent_t
|
||||
util::region<T>::magnitude (extent_t e)
|
||||
template <size_t S, typename T>
|
||||
typename util::region<S,T>::extent_t
|
||||
util::region<S,T>::magnitude (extent_t e)
|
||||
{
|
||||
w = e.w;
|
||||
h = e.h;
|
||||
@ -105,9 +105,9 @@ util::region<T>::magnitude (extent_t e)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
void
|
||||
util::region<T>::scale (T factor)
|
||||
util::region<S,T>::scale (T factor)
|
||||
{
|
||||
x -= (w * factor - w) / T{2};
|
||||
y -= (h * factor - h) / T{2};
|
||||
@ -118,18 +118,18 @@ util::region<T>::scale (T factor)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
bool
|
||||
util::region<T>::empty (void) const
|
||||
util::region<S,T>::empty (void) const
|
||||
{
|
||||
return almost_zero (area ());
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::point<2,T>
|
||||
util::region<T>::rebase (util::point<2,T> p)
|
||||
template <size_t S, typename T>
|
||||
typename util::region<S,T>::point_t
|
||||
util::region<S,T>::rebase (point_t p)
|
||||
{
|
||||
x = p.x;
|
||||
y = p.y;
|
||||
@ -139,39 +139,39 @@ util::region<T>::rebase (util::point<2,T> p)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::point<2,T>
|
||||
util::region<T>::base (void) const
|
||||
template <size_t S, typename T>
|
||||
typename util::region<S,T>::point_t
|
||||
util::region<S,T>::base (void) const
|
||||
{
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::point<2,T>
|
||||
util::region<T>::away (void) const
|
||||
template <size_t S, typename T>
|
||||
typename util::region<S,T>::point_t
|
||||
util::region<S,T>::away (void) const
|
||||
{
|
||||
return { x + w, y + h };
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::point<2,T>
|
||||
util::region<T>::centre (void) const
|
||||
template <size_t S, typename T>
|
||||
typename util::region<S,T>::point_t
|
||||
util::region<S,T>::centre (void) const
|
||||
{
|
||||
T cx = x + w / T{2},
|
||||
cy = y + h / T{2};
|
||||
|
||||
return point<2,T> { cx, cy };
|
||||
return point_t { cx, cy };
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::point<2,T>
|
||||
util::region<T>::closest (point<2,T> p) const
|
||||
template <size_t S, typename T>
|
||||
typename util::region<S,T>::point_t
|
||||
util::region<S,T>::closest (point_t p) const
|
||||
{
|
||||
return {
|
||||
p.x < x ? x :
|
||||
@ -186,9 +186,9 @@ util::region<T>::closest (point<2,T> p) const
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
bool
|
||||
util::region<T>::includes (const point<2,T> &p) const
|
||||
util::region<S,T>::includes (point_t p) const
|
||||
{
|
||||
return p.x >= x &&
|
||||
p.y >= y &&
|
||||
@ -198,9 +198,9 @@ util::region<T>::includes (const point<2,T> &p) const
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
bool
|
||||
util::region<T>::contains (const point<2,T> &p) const
|
||||
util::region<S,T>::contains (point_t p) const
|
||||
{
|
||||
return p.x > x &&
|
||||
p.y > y &&
|
||||
@ -212,9 +212,9 @@ util::region<T>::contains (const point<2,T> &p) const
|
||||
//-----------------------------------------------------------------------------
|
||||
// FIXME: This will fail with an actual infinite range (NaNs will be generated
|
||||
// in the conditionals).
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
bool
|
||||
util::region<T>::intersects (const util::region<T> &rhs) const
|
||||
util::region<S,T>::intersects (region<S,T> rhs) const
|
||||
{
|
||||
return x < rhs.x + rhs.w &&
|
||||
rhs.x < x + w &&
|
||||
@ -224,9 +224,9 @@ util::region<T>::intersects (const util::region<T> &rhs) const
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
void
|
||||
util::region<T>::constrain (point<2,T> &p) const
|
||||
util::region<S,T>::constrain (point_t &p) const
|
||||
{
|
||||
p.x = std::min (std::max (p.x, x), x + w);
|
||||
p.y = std::min (std::max (p.y, y), y + h);
|
||||
@ -234,11 +234,11 @@ util::region<T>::constrain (point<2,T> &p) const
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::point<2,T>
|
||||
util::region<T>::constrained (const point<2,T> &p) const
|
||||
template <size_t S, typename T>
|
||||
typename util::region<S,T>::point_t
|
||||
util::region<S,T>::constrained (point_t p) const
|
||||
{
|
||||
point<2,T> v;
|
||||
point_t v;
|
||||
v.x = std::min (std::max (p.x, x), x + w);
|
||||
v.y = std::min (std::max (p.y, y), y + h);
|
||||
|
||||
@ -247,9 +247,9 @@ util::region<T>::constrained (const point<2,T> &p) const
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
util::region<T>
|
||||
util::region<T>::intersection (const util::region<T> &rhs) const
|
||||
template<size_t S, typename T>
|
||||
util::region<S,T>
|
||||
util::region<S,T>::intersection (region<S,T> rhs) const
|
||||
{
|
||||
T newx1 = max (x, rhs.x),
|
||||
newy1 = max (y, rhs.y),
|
||||
@ -261,14 +261,14 @@ util::region<T>::intersection (const util::region<T> &rhs) const
|
||||
|
||||
size_type nw = sign_cast<size_type> (newx2 - newx1);
|
||||
size_type nh = sign_cast<size_type> (newy2 - newy1);
|
||||
return util::region<T> (newx1, newy1, nw, nh);
|
||||
return util::region<S,T> (newx1, newy1, nw, nh);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::region<T>
|
||||
util::region<T>::inset (T mag)
|
||||
template <size_t S, typename T>
|
||||
util::region<S,T>
|
||||
util::region<S,T>::inset (T mag)
|
||||
{
|
||||
CHECK_GE (w, 2 * mag);
|
||||
CHECK_GE (h, 2 * mag);
|
||||
@ -278,9 +278,9 @@ util::region<T>::inset (T mag)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::region<T>&
|
||||
util::region<T>::expand (T _w, T _h)
|
||||
template <size_t S, typename T>
|
||||
util::region<S,T>&
|
||||
util::region<S,T>::expand (T _w, T _h)
|
||||
{
|
||||
x -= _w;
|
||||
y -= _h;
|
||||
@ -292,18 +292,18 @@ util::region<T>::expand (T _w, T _h)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::region<T>&
|
||||
util::region<T>::expand (T mag)
|
||||
template <size_t S, typename T>
|
||||
util::region<S,T>&
|
||||
util::region<S,T>::expand (T mag)
|
||||
{
|
||||
return expand (mag, mag);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::region<T>
|
||||
util::region<T>::expanded (T _w, T _h) const
|
||||
template <size_t S, typename T>
|
||||
util::region<S,T>
|
||||
util::region<S,T>::expanded (T _w, T _h) const
|
||||
{
|
||||
return {
|
||||
x - _w,
|
||||
@ -315,36 +315,36 @@ util::region<T>::expanded (T _w, T _h) const
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::region<T>
|
||||
util::region<T>::expanded (T mag) const
|
||||
template <size_t S, typename T>
|
||||
util::region<S,T>
|
||||
util::region<S,T>::expanded (T mag) const
|
||||
{
|
||||
return expanded (mag, mag);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
util::region<T>
|
||||
util::region<T>::operator+ (vector<2,T> rhs) const
|
||||
template <size_t S, typename T>
|
||||
util::region<S,T>
|
||||
util::region<S,T>::operator+ (vector<S,T> rhs) const
|
||||
{
|
||||
return { x + rhs.x, y + rhs.y, w, h };
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
util::region<T>
|
||||
util::region<T>::operator- (vector<2,T> rhs) const
|
||||
template <size_t S, typename T>
|
||||
util::region<S,T>
|
||||
util::region<S,T>::operator- (vector<S,T> rhs) const
|
||||
{
|
||||
return { x - rhs.x, y - rhs.y, w, h };
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
bool
|
||||
util::region<T>::operator== (const region& rhs) const
|
||||
util::region<S,T>::operator== (region rhs) const
|
||||
{
|
||||
return almost_equal (x, rhs.x) &&
|
||||
almost_equal (y, rhs.y) &&
|
||||
@ -354,9 +354,9 @@ util::region<T>::operator== (const region& rhs) const
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
void
|
||||
util::region<T>::sanity (void) const {
|
||||
util::region<S,T>::sanity (void) const {
|
||||
CHECK_GE (w, 0);
|
||||
CHECK_GE (h, 0);
|
||||
static_assert(!std::is_floating_point<T>::value,
|
||||
@ -367,14 +367,14 @@ util::region<T>::sanity (void) const {
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace util {
|
||||
template <>
|
||||
void region<double>::sanity (void) const {
|
||||
void region<2,double>::sanity (void) const {
|
||||
CHECK_GE (w, 0);
|
||||
CHECK_GE (h, 0);
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
void region<float>::sanity (void) const {
|
||||
void region<2,float>::sanity (void) const {
|
||||
CHECK_GE (w, 0);
|
||||
CHECK_GE (h, 0);
|
||||
}
|
||||
@ -389,9 +389,9 @@ namespace util {
|
||||
///
|
||||
/// Specifically does not allow infinities. Use/define INFINITE when required.
|
||||
|
||||
template <typename T>
|
||||
const util::region<T>
|
||||
util::region<T>::MAX (
|
||||
template <size_t S, typename T>
|
||||
const util::region<S,T>
|
||||
util::region<S,T>::MAX (
|
||||
std::numeric_limits<T>::lowest () / 2,
|
||||
std::numeric_limits<T>::lowest () / 2,
|
||||
std::numeric_limits<T>::max (),
|
||||
@ -399,15 +399,15 @@ util::region<T>::MAX (
|
||||
);
|
||||
|
||||
|
||||
template <typename T>
|
||||
const util::region<T>
|
||||
util::region<T>::UNIT (0, 0, 1, 1);
|
||||
template <size_t S, typename T>
|
||||
const util::region<S,T>
|
||||
util::region<S,T>::UNIT (0, 0, 1, 1);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
std::ostream&
|
||||
util::operator<< (std::ostream &os, const util::region<T> &rhs) {
|
||||
util::operator<< (std::ostream &os, const util::region<S,T> &rhs) {
|
||||
os << "region(" << rhs.x << ", " << rhs.y << ", " << rhs.w << ", " << rhs.h << ")";
|
||||
return os;
|
||||
}
|
||||
@ -415,15 +415,15 @@ util::operator<< (std::ostream &os, const util::region<T> &rhs) {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace util {
|
||||
template struct region<uint32_t>;
|
||||
template struct region<uint64_t>;
|
||||
template struct region<float>;
|
||||
template struct region<double>;
|
||||
template struct region<2,uint32_t>;
|
||||
template struct region<2,uint64_t>;
|
||||
template struct region<2,float>;
|
||||
template struct region<2,double>;
|
||||
|
||||
template std::ostream& operator<< (std::ostream&, const region< int32_t>&);
|
||||
template std::ostream& operator<< (std::ostream&, const region< int64_t>&);
|
||||
template std::ostream& operator<< (std::ostream&, const region<uint32_t>&);
|
||||
template std::ostream& operator<< (std::ostream&, const region<uint64_t>&);
|
||||
template std::ostream& operator<< (std::ostream&, const region< float>&);
|
||||
template std::ostream& operator<< (std::ostream&, const region< double>&);
|
||||
template std::ostream& operator<< (std::ostream&, const region<2, int32_t>&);
|
||||
template std::ostream& operator<< (std::ostream&, const region<2, int64_t>&);
|
||||
template std::ostream& operator<< (std::ostream&, const region<2,uint32_t>&);
|
||||
template std::ostream& operator<< (std::ostream&, const region<2,uint64_t>&);
|
||||
template std::ostream& operator<< (std::ostream&, const region<2, float>&);
|
||||
template std::ostream& operator<< (std::ostream&, const region<2, double>&);
|
||||
}
|
||||
|
59
region.hpp
59
region.hpp
@ -30,25 +30,25 @@ namespace util {
|
||||
/**
|
||||
* A two-dimensional rectangle, with size and position.
|
||||
*/
|
||||
template <typename T>
|
||||
template <size_t S, typename T>
|
||||
struct region {
|
||||
using position_type = T;
|
||||
using size_type = typename try_unsigned<T>::type;
|
||||
|
||||
static constexpr size_t dimension = 2u;
|
||||
static constexpr size_t dimension = S;
|
||||
static constexpr size_t elements = dimension * 2;
|
||||
using value_type = T;
|
||||
|
||||
using extent_t = util::extent<size_type>;
|
||||
using point_t = util::point<2,T>;
|
||||
using extent_t = util::extent<S,size_type>;
|
||||
using point_t = util::point<S,position_type>;
|
||||
|
||||
position_type x, y;
|
||||
size_type w, h;
|
||||
|
||||
region () = default;
|
||||
region (util::extent<size_type>);
|
||||
region (util::point<2,T>, util::extent<size_type>);
|
||||
region (util::point<2,T>, util::point<2,T>);
|
||||
region (extent_t);
|
||||
region (point_t, extent_t);
|
||||
region (point_t, point_t);
|
||||
region (T _x, T _y, size_type _w, size_type _h);
|
||||
|
||||
size_type area (void) const;
|
||||
@ -60,24 +60,24 @@ namespace util {
|
||||
|
||||
bool empty (void) const;
|
||||
|
||||
point<2,T> rebase (util::point<2,T>);
|
||||
point_t rebase (point_t);
|
||||
|
||||
point<2,T> base (void) const;
|
||||
point<2,T> away (void) const;
|
||||
point<2,T> centre (void) const;
|
||||
point<2,T> closest (point<2,T>) const;
|
||||
point_t base (void) const;
|
||||
point_t away (void) const;
|
||||
point_t centre (void) const;
|
||||
point_t closest (point_t) const;
|
||||
|
||||
// Point and region relation queries
|
||||
bool includes (const point<2,T>&) const; // inclusive of borders
|
||||
bool contains (const point<2,T>&) const; // exclusive of borders
|
||||
bool intersects (const region<T>&) const; // exclusive of borders
|
||||
bool includes (point_t) const; // inclusive of borders
|
||||
bool contains (point_t) const; // exclusive of borders
|
||||
bool intersects (region<S,T>) const; // exclusive of borders
|
||||
|
||||
// Move a point to be within the region bounds
|
||||
void constrain (point<2,T>&) const;
|
||||
point<2,T> constrained (const point<2,T>&) const;
|
||||
void constrain (point_t&) const;
|
||||
point_t constrained (point_t) const;
|
||||
|
||||
// Compute binary region combinations
|
||||
region intersection (const region<T>&) const;
|
||||
region intersection (region<S,T>) const;
|
||||
|
||||
// Compute a region `mag` units into the region
|
||||
region inset (T mag);
|
||||
@ -89,27 +89,28 @@ namespace util {
|
||||
region& expand (T w, T h);
|
||||
|
||||
// arithmetic operators
|
||||
region operator+ (vector<2,T>) const;
|
||||
region operator- (vector<2,T>) const;
|
||||
region operator+ (vector<S,T>) const;
|
||||
region operator- (vector<S,T>) const;
|
||||
|
||||
// Logical comparison operators
|
||||
bool operator ==(const region<T>& rhs) const;
|
||||
bool operator !=(const region<T>& rhs) const
|
||||
bool operator ==(region<S,T> rhs) const;
|
||||
bool operator !=(region<S,T> rhs) const
|
||||
{ return !(*this == rhs); }
|
||||
|
||||
// Utility constants
|
||||
static const region<T> MAX;
|
||||
static const region<T> UNIT;
|
||||
static const region<S,T> MAX;
|
||||
static const region<S,T> UNIT;
|
||||
|
||||
void sanity (void) const;
|
||||
};
|
||||
|
||||
typedef region<size_t> region2u;
|
||||
typedef region<intmax_t> region2i;
|
||||
typedef region<float> region2f;
|
||||
typedef region<2,size_t> region2u;
|
||||
typedef region<2,intmax_t> region2i;
|
||||
typedef region<2,float> region2f;
|
||||
typedef region<2,double> region2d;
|
||||
|
||||
template <typename T>
|
||||
std::ostream& operator<< (std::ostream&, const util::region<T>&);
|
||||
template <size_t S, typename T>
|
||||
std::ostream& operator<< (std::ostream&, const util::region<S,T>&);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,5 +4,6 @@
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
debug::sanity (util::extent<float> {0, 0});
|
||||
// Simple symbol visibility check
|
||||
util::extent2f instance;
|
||||
}
|
||||
|
@ -2,35 +2,33 @@
|
||||
#include "../point.hpp"
|
||||
#include "../debug.hpp"
|
||||
|
||||
using util::region;
|
||||
using util::point;
|
||||
using util::point2d;
|
||||
using namespace util;
|
||||
|
||||
int
|
||||
main (int, char **) {
|
||||
{
|
||||
region<double> a (32.7, -6.09703, 0.8, 2);
|
||||
region<double> b (33.5, -4.5, 0.5, 0.5);
|
||||
region2d a {32.7, -6.09703, 0.8, 2};
|
||||
region2d b {33.5, -4.5, 0.5, 0.5};
|
||||
|
||||
CHECK (!a.intersects (b));
|
||||
}
|
||||
|
||||
CHECK (region<double>::MAX.intersects (region<double>::UNIT));
|
||||
CHECK (region< float>::MAX.intersects (region< float>::UNIT));
|
||||
CHECK (region2d::MAX.intersects (region2d::UNIT));
|
||||
CHECK (region2f::MAX.intersects (region2f::UNIT));
|
||||
|
||||
CHECK_EQ (region<double>::UNIT.area (), 1.0);
|
||||
CHECK_EQ (region< float>::UNIT.area (), 1.0f);
|
||||
CHECK_EQ (region2d::UNIT.area (), 1.0);
|
||||
CHECK_EQ (region2f::UNIT.area (), 1.0f);
|
||||
|
||||
CHECK (region<unsigned> (0, 0, 2, 2).includes (point<2,unsigned>(1, 1)));
|
||||
CHECK (region<unsigned> (0, 0, 2, 2).includes (point<2,unsigned>(0, 0)));
|
||||
CHECK (region<unsigned> (0, 0, 2, 2).includes (point<2,unsigned>(2, 2)));
|
||||
CHECK (region2u (0, 0, 2, 2).includes (point2u {1, 1}));
|
||||
CHECK (region2u (0, 0, 2, 2).includes (point2u {0, 0}));
|
||||
CHECK (region2u (0, 0, 2, 2).includes (point2u {2, 2}));
|
||||
|
||||
CHECK ( region<unsigned> (0, 0, 2, 2).contains (point<2,unsigned>(1, 1)));
|
||||
CHECK (!region<unsigned> (0, 0, 2, 2).contains (point<2,unsigned>(0, 0)));
|
||||
CHECK (!region<unsigned> (0, 0, 2, 2).contains (point<2,unsigned>(2, 2)));
|
||||
CHECK ( region2u (0, 0, 2, 2).contains (point2u {1, 1}));
|
||||
CHECK (!region2u (0, 0, 2, 2).contains (point2u {0, 0}));
|
||||
CHECK (!region2u (0, 0, 2, 2).contains (point2u {2, 2}));
|
||||
|
||||
//CHECK (region<intmax_t> (0, 0, 10, 10).includes (point2d (0.4, 0.01)));
|
||||
//CHECK (region<intmax_t> (0, 0, 10, 10).contains (point2d (0.4, 0.01)));
|
||||
//CHECK (region<2,intmax_t> (0, 0, 10, 10).includes (point2d (0.4, 0.01)));
|
||||
//CHECK (region<2,intmax_t> (0, 0, 10, 10).contains (point2d (0.4, 0.01)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user