Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
404 lines (299 sloc) 9.49 KB
////////////////////////////////////////////////////////////////////////////////
// -------------------------------------------------------------------------- //
// //
// (C) 2010-2016 Robot Developers //
// See LICENSE for licensing info //
// //
// -------------------------------------------------------------------------- //
////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------//
// Prefaces //
//----------------------------------------------------------------------------//
#include "Bounds.h"
#include "Size.h"
#include "Point.h"
#include <algorithm>
using std::min;
using std::max;
ROBOT_NS_BEGIN
//----------------------------------------------------------------------------//
// Macros //
//----------------------------------------------------------------------------//
////////////////////////////////////////////////////////////////////////////////
#define NORM( l, r, t, b, x, y, w, h ) \
int32 l = x, r = x, t = y, b = y; \
if (w < 0) l += w; else r += w; \
if (h < 0) t += h; else b += h;
//----------------------------------------------------------------------------//
// Constructors Bounds //
//----------------------------------------------------------------------------//
////////////////////////////////////////////////////////////////////////////////
Bounds::Bounds (int32 value)
{
X = value;
Y = value;
W = value;
H = value;
}
////////////////////////////////////////////////////////////////////////////////
Bounds::Bounds (int32 x, int32 y, int32 w, int32 h)
{
X = x;
Y = y;
W = w;
H = h;
}
////////////////////////////////////////////////////////////////////////////////
Bounds::Bounds (const Point& p, const Size& s)
{
X = p.X;
Y = p.Y;
W = s.W;
H = s.H;
}
//----------------------------------------------------------------------------//
// Functions Bounds //
//----------------------------------------------------------------------------//
////////////////////////////////////////////////////////////////////////////////
bool Bounds::IsZero (void) const
{
return X == 0 && Y == 0 &&
W == 0 && H == 0;
}
////////////////////////////////////////////////////////////////////////////////
bool Bounds::IsEmpty (void) const
{
return W == 0 || H == 0;
}
////////////////////////////////////////////////////////////////////////////////
bool Bounds::IsValid (void) const
{
return W > 0 && H > 0;
}
////////////////////////////////////////////////////////////////////////////////
int32 Bounds::GetLeft (void) const
{
return X;
}
////////////////////////////////////////////////////////////////////////////////
int32 Bounds::GetTop (void) const
{
return Y;
}
////////////////////////////////////////////////////////////////////////////////
int32 Bounds::GetRight (void) const
{
return X + W;
}
////////////////////////////////////////////////////////////////////////////////
int32 Bounds::GetBottom (void) const
{
return Y + H;
}
////////////////////////////////////////////////////////////////////////////////
void Bounds::SetLeft (int32 l)
{
X = l;
}
////////////////////////////////////////////////////////////////////////////////
void Bounds::SetTop (int32 t)
{
Y = t;
}
////////////////////////////////////////////////////////////////////////////////
void Bounds::SetRight (int32 r)
{
W = r - X;
}
////////////////////////////////////////////////////////////////////////////////
void Bounds::SetBottom (int32 b)
{
H = b - Y;
}
////////////////////////////////////////////////////////////////////////////////
void Bounds::GetLTRB (int32& l,
int32& t, int32& r, int32& b)
{
l = X;
t = Y;
r = X + W;
b = Y + H;
}
////////////////////////////////////////////////////////////////////////////////
void Bounds::SetLTRB (int32 l,
int32 t, int32 r, int32 b)
{
X = l;
Y = t;
W = r - l;
H = b - t;
}
////////////////////////////////////////////////////////////////////////////////
void Bounds::Normalize (void)
{
if (W < 0) { X += W; W = -W; }
if (H < 0) { Y += H; H = -H; }
}
////////////////////////////////////////////////////////////////////////////////
bool Bounds::Contains (const Point& p, bool inclusive) const
{
return Contains (p.X, p.Y, inclusive);
}
////////////////////////////////////////////////////////////////////////////////
bool Bounds::Contains (int32 x, int32 y, bool inclusive) const
{
// Normalize negative rectangle
NORM (l, r, t, b, X, Y, W, H);
return inclusive ?
l <= x && x <= r && t <= y && y <= b :
l < x && x < r && t < y && y < b;
}
////////////////////////////////////////////////////////////////////////////////
bool Bounds::Contains (const Bounds& b, bool inclusive) const
{
return Contains (b.X, b.Y, b.W, b.H, inclusive);
}
////////////////////////////////////////////////////////////////////////////////
bool Bounds::Contains (int32 x, int32 y,
int32 w, int32 h, bool inclusive) const
{
if ((W == 0 && H == 0) || (w == 0 && h == 0))
return false;
// Normalize negative rectangles
NORM (l1, r1, t1, b1, X, Y, W, H);
NORM (l2, r2, t2, b2, x, y, w, h);
return inclusive ?
l1 <= l2 && r1 >= r2 && t1 <= t2 && b1 >= b2 :
l1 < l2 && r1 > r2 && t1 < t2 && b1 > b2;
}
////////////////////////////////////////////////////////////////////////////////
bool Bounds::Intersects (const Bounds& b, bool inclusive) const
{
return Intersects (b.X, b.Y, b.W, b.H, inclusive);
}
////////////////////////////////////////////////////////////////////////////////
bool Bounds::Intersects (int32 x, int32 y,
int32 w, int32 h, bool inclusive) const
{
if ((W == 0 && H == 0) || (w == 0 && h == 0))
return false;
// Normalize negative rectangles
NORM (l1, r1, t1, b1, X, Y, W, H);
NORM (l2, r2, t2, b2, x, y, w, h);
return inclusive ?
l1 <= r2 && r1 >= l2 && t1 <= b2 && b1 >= t2 :
l1 < r2 && r1 > l2 && t1 < b2 && b1 > t2;
}
////////////////////////////////////////////////////////////////////////////////
Point Bounds::GetPoint (void) const
{
return Point (X, Y);
}
////////////////////////////////////////////////////////////////////////////////
void Bounds::SetPoint (const Point& p)
{
X = p.X;
Y = p.Y;
}
////////////////////////////////////////////////////////////////////////////////
void Bounds::SetPoint (int32 x, int32 y)
{
X = x;
Y = y;
}
////////////////////////////////////////////////////////////////////////////////
Size Bounds::GetSize (void) const
{
return Size (W, H);
}
////////////////////////////////////////////////////////////////////////////////
void Bounds::SetSize (const Size& s)
{
W = s.W;
H = s.H;
}
////////////////////////////////////////////////////////////////////////////////
void Bounds::SetSize (int32 w, int32 h)
{
W = w;
H = h;
}
////////////////////////////////////////////////////////////////////////////////
Point Bounds::GetCenter (void) const
{
return Point
(X + (int32) (W * 0.5f),
Y + (int32) (H * 0.5f));
}
//----------------------------------------------------------------------------//
// Operators Bounds //
//----------------------------------------------------------------------------//
////////////////////////////////////////////////////////////////////////////////
Bounds& Bounds::operator |= (const Bounds& bounds)
{
return *this = *this | bounds;
}
////////////////////////////////////////////////////////////////////////////////
Bounds& Bounds::operator &= (const Bounds& bounds)
{
return *this = *this & bounds;
}
////////////////////////////////////////////////////////////////////////////////
Bounds Bounds::operator | (const Bounds& bounds) const
{
int32 x = bounds.X;
int32 y = bounds.Y;
int32 w = bounds.W;
int32 h = bounds.H;
Bounds result;
// Normalize negative rectangles
NORM (l1, r1, t1, b1, X, Y, W, H);
NORM (l2, r2, t2, b2, x, y, w, h);
if (W == 0 && H == 0)
{
result.SetLTRB (l2, t2, r2, b2);
return result;
}
if (w == 0 && h == 0)
{
result.SetLTRB (l1, t1, r1, b1);
return result;
}
result.SetLTRB
(min (l1, l2), min (t1, t2),
max (r1, r2), max (b1, b2));
return result;
}
////////////////////////////////////////////////////////////////////////////////
Bounds Bounds::operator & (const Bounds& bounds) const
{
int32 x = bounds.X;
int32 y = bounds.Y;
int32 w = bounds.W;
int32 h = bounds.H;
if ((W == 0 && H == 0) || (w == 0 && h == 0))
return Bounds();
// Normalize negative rectangles
NORM (l1, r1, t1, b1, X, Y, W, H);
NORM (l2, r2, t2, b2, x, y, w, h);
// Check for bounds intersection
if (l1 > r2 || r1 < l2 || t1 > b2 || b1 < t2)
return Bounds();
Bounds result;
result.SetLTRB (max (l1, l2), max (t1, t2),
min (r1, r2), min (b1, b2));
return result;
}
////////////////////////////////////////////////////////////////////////////////
bool Bounds::operator == (const Bounds& bounds) const
{
return X == bounds.X && Y == bounds.Y &&
W == bounds.W && H == bounds.H;
}
////////////////////////////////////////////////////////////////////////////////
bool Bounds::operator != (const Bounds& bounds) const
{
return X != bounds.X || Y != bounds.Y ||
W != bounds.W || H != bounds.H;
}
ROBOT_NS_END