CS 372 Spring 2016 > Group Project 2
CS 372 Spring 2016
Group Project 2
Idea
In this project, you are to work in a group of students to go through a software development process whose goal is to produce a C++ library that takes commands to draw certain shapes and outputs code in the PostScript programming language.
You should use Object-Oriented Design in this project.
Rules
You must work with your assigned group.
Each group member must present at least one of the in-class presentations.
All project documents—source code, requirements, design, testing, etc.—must be stored in a Git repository, to which all students in the group have read/write access, and to which the instructor has read access. E-mail me the URL for your project repository as soon as you set it up.
Project source code must be in C++.
Project source code must compile and execute at all times.
Specification
Shape Language
The Shape language allows specification of a drawing in terms of a number of shapes.
A shape may be a basic shape, which can be created without reference to any existing shapes. Examples of basic shapes are cirlces, rectangles, etc. A shape may also be a compound shape, which is constructed from existing shapes.
Each shape has a bounding box: an axis-aligned rectangle that encloses it. The center of a shape is defined to be the center of its bounding box.
The base unit is 1/72 inch, just as in the PostScript language.
Basic Shapes
Basic shapes are shapes that can be created without reference to any existing shapes. Boldface text below is not a specification of syntax, but simply shows the information that needs to be given to create a shape of each kind.
- Circle(double radius). Creates a circle with the given radius. The height and the width are both 2*radius.
- Polygon(int numSides, double sideLength). Creates a regular polygon with the given number of sides, each of the given length, oriented to that the lowest side is horizontal.
- Rectangle(double width, double height). Creates a rectangle of the given width and height.
- Spacer(double width, double height). Just like a rectangle, but nothing is drawn. A Spacer is not visible on the page.
- Square(double sideLength). Same as Polygon(4, sideLength).
- Triangle(double sideLength). Same as Polygon(3, sideLength).
Compound Shapes
Compound shapes are shapes that are constructed from existing shapes. Boldface text below is not a specification of syntax, but simply shows the information that needs to be given to create a shape of each kind.
- Rotated(Shape shape, RotationAngle angle). Takes an existing shape and an angle, which must be a multiple of 90 degrees (0, 90, 180, 270, 360, 450, -90, -180, etc.). Creates a version of the original shape that is rotated counter-clockwise through the given angle about its center.
- Scaled(Shape shape, double sx, double sy). Takes an existing shape and two scale factors. Scales the x-coordinate by sx, and the y-coordinate by sy, with the center of the shape being unchanged. For example, if sx and sy are both 1, then the Scaled shape appears identical to the existing shape.
- Layered(Shape... shapes). Given a collection of shapes, creates a new shape consisting of all the given shapes drawn with their centers at the same point.
- Vertical(Shape... shapes). Given a collection of shapes, creates a new shape consisting of all the given shapes drawn in a vertical stack, top to bottom, with their bounding boxes touching, and centered at the same x-coordinate.
- Horizontal(Shape... shapes). Given a collection of shapes, creates a new shape consisting of all the given shapes drawn in a horizontal stack, left to right, with their bounding boxes touching, and centered at the same y-coordinate.
Tasks
Your group is to do the following.
- Formalize the shape language.
- Design and implement a shape-language to PostScript translator.
- Design some nice shapes of your own: basic and/or compound. Include these in your implementation.
- Design and implement a test strategy for your package.
- Code a few examples that use your library.
Deliverables
- Git repository URL
- Design document
- Project source code
- Testing code
- Example code using your library. This should include multiple drawings, at least one of which uses the shapes you added.
- The PostScript output produced by the above examples.
Final versions of all of the above will be due at noon on Wednesday, April 20. Earlier due dates for possibly incomplete versions of various of the above will be announced.
Formulae
Suppose we are drawing Polygon(\(n\), \(e\)). So \(n\) is the number of sides, and \(e\) is the edge length. If the polygon is centered at the point \((0,0)\), then the coordinates of the vertices are the following.
\[ \left( \frac{e}{2}\cdot\frac{\sin\frac{(2k+1)\pi}{n}}{\sin\frac{\pi}{n}}, -\frac{e}{2}\cdot\frac{\cos\frac{(2k+1)\pi}{n}}{\sin\frac{\pi}{n}} \right), \quad\text{for \(k = 0,1,\dots,n-1\)} \]
The width and height of the bounding box of Polygon(n, e) are as follows (\(n\) is the number of sides, and \(e\) is the edge length).
Values of \(n\) | Width | Height |
---|---|---|
Case 1. \(n\) is odd | \(\displaystyle e\cdot \frac{\sin\frac{\pi(n-1)}{2n}}{\sin\frac{\pi}{n}}\) | \(\displaystyle e\cdot \frac{1+\cos\frac{\pi}{n}}{2\sin\frac{\pi}{n}}\) |
Case 2. \(n\) is even, but is not divisible by \(4\) | \(\displaystyle e\cdot\frac{1}{\sin\frac{\pi}{n}}\) | \(\displaystyle e\cdot\frac{\cos\frac{\pi}{n}}{\sin\frac{\pi}{n}}\) |
Case 3. \(n\) is divisible by \(4\) | \(\displaystyle e\cdot\frac{\cos\frac{\pi}{n}}{\sin\frac{\pi}{n}}\) |
Grading
The project is worth 50 points. Grading will be as for Group Project 1.
Thoughts
Some things to consider.
- How does the code that calls your library indicate that it is time to generate PostScript code?
- When a shape is specified, its location is not given. This is necessary, since compound shapes can move around the shapes they are composed of. But a location must be specified at some point. How will this be done?
- I suggest passing a collection of shapes
using the C++11 initializer-list syntax.
The result will be an object of type
std::initializer_list<T>
, whereT
is the type of each item in the list (Shape
?(Shape *)
?). - If you design your library well, then adding new kinds of shapes should be very easy.