// -*- C++ -*- // $RCSfile: shape.h,v $ // $Revision: 1.7 $ // $Author: langer $ // $Date: 2001/02/16 14:53:54 $ /* This software was produced by NIST, an agency of the U.S. government, * and by statute is not subject to copyright in the United States. * Recipients of this software assume all responsibilities associated * with its operation, modification and maintenance. However, to * facilitate maintenance we ask that before distributing modifed * versions of this software, you first contact the authors at * oof_manager@ctcms.nist.gov. */ // Shapes with integer coordinates (shapes defined on an image) #ifndef SHAPE_H #define SHAPE_H class Shape; class Intersection; #include "array.h" #include "ishape.h" #include "meshcoord.h" class Cell_coordinate; class ImageRect; class Shape { public: virtual ~Shape() {} virtual int contains(const MeshCoord&) const = 0; virtual ImageRect containing_rectangle() const = 0; virtual Shape *clone() const = 0; }; // A rectangle is defined by two diagonally opposing corners. class Rectangle : public Shape { public: MeshCoord ll; // lower left MeshCoord ur; // upper right Rectangle() {} Rectangle(const MeshCoord &c1, const MeshCoord &c2); double width() const; double height() const; virtual int contains(const MeshCoord&) const; virtual ImageRect containing_rectangle() const; virtual Shape *clone() const; }; // A circle is defined by its center and a point on the perimeter. class Circle : public Shape { private: double xcenter, ycenter; double r, rsquare; ImageRect container; public: Circle() : xcenter(0), ycenter(0), r(0), rsquare(0) {} Circle(const MeshCoord &c1, const MeshCoord &c2); virtual int contains(const MeshCoord &) const; virtual ImageRect containing_rectangle() const { return container; } virtual Shape *clone() const; }; // An ellipse is defined by the box that it fits into. The axes must // be along x and y. class Ellipse : public Shape { private: double xcenter, ycenter; double invxaxis, invyaxis; bool null; // is this a degenerate ellipse? ImageRect container; public: Ellipse() : xcenter(0), ycenter(0), invxaxis(0), invyaxis(0), null(1) {} Ellipse(const MeshCoord &c1, const MeshCoord &c2); virtual int contains(const MeshCoord&) const; virtual ImageRect containing_rectangle() const { return container; } virtual Shape *clone() const; }; //=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=// class Intersection : public Shape { private: // have to have a copy of the shapes, in case the constructor's // arguments are temporary variables. const Shape *shape1; const Shape *shape2; ImageRect container; public: Intersection(const Shape&, const Shape&); virtual ~Intersection(); Shape *clone() const; virtual int contains(const MeshCoord &) const; virtual ImageRect containing_rectangle() const; // { return container; } }; Intersection operator&&(const Shape &s1, const Shape &s2); //=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=// class ShapeIterator { private: ArrayIterator iter; const Shape *shape; public: ShapeIterator(const Shape &sh) : shape(sh.clone()), iter(sh.containing_rectangle()) {} ~ShapeIterator(); int operator()(Cell_coordinate &pixel); void reset() { iter.reset(); } int upperbound() const; // an upper bound on the number of pixels }; #endif