// shape.h // Definition of classes Point, Shape, Polyline, // Line, Polygon, Rectangle, Ellipse, Circle. #ifndef SHAPE_H #define SHAPE_H #include using std::string; using std::stringstream; using std::ostream; #include using std::cout; using std::endl; using std::cin; #include // sqrt // class Point struct Point { double x, y; Point( double xx = 0.0, double yy = 0.0 ) : x( xx ), y( yy ) { } double distance( const Point& p2 ) const { double dx = x - p2.x, dy = y - p2.y; return sqrt( dx * dx + dy * dy ); } string toString() const { stringstream sstream; sstream << '(' << x << ", " << y << ')'; return sstream.str(); } Point& operator*=( double c ) { x *= c; y *= c; return *this; } }; inline Point operator+( const Point& p1, const Point& p2 ) { return Point( p1.x + p2.x, p1.y + p2.y ); } inline Point operator-( const Point& p1, const Point& p2 ) { return Point( p1.x - p2.x, p1.y - p2.y ); } inline bool operator==( const Point& p1, const Point& p2 ) { return p1.x == p2.x && p1.y == p2.y; } inline bool operator!=( const Point& p1, const Point& p2 ) { return !( p1 == p2 ); } inline ostream& operator<<( ostream& os, const Point& p ) { os << p.toString(); return os; } // class Shape class Shape { protected: Point anchor; // anchor: point of reference for position of figure public: Shape( const Point& a = Point() ) : anchor( a ) { } virtual ~Shape() { } Point getAnchor() const { return anchor; } void setAnchor( Point a ) { anchor = a; } void move( double dx, double dy ) // displacement { anchor.x += dx; anchor.y += dy; } virtual void scale( double scalingFactor ) = 0; virtual void draw() const = 0; virtual string toString() const { string str( "Shape-Anker: " ); return str += anchor.toString(); } }; // class Polyline class Polyline : public Shape { protected: Point* arrPoints; // end-points of lines, relativ to anchor int nLines; // number of line-segments == number of end-points public: Polyline( const Point& a = Point() ) // only one point : Shape( a ), nLines( 0 ), arrPoints( NULL ) { } Polyline( const Point& p1, const Point& p2 ) // one line : Shape( p1 ), nLines( 1 ) { arrPoints = new Point( p2 - p1 ); } Polyline( Point arr[], int n ); Polyline( const Polyline& src ); // copy constructor ~Polyline() { delete [] arrPoints; } // destructor Polyline& operator=( const Polyline& src ); // assignment int getNumberOfLines() const { return nLines; } double getLength() const; void scale( double scalingFactor ); // scaling virtual void draw() const { } Polyline& operator+=( const Point& p ); // appends a new point Polyline& operator+=( const Polyline& pl ); // appends a new line string toString() const; }; // class Line class Line : public Polyline { public: Line( Point a, Point b ) : Polyline( a, b ) { } Line( double x1, double y1, double x2, double y2 ) : Polyline( Point( x1, y1 ), Point( x2, y2 ) ) { } private: Polyline& operator+=( const Point& ); // not allowed Polyline& operator+=( const Polyline& ); // not allowed }; // class Polygon class Polygon : public Polyline { public: Polygon( Point a = Point( 0, 0 ) ) : Polyline( a ) {} Polygon( Point arr[], int n ) : Polyline( arr, n ) {} int getNumberOfVertices() const { if( nLines == 0 || arrPoints[ nLines - 1 ] != anchor ) return nLines + 1; else return nLines; } int getNumberOfLines() const { return getNumberOfVertices(); } double getCircumference() const { double len = Polyline::getLength(); if( nLines > 0 ) len += anchor.distance( anchor + arrPoints[ nLines - 1 ] ); return len; } double getLength() const { return getCircumference(); } }; // class Rectangle class Rectangle : public Polygon // rectangle { // anchor: left lower corner public: Rectangle( Point lBottom, double w, double h ) : Polygon( lBottom ) { nLines = 3; // number of lines: nLines + 1 arrPoints = new Point[ 3 ]; arrPoints[ 0 ] = Point( 0, h ); arrPoints[ 1 ] = Point( w, h ); arrPoints[ 2 ] = Point( w, 0 ); } Rectangle( Point lBottom, Point rTop ) { *this = Rectangle( lBottom, rTop.x - lBottom.x, rTop.y - lBottom.y ); } double getHeight() const { return arrPoints[ 0 ].y; } double getWidth() const { return arrPoints[ 2 ].x; } double getArea() const { return getHeight() * getWidth(); } private: Polyline& operator+=( const Point& ); // not allowed Polyline& operator+=( const Polyline& ); // not allowed }; // class Ellipse class Ellipse : public Shape // anchor-centered ellipse { protected: double a, b; // semi-major and semi-minor axis public: Ellipse( Point m, double aa, double bb ) : Shape( m ), a( aa ), b( bb ) { } double getSemimajorAxis() const { return a; } double getSemiminorAxis() const { return b; } bool setSemimajorAxis( double aa ) { if( aa >= 0 ) { a = aa; return true; } else return false; } bool setSemiminorAxis( double bb ) { if( bb >= 0 ) { b = bb; return true; } else return false; } void scale( double scalingFactor ) // scaling { a *= scalingFactor; b *= scalingFactor; } virtual void draw() const { } double getCircumference() const { return 3.14159 * ( 1.5 * ( a + b ) - sqrt( a * b ) ); } string toString() const { stringstream sstream; sstream << "Ellipsen-Mittelpunkt: " << anchor.toString() << " Halbachsen: " << a << " und " << b; return sstream.str(); } }; // class Circle class Circle : public Ellipse // anchor-centered circle { public: Circle( Point m, double r ) : Ellipse( m, r, r ) { } double getRadius() const { return a; } bool setRadius( double r ) { if( r >= 0 ) { a = r; b = r; return true; } else return false; } string toString() const { stringstream sstream; sstream << "Kreis-Mittelpunkt: " << anchor.toString() << " Radius: " << a; return sstream.str(); } }; #endif