#ifndef SHAPES_H #define SHAPES_H #ifndef GRAPHICS_H #include "graphics.h" #endif class Point; class Segment; class Shape { public: virtual void scale(Point center, double s) = 0; virtual void move(int x, int y) = 0; virtual void read(istream& is) = 0; virtual void plot(Graphics& g) const = 0; virtual void print(ostream& os) const = 0; virtual Shape* clone() const = 0; virtual ~Shape() {} }; class Point : public Shape { public: Point(int xx =0, int yy =0); virtual void scale(Point center, double s); virtual void move(int x, int y); virtual void read(istream& is); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; virtual Shape* clone() const; int x() const; int y() const; double distance(Point b) const; double angle(Point b) const; private: int _x; int _y; }; class Rectangle : public Shape { public: Rectangle(); Rectangle(Point, Point); virtual void scale(Point center, double s); virtual void move(int x, int y); virtual void read(istream& is); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; virtual Shape* clone() const; Point topleft() const; Point bottomright() const; Point center() const; bool is_inside(Point p) const; Point boundary_point(Point p) const; private: Point _topleft; Point _bottomright; }; class FilledRect : public Rectangle { public: FilledRect(); FilledRect(Point, Point, Color); virtual void plot(Graphics& g) const; private: Color _color; }; class Segment : public Shape { public: Segment(); Segment(Point f, Point t); virtual void scale(Point center, double s); virtual void move(int x, int y); virtual void read(istream& is); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; virtual Shape* clone() const; Point center() const; bool intersect(Segment s, Point& p) const; Point closest(Point p) const; double distance(Point p) const; Point from() const; Point to() const; private: Point _from; Point _to; }; class Ellipse : public Shape { public: Ellipse(); Ellipse(Point, int, int); virtual void scale(Point center, double s); virtual void move(int x, int y); virtual void read(istream& is); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; virtual Shape* clone() const; Point center() const; int xradius() const; int yradius() const; bool is_inside(Point p) const; Point boundary_point(Point p) const; private: Point _center; int _xradius; int _yradius; }; class Polygon : public Shape { public: Polygon(); Polygon(int); void set_corner(int, Point); virtual void scale(Point center, double s); virtual void move(int x, int y); virtual void read(istream& is); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; virtual Shape* clone() const; Point corner(int) const; Point center() const; private: #ifndef PRACTICALOO_MUST_USE_ALLOCATOR vector _corners; #else vector > _corners; #endif }; class Text : public Shape { public: Text() {} Text(Point, string); virtual void scale(Point center, double s); virtual void move(int x, int y); virtual void read(istream& is); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; virtual Shape* clone() const; private: Point _start; string _text; }; class ScalableText : public Text { public: ScalableText(); ScalableText(Point, string, double); virtual void scale(Point center, double s); virtual void read(istream& is); virtual void plot(Graphics& g) const; virtual void print(ostream& os) const; virtual Shape* clone() const; Rectangle extent(Graphics& g) const; private: double _size; }; inline bool approx_eq(double x, double y) /* PURPOSE: tests whether two floating point numbers are approximately equal RETURNS: true iff |x-y| approx. 0 */ { const double EPS = 0.000001; return fabs(x - y) < EPS; } inline bool approx_le(double x, double y) /* PURPOSE: compares two floating point numbers, allowing for roundoff RETURNS: true iff x < y + roundoff */ { const double EPS = 0.000001; return x - y < EPS; } inline int Point::x() const { return _x; } inline int Point::y() const { return _y; } #endif