/****************************************************************************
* rect_adt.h :
* header file for rectanle ADT.
*
* Change Log :
* DEC-22-1996 Initial version, Liujian Qian
*
* $Id: gadt_rect.h,v 1.8 1999/02/03 06:44:59 qian Exp $
***************************************************************************/
#ifndef _GRECT_H_
#define _GRECT_H_
#include "gadt.h"
#include <math.h>
/**
* a rectangle ADT class.
*
* Setup the lower corner (the corner with lower
* coordinates) and the upper corner. Then you can check whether
* it covers or intersects other types of spatial objects, among
* other functionalities.
*/
class GRect : public GSpatial
{
public:
/**
* the two corners' coordinates
*/
Coord xlow, ylow, xhi, yhi;
public:
/**
*/
GRect() ;
/**
*/
GRect(Coord xLow, Coord yLow, Coord xUp, Coord yUp);
/**
*/
GRect(const GRect& other);
/**
*/
GRect& operator= (const GRect& other);
/**
*/
virtual ~GRect() { };
virtual GType type (void) const { return _Rect; }
virtual uint32 getPSize() const;
virtual Result input (const char* in);
virtual Result output (char*& out);
virtual Result pack (DataPipe& p);
virtual Result unpack (DataPipe& p);
virtual Result mbr (GRect& b) const { b = *this; return GOk; }
virtual int cmp (const GADT& other) const;
virtual Result init (void) { xlow=ylow=xhi=yhi=InvalidCoord;
return GOk;}
virtual GADT* clone () const {return new GRect;}
virtual Result scale (double xf, double yf, double zf=1);
virtual Result translate (double xf, double yf, double zf=1);
virtual Result rotate (double, bool);
virtual Result transform (const GMatrix&);
/**
* return the smaller X coordinate
*/
inline Coord getXL() const { return xlow; }
/**
* return the smaller Y coordinate
*/
inline Coord getYL() const { return ylow; }
/**
* return the higher X coordinate
*/
inline Coord getXH() const { return xhi; }
/**
* return the hither Y coordinate
*/
inline Coord getYH() const { return yhi; }
/**
* set the value of lower X coordinate
*/
inline void setXL(Coord x) { xlow = x; }
/**
* set the value of lower Y coordinate
*/
inline void setYL(Coord y) { ylow = y; }
/**
* set the value of higher X coordinate
*/
inline void setXH(Coord x) { xhi = x; }
/**
* set the value of higher Y coordinate
*/
inline void setYH(Coord y) { yhi = y; }
/**
* set the coordinates for the two corners.
* xLow/yLow is the lower corner; xHi/yHi the higher corner.
*/
inline void set(Coord xLow, Coord yLow, Coord xHi, Coord yHi);
/**
*/
inline Coord getWidth(void) const {return GABS(xhi - xlow) ;}
/**
*/
inline Coord getHeight(void) const {return GABS(yhi - ylow) ;}
/**
*/
inline double area() const { return (getWidth() * getHeight()); }
/**
* return the distance between the centroids of the two rectangles.
*/
double distance (const GRect& other) const;
/**
*/
inline double perimeter() const {return (2*getWidth() + 2*getHeight()); }
/**
* check if the rectangle contains valid coordinates.
* a rectangle is invalid if A: any of the coordinates are of
* InvalidCoord value, or B: the lower coordinate values are
* greater than the higher coordinates.
*/
inline bool isValid() const ;
/**
* check whehter two rectangles are the same
*/
bool equals (const GRect& other) const;
/**
* if the "other" rectangle covers or intersects with this one,
* then enlarge this rectangle to just contain the other one;
* otherwise (the other rect is inside this one) do nothing.
*/
void enlarge (const GRect& other);
/**
* get the centroid of the rectangle
*/
void centroid(Coord& x, Coord& y);
/**
* check if the rectangle covers another geometry object;
* possible types of objects are: Rect, Point, Segment, Polyline, Ring, Polygon.
*/
virtual int covers (const GSpatial& a) const;
/**
* check if the rectangle intersects another object
* possible types of objects are: Rect, Circle, Polyline, Ring, Segment, Polygon
*/
virtual int intersects(const GSpatial& a) const;
private:
int _covers(const GRect& a) const;
int _covers(const GPoint& p) const;
int _covers(const GSegment& seg) const;
int _covers(const GArc& pln) const;
int _covers(const GPolygon& pgn) const;
int _intersects(const GRect& a) const;
int _intersects(const GCircle& a) const;
int _intersects(const GArc& ln) const;
int _intersects(const GSegment& seg) const;
int _intersects(const GPolygon& pgn) const;
friend ostream& operator<<(ostream& s, const GRect& r);
}; //class GRect
static class _GIRect
{
static int cnt;
public:
_GIRect()
{
if(cnt++ ==0 )
GADTManager::registerADT(new GADTDef( _Rect, "Rect", 1, 1, new GRect) );
}
~_GIRect()
{
if(--cnt==0)
GADTManager::removeADT(_Rect);
}
} gi_rect;
inline void
GRect::set(Coord xLow, Coord yLow, Coord xUp, Coord yUp)
{
if(xLow<=xUp && yLow<=yUp) {
xlow = xLow, ylow=yLow, xhi = xUp, yhi = yUp;
} else {
msgWarn("rect's lower/upper boundary not properly given");
xlow = GMIN(xLow, xUp), ylow=GMIN(yLow,yUp);
xhi = GMAX(xLow, xUp), yhi =GMAX(yLow,yUp);
}
};
#endif
Documentation generated by lqian@lqian-sun on Wed Jul 14 09:36:10 EDT 1999