Because Shapes are passed by const reference, do not delete a Shape if they are being referenced within another Shape. This means a Shape should be named and have at least the same scope as any objects which reference it.
Do not overlap constructor calls: auto layered = Layered(Circle(80.0), Rectangle(80.0, 80.0))
The line above will compile and the object layered
will access the deallocated Circle and Rectangle.
A Shape has one inherited user-accessible public function:
std::string evaluatePostScript() const
- Returns a string of valid PostScript to draw the Shape on the center of a page
A derived class of Shape must define:
point_t getBoundingBox() const
- Returns the bounding box to affect this and other Shapes' placementstd::string generatePostScript(point_t center) const
- Returns a string of valid PostScript to draw the Shape at the given center point
A derived class of Shape which needs to call the protected members getBoundingBox()
and generatePostScript(point_t)
of other Shapes can use the public wrapper functions getBoundingBox(ShapeKey)
and generatePostScript(point_t, ShapeKey)
.
An Example:
for (const auto & shape : shapes)
{
auto boundingBox = shape.getBoundingBox({});
point_t center = {0.0, 0.0};
auto postscript = shape.generatePostScript(center, {});
// ...
}
Interface: Circle(double radius)
Description: A circle with the given radius.
Example:
auto circle = Circle(80.0);
Interface: Rectangle(double width, double height)
Description: A rectangle with the given width and height.
Example:
auto rectangle = Rectangle(80.0, 40.0);
Interface: Square(double sideLength)
Description: A square with the given side length.
Example:
auto square = Square(80.0);
Interface: Triangle(double sideLength)
Description: A triangle with the given side length.
Example:
auto triangle = Triangle(80.0);
Interface: Polygon(unsigned int numSides, double sideLength)
Description: A regular polygon with the given number of sides.
Example:
auto polygon = Polygon(6, 40.0);
Interface: Spacer(double width, double height)
Description: An invisible rectangle which can offset the placement of other Shapes.
Example:
auto spacer = Spacer(80.0, 40.0);
Interface: Rotated(const Shape & shape, double angleInDegrees)
Description: Rotates a shape counter-clockwise by the given angle in degrees.
Example:
auto rectangle = Rectangle(80.0, 40.0);
auto spacer = Rotated(rectangle, 45.0);
Interface: Scaled(const Shape & shape, double xScale, double yScale)
Description: Scales a shape's width and height.
Example:
auto circle = Circle(40.0);
auto scaled = Scaled(circle, 2.0, 1.0);
Interface: Layered(std::vector<std::reference_wrapper<const Shape>> shapes)
Description: Overlaps shapes by centering.
Example:
auto circle = Circle(40.0);
auto scaled = Scaled(circle, 2.0, 1.0);
auto rectangle = Rectangle(80.0, 40.0);
auto layered = Layered( { circle, scaled, rectangle } );
Interface: Vertical(std::vector<std::reference_wrapper<const Shape>> shapes)
Description: Vertically stacks shapes from bottom to top.
Example:
auto circle = Circle(40.0);
auto spacer = Spacer(40.0, 40.0);
auto vertical = Vertical( { circle, spacer, circle } );
Interface: Horizontal(std::vector<std::reference_wrapper<const Shape>> shapes)
Description: Horizontally stacks shapes from left to right.
Example:
auto circle = Circle(40.0);
auto spacer = Spacer(40.0, 40.0);
auto horizontal = Horizontal( { circle, spacer, circle } );
Interface: Ellipse(double xRadius, double yRadius)
Description: An ellipse with the given x and y radii.
Example:
auto ellipse = Ellipse(80.0, 40.0);
Interface: Donut(unsigned int n, double offsetR, double subcircleR)
Description: A donut-like shape with n
evenly-distributed subcircles of radius subcircleR
which are each centered on the radius offsetR
.
Example:
auto donut = Donut(100, 80.0, 40.0);