deargui-vpl/ref/virtools/Includes/VxRect.h

666 lines
18 KiB
C++

/*************************************************************************/
/* File : VxRect.h */
/* Author : Aymeric Bard */
/* */
/* Virtools SDK */
/* Copyright (c) Virtools 2000, All Rights Reserved. */
/*************************************************************************/
#ifndef VXRECT_H
#define VXRECT_H
typedef enum VXRECT_INTERSECTION {
ALLOUTSIDE = 0,
ALLINSIDE = 1,
PARTINSIDE = 2
} VXRECT_INTERSECTION;
/**********************************************************
{filename:VxRect}
Name: VxRect
Remarks:
A Rect is defined by 4 floats and is used to represents
a 2D region.
A VxRect is defined as:
class VxRect
{
public:
float left;
float top;
float right;
float bottom;
};
Elements can be accessed directly or by using the accessors functions
for more sophisticate access.
See Also :
*********************************************************/
class VxRect
{
public:
#if defined(_LINUX) || defined(PSX2) || defined(PSP) || defined(__GNUC__)
float left;
float top;
float right;
float bottom;
#else
// Members
union {
struct {
float left;
float top;
float right;
float bottom;
};
struct {
Vx2DVector m_TopLeft;
Vx2DVector m_BottomRight;
};
};
#endif
// Methods
VxRect(): left(0.0f),top(0.0f),right(0.0f),bottom(0.0f) {}
#if defined(_LINUX) || defined(PSX2) || defined(PSP) || defined(__GNUC__)
VxRect(Vx2DVector& topleft,Vx2DVector& bottomright):left(topleft.x),top(topleft.y),right(bottomright.x),bottom(bottomright.y) {}
VxRect(float l,float t,float r,float b):left(l),top(t),right(r),bottom(b) {}
#else
VxRect(Vx2DVector& topleft,Vx2DVector& bottomright):m_TopLeft(topleft),m_BottomRight(bottomright) {}
VxRect(float l,float t,float r,float b):m_TopLeft(l,t),m_BottomRight(r,b) {}
#endif
/************************************************
Summary: Changes the width of a rectangle.
Input Arguments:
w: new width in float.
************************************************/
void SetWidth(float w) {right = left+w;};
/************************************************
Summary: Returns the width of a rectangle.
************************************************/
float GetWidth() const {return right-left;}
/************************************************
Summary: Changes the height of a rectangle.
Input Arguments:
h: new height in float.
************************************************/
void SetHeight(float h) {bottom = top+h;}
/************************************************
Summary: Returns the height of a rectangle.
************************************************/
float GetHeight() const {return bottom-top;}
/************************************************
Summary: Returns the horizontal center of the rect.
************************************************/
float GetHCenter() const {return left+0.5f*GetWidth();}
/************************************************
Summary: Returns the vertical center of the rect.
************************************************/
float GetVCenter() const {return top+0.5f*GetHeight();}
/************************************************
Summary: Changes the size of a rectangle.
Input Arguments:
v: new size in the form of a Vx2DVector.
************************************************/
void SetSize(const Vx2DVector& v) {SetWidth(v.x);SetHeight(v.y);}
/************************************************
Summary: Returns the size of a rectangle.
************************************************/
Vx2DVector GetSize() const {return Vx2DVector(GetWidth(),GetHeight());}
void SetHalfSize(const Vx2DVector& v) {Vx2DVector c = GetCenter();SetCenter(c,v);}
Vx2DVector GetHalfSize() const {return Vx2DVector(0.5f*GetWidth(),0.5f*GetHeight());}
void SetCenter(const Vx2DVector& v) {Vx2DVector hs = GetHalfSize();SetCenter(v,hs);}
Vx2DVector GetCenter() const {return Vx2DVector(GetHCenter(),GetVCenter());}
void SetTopLeft(const Vx2DVector& v) {left = v.x;top = v.y;}
#if !defined(_LINUX) && !defined(PSX2) && !defined(PSP) && !defined(__GNUC__)
const Vx2DVector& GetTopLeft() const {return m_TopLeft;}
Vx2DVector& GetTopLeft() {return m_TopLeft;}
#else
const Vx2DVector& GetTopLeft() const {
return (const Vx2DVector&) *(Vx2DVector*) &left;
}
Vx2DVector& GetTopLeft() {
return (Vx2DVector&) *(Vx2DVector*) &left;
}
#endif
void SetBottomRight(const Vx2DVector& v) {right = v.x;bottom = v.y;}
#if !defined(_LINUX) && !defined(PSX2) && !defined(PSP) && !defined(__GNUC__)
const Vx2DVector& GetBottomRight() const {return m_BottomRight;}
Vx2DVector& GetBottomRight() {return m_BottomRight;}
#else
const Vx2DVector& GetBottomRight() const {
return (const Vx2DVector&) *(Vx2DVector*) &right;
}
Vx2DVector& GetBottomRight() {
return (Vx2DVector&) *(Vx2DVector*) &right;
}
#endif
/************************************************
Summary: Sets the rectangle as a NULL rectangle
(position (0,0) ; size (0,0).
************************************************/
void Clear() {SetCorners(0,0,0,0);}
/*************************************************
Summary: Creates a rectangle based on two corners.
Input Arguments:
topleft: a Vx2DVector containing the top left corner.
bottomright: a Vx2DVector containing the bottom right corner.
t: top in float.
l: left in float.
b: bottom in float.
r: right in float.
See also: VxRect::SetDimension,VxRect::SetCenter
*************************************************/
void SetCorners(const Vx2DVector& topleft,const Vx2DVector& bottomright){left = topleft.x;top = topleft.y;right = bottomright.x;bottom = bottomright.y;}
void SetCorners(float l,float t,float r,float b) {left = l;top = t;right = r;bottom = b;}
/*************************************************
Summary: Creates a rectangle based on the top left coner and the size.
Input Arguments:
position: a Vx2DVector containing the top left corner.
size: a Vx2DVector containing the size.
x: left position in float.
y: top position in float.
w: width in float.
y: height in float.
See also: VxRect::SetCorners,VxRect::SetCenter
*************************************************/
void SetDimension(const Vx2DVector& position,const Vx2DVector& size){left = position.x;top = position.y;right = left + size.x;bottom = top + size.y;}
void SetDimension(float x,float y,float w,float h){left = x;top = y;right = x+w;bottom = y+h;}
/*************************************************
Summary: Creates a rectangle based on the center position and the half size.
Input Arguments:
position: a Vx2DVector containing the center position.
halfsize: a Vx2DVector containing half size.
cx: horizontal center position in float.
cy: vertical center position in float.
hw: half width in float.
hy: half height in float.
See also: VxRect::SetCorners,VxRect::SetDimension
*************************************************/
void SetCenter(const Vx2DVector& center,const Vx2DVector& halfsize){left = center.x - halfsize.x;top = center.y - halfsize.y;right = center.x + halfsize.x;bottom = center.y + halfsize.y;}
void SetCenter(float cx,float cy,float hw,float hh){left = cx-hw;top = cy-hh;right = cx+hw;bottom = cy+hh;}
/*************************************************
Summary: Assign the VxRect to a CKRECT.
Input Arguments:
iRect: the rectangle to copy from.
*************************************************/
void CopyFrom(const CKRECT& iRect) {
left = (float)iRect.left;
top = (float)iRect.top;
right = (float)iRect.right;
bottom = (float)iRect.bottom;
}
/*************************************************
Summary: Assign the VxRect to a CKRECT.
Input Arguments:
oRect: the rectangle to copy to.
*************************************************/
void CopyTo(CKRECT* oRect) const {
XASSERT(oRect);
oRect->left = (int)left;
oRect->top = (int)top;
oRect->right = (int)right;
oRect->bottom = (int)bottom;
}
/*************************************************
Summary: Creates a rectangle bounding two given points.
Input Arguments:
p1: the first Vx2DVector.
p2: the second Vx2DVector.
See also: VxRect::SetCorners,VxRect::SetDimension
*************************************************/
void Bounding(const Vx2DVector& p1,const Vx2DVector& p2)
{
if(p1.x < p2.x) {
left = p1.x;
right = p2.x;
} else {
left = p2.x;
right = p1.x;
}
if(p1.y < p2.y) {
top = p1.y;
bottom = p2.y;
} else {
top = p2.y;
bottom = p1.y;
}
}
/*************************************************
Summary: Checks that the rectangle is valid. If not, turns it right.
Remarks:
Use this function when you create a rectangle with two
corners without being sure that you provided the top left
and top right corners, if this order.
See also: VxRect::SetCorners,VxRect::SetDimension
*************************************************/
void Normalize()
{
// Check horizontally
if (left > right) XSwap(right,left);
// Check vertically
if (top > bottom) XSwap(top,bottom);
}
/*************************************************
Summary: Move a rectangle to a position.
Input Arguments:
pos: new position of the rectangle in Vx2DVector.
See also: VxRect::Translate
*************************************************/
void Move(const Vx2DVector& pos)
{
right += (pos.x - left);
bottom += (pos.y - top);
left = pos.x;
top = pos.y;
}
/*************************************************
Summary: Translate a rectangle of an offset.
Input Arguments:
t: translation vector in Vx2DVector.
See also: VxRect::Move
*************************************************/
void Translate(const Vx2DVector& t)
{
left += t.x;
right += t.x;
top += t.y;
bottom += t.y;
}
void HMove(float h) {right += (h - left);left = h;}
void VMove(float v) {bottom += (v - top);top = v;}
void HTranslate(float h) {right += h;left += h;}
void VTranslate(float v) {bottom += v;top += v;}
/*************************************************
Summary: Transform a point in homogeneous coordinates
into a points in screen coordinates (the rect representing the screen).
Input Arguments:
dest: vector destination (in screen coordinates).
srchom: src vector (in homogeneous coordinates).
See also: VxRect::Move
*************************************************/
void TransformFromHomogeneous(Vx2DVector& dest,const Vx2DVector& srchom) const
{
dest.x = left + GetWidth()*srchom.x;
dest.y = left + GetHeight()*srchom.y;
}
/*************************************************
Summary: Scales a rectangle by a factor.
Input Arguments:
t: translation vector in Vx2DVector.
See also: VxRect::Inflate
*************************************************/
void Scale(const Vx2DVector& s)
{
SetWidth(s.x*GetWidth());
SetHeight(s.y*GetHeight());
}
/*************************************************
Summary: Inflates a rectangle by an offset.
Input Arguments:
See also: VxRect::Scale
*************************************************/
void Inflate(const Vx2DVector& pt)
{
left -= pt.x; right += pt.x;
top -= pt.y; bottom += pt.y;
}
/*************************************************
Summary: Interpolates a rectangle with another one.
Input Arguments:
See also: VxRect::Scale
*************************************************/
void Interpolate(float value, const VxRect& a)
{
left += (a.left-left)*value;
right += (a.right-right)*value;
top += (a.top-top)*value;
bottom += (a.bottom-bottom)*value;
}
/*************************************************
Summary: Merge a rectangle with another one.
Input Arguments:
See also: VxRect::Scale
*************************************************/
void Merge(const VxRect& a)
{
if (a.left < left) left = a.left;
if (a.right > right) right = a.right;
if (a.top < top) top = a.top;
if (a.bottom > bottom) bottom = a.bottom;
}
/*************************************************
Summary: Tests a rectangle over a clipping rectangle.
Input Arguments:
cliprect: clipping rectangle.
Return Value:
ALLOUTSIDE if the two rectangles are distinct.
PARTINSIDE if the two rectangles are crossing.
ALLINSIDE if the tested rectangle is inside the clipping rectangle.
See also: VxRect::IsOutside
*************************************************/
int IsInside(const VxRect& cliprect) const
{
// entirely clipped
if(left >= cliprect.right) return ALLOUTSIDE;
if(right < cliprect.left) return ALLOUTSIDE;
if(top >= cliprect.bottom) return ALLOUTSIDE;
if(bottom < cliprect.top) return ALLOUTSIDE;
// partially or not clipped
if(left < cliprect.left) return PARTINSIDE;
if(right > cliprect.right) return PARTINSIDE;
if(top < cliprect.top) return PARTINSIDE;
if(bottom > cliprect.bottom)return PARTINSIDE;
return ALLINSIDE;
}
/*************************************************
Summary: Tests a rectangle over a clipping rectangle.
Input Arguments:
cliprect: clipping rectangle.
Return Value:
TRUE if the rectangle is outside the clipping one,
FALSE otherwise.
See also: VxRect::IsInside
*************************************************/
BOOL IsOutside(const VxRect& cliprect) const
{
// entirely clipped
if(left >= cliprect.right) return TRUE;
if(right < cliprect.left) return TRUE;
if(top >= cliprect.bottom) return TRUE;
if(bottom < cliprect.top) return TRUE;
return FALSE;
}
/*************************************************
Summary: Tests a point for rectangle interiority.
Input Arguments:
pt: Vx2DVector to test.
Return Value:
TRUE if the point is inside, FALSE otherwise.
See also: VxRect::IsOutside
*************************************************/
BOOL IsInside(const Vx2DVector& pt) const
{
if (pt.x<left) return FALSE;
if (pt.x>right) return FALSE;
if (pt.y<top) return FALSE;
if (pt.y>bottom) return FALSE;
return TRUE;
}
/*************************************************
Summary: Tests a rectangle for validity.
Return Value:
TRUE if the rectangle is NULL, FALSE otherwise.
See also: VxRect::IsOutside, VxRect::Clear
*************************************************/
BOOL IsNull() const {return (left==0 && right==0 && bottom==0 && top==0);}
/*************************************************
Summary: Clips a rectangle over a clipping rectangle.
Input Arguments:
cliprect: clipping rectangle.
Return Value:
TRUE if the rectangle is visible (partially clipped or not),
FALSE otherwise.
See also: VxRect::IsOutside,VxRect::IsInside
*************************************************/
BOOL Clip(const VxRect& cliprect)
{
// entirely clipped
if (IsOutside(cliprect)) return FALSE;
// partially or not clipped
if(left < cliprect.left) left = cliprect.left;
if(right > cliprect.right) right = cliprect.right;
if(top < cliprect.top) top = cliprect.top;
if(bottom > cliprect.bottom) bottom = cliprect.bottom;
return TRUE;
}
/*************************************************
Summary: Clips a point over a rectangle.
Input Arguments:
pt: point to clip
excluderightbottom: should the bottom and right line be considered as valid values for the point.
See also: VxRect::IsOutside,VxRect::IsInside
*************************************************/
void Clip(Vx2DVector& pt,BOOL excluderightbottom = TRUE) const
{
if (pt.x < left) pt.x = left;
else {
if (pt.x >= right) {
if (excluderightbottom) pt.x = right-1;
else pt.x = right;
}
}
if (pt.y < top) pt.y = top;
else {
if (pt.y >= bottom) {
if (excluderightbottom) pt.y = bottom-1;
else pt.y = bottom;
}
}
}
/*************************************************
Summary: Transforms a rectangle from a screen referentiel to another.
Input Arguments:
destscreen: destination referential screen defined by a rectangle.
srcscreen: source referential screen defined by a rectangle.
destscreen: destination referential screen size.
srcscreen: source referential screen size.
See also: VxRect::TransformToHomogeneous
*************************************************/
VX_EXPORT void Transform(const VxRect& destScreen,const VxRect& srcScreen);
VX_EXPORT void Transform(const Vx2DVector& destScreenSize,const Vx2DVector& srcScreenSize);
/*************************************************
Summary: Transforms a screen coordinate rectangle to an homogeneous rectangle.
Input Arguments:
screen: Vx2DVector screen size.
See also: VxRect::Transform
*************************************************/
VX_EXPORT void TransformToHomogeneous(const VxRect& screen);
/*************************************************
Summary: Transforms an homogeneous rectangle to a screen coordinate rectangle.
Input Arguments:
screen: Vx2DVector screen size.
See also: VxRect::Transform
*************************************************/
VX_EXPORT void TransformFromHomogeneous(const VxRect& screen);
// Operator with 2DVectors
VxRect& operator += (const Vx2DVector& t)
{
left += t.x; right += t.x;
top += t.y; bottom += t.y;
return *this;
}
VxRect& operator -= (const Vx2DVector& t)
{
left -= t.x; right -= t.x;
top -= t.y; bottom -= t.y;
return *this;
}
VxRect& operator *= (const Vx2DVector& t)
{
left *= t.x; right *= t.x;
top *= t.y; bottom *= t.y;
return *this;
}
VxRect& operator /= (const Vx2DVector& t)
{
float x = 1.0f/t.x; float y = 1.0f/t.y;
left *= x; right *= x;
top *= y; bottom*= y;
return *this;
}
//
friend int operator == (const VxRect& r1, const VxRect& r2);
//
friend int operator != (const VxRect& r1, const VxRect& r2);
};
//
inline int operator == (const VxRect& r1, const VxRect& r2)
{
return (r1.left==r2.left && r1.right==r2.right && r1.top==r2.top && r1.bottom==r2.bottom);
}
//
inline int operator != (const VxRect& r1, const VxRect& r2)
{
return !(r1 == r2);
}
#endif