/****************************************************************************
 *   gcircle_adt.h : 
 *   		header file for circle ADT.
 *
 *   Change Log :
 *		 Dec-22-1996 Initial version,  Liujian Qian
 *
 *   $Id: gadt_circle.h,v 1.5 1999/02/09 09:21:07 qian Exp $
 ***************************************************************************/
 
#ifndef _GCIRCLE_H_
#define _GCIRCLE_H_

#include "gadt.h"

/**
 *	Class for circles.
 *
 *      This is a circle class. A circle consists of the center (x,y) and the
 *	radius. You can use it with other spatial ADTs through the
 *	commonly defined methods such as <b> intersects </b> or <b>
 *	covers, isInside </b>, etc. 
 */
class GCircle : public GSpatial
{
    Coord cx, cy;
    double radius;

public:

    /**
     */
    GCircle(Coord x, Coord y, double r) 
    {
	cx =x , cy =y, radius = r;
    }

    /**
     */
    GCircle() { init(); }

    /**
     * copy constructor
     */
    GCircle(const GCircle& other) 
    {
	radius = other.radius;
	cx = other.cx;
	cy = other.cy;
    }

    /**
     */
    GCircle& operator=(const GCircle& other);
    
    /**
     */
    virtual ~GCircle() {};
    
    virtual GType 	 type(void) const { return _Circle; }

    virtual uint32  	 getPSize() const;
    virtual Result	 init	   (void) {cx=cy=InvalidCoord; 
                                           radius = 0.0; return GOk; }
    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;
    virtual int		 cmp	   (const GADT& other) const;
    virtual GADT* 	 clone	   () const {return new GCircle;}

    virtual Result       translate  (double xf, double yf, double zf=1);
    virtual Result       scale      (double xf, double yf, double zf=1);
    virtual Result	 rotate	   (double, bool);
    virtual Result	 transform  (const GMatrix&);

    /**
     * calculate and return the area
     */
    double               area() const { return (double)(_PI_ * radius * radius); }
    
    /**
     * calculate and return the preimeter
     */
    double               perimeter() const {return (double) 2 * _PI_ * radius; }

    /**
     * set the center point
     */
    void                 setCntr(Coord _cx, Coord _cy) { cx = _cx, cy = _cy;}

    /**
     * set the center point and the radius
     */
    void                 set(Coord _cx, Coord _cy, double r){
      cx = _cx , cy = _cy, radius = r; }

    /**
     * given the center and area; calculate the radius
     */
    void                 setArea(Coord _cx, Coord _cy, double area);

    /**
     * set radius
     */
    void                 setR(double rad);

    /**
     * retrieving center and the radius
     */
    Coord                getCX() const {return cx;}
    Coord                getCY() const {return cy;}
    double               getR() const  {return radius;}

    /**
     * comparing with another circle
     */
    bool equals (GCircle& other) const;

    /**
     * return the centroid, which is the center
     */
    void centroid(Coord& x, Coord& y) {x = cx, y= cy;}

    /**
     * check it this object covers another spatial ADT 0bject
     */
    virtual int covers     (const GSpatial& a) const;
    
    /**
     * check if this object intersects another spatial ADT object
     */
    virtual int	intersects (const GSpatial& a) const;


private:
    
    int _covers(const GPoint& a) const;
    int _covers(const GSegment& a) const;
    int _covers(const GRect& a) const ;
    int _covers(const GCircle& a) const;
    int _covers(const GArc& arc) const;
    int _covers(const GPolygon& pgn) const;
    
    int _intersects (const GSegment& s) const;
    int _intersects (const GCircle& a) const;
    int _intersects (const GRect& r) const;
    int _intersects (const GArc& r) const;
    int _intersects (const GPolygon& r) const;
    
    friend ostream& operator<<(ostream& s, const GCircle& c);
    
};  //class GCircle


static class _GICircle
{
    static int cnt;
public:
    _GICircle() 
    {
	if(cnt++ ==0 ) 
	    GADTManager::registerADT(new GADTDef( _Circle, "Circle", 
						  1, 1, new GCircle) );
    }
    ~_GICircle() 
    {
	if(--cnt==0)
	    GADTManager::removeADT(_Circle);
    }
} gi_circle;


#endif





Documentation generated by lqian@lqian-sun on Wed Jul 14 09:36:10 EDT 1999