Homework 2: Simple Drawing Program

Hand out

Check in

Policy on plagiarism

This is an individual homework. While you may discuss the ideas and algorithms of this homework with others, at no time should you read, possess, or submit the solution source code of any other person (including people outside this course), or allow anyone else to read or possess your source code. We will detect plagiarism using automated tools and will prosecute all violations to the fullest extent of the university regulations, including failing this course, academic probation, and expulsion from the university.

Description

Create a simple drawing program.

A picture is worth a thousand words. In this assignment, transform those words back into a picture. You'll translate a drawing description into a PostScript file that will produce the specified picture. Your program should read input from stdin and output the PostScript file to stdout.

Input Language

A drawing consists of zero or more picture elements, with each element modified by zero or more transformations. The drawing may also have zero or more parameter settings before any picture element. All numbers should be handled in floating-point. The coordinate (0,0) is the origin and is the lower left corner of the drawing. X-coordinate values increase to the right and y-coordinate values increase to the top.

Create picture elements using the commands below.

(line X0 Y0 X1 Y1)
Draw a line with one endpoint at (X0, Y0) and the second endpoint at (X1, Y1).
(rect X Y W H)
Draw an outline of a rectangle whose lower left corner is at (X,Y), and which has a width of W and height of H. The rectangle should be drawn counter-clockwise starting from the lower left corner.

Create transformations using the commands below.

(translate X Y)
Translate the following picture element by X units along the x-axis, and Y units along the y-axis.
(rotate X)
Rotate the following picture element by X degrees about the origin.

Create drawing parameters using the commands below.

(color R G B)
Set the current color to (R,G,B). The arguments must be numbers between 0 and 1, inclusive. Initially, R = G = B = 0 (i.e. black).
(linewidth W)
Set the current line width to W, which must be a non-negative number. This meaning of this width value is as that of PostScript, meaning you can pass this value directly to PostScript commands. The initial value of the line width is 1.

Zero or more whitespaces are allowed between a parenthesis and the start or end of a command, and between commands. At least one character of whitespace is required to separate arguments within a command.

For example, the following would draw a thick blue square, rotated 45 degrees.

We will test your program with only valid drawing input. In other words, your program need not handle input errors.

PostScript

The output of your program will be a PostScript document. You can view a PostScript file with any PostScript viewer. A popular one is gv available on Linux. A PostScript file has the following form:

%!PS-Adobe-3.1
commands
showpage

The commands of the PostScript language are in postfix notation. The actual PostScript language is free form, meaning operands and operators can be separated by arbitrary whitespace. Your output, however, must mimic the reference program to make your program easier to debug and grade. Each command will start on a newline with operands separated by a single space.

The origin of a PostScript starts at (0,0) in the lower left corner, with x-coordinates increasing to the right and y-coordinates increasing to the top. To draw something, one builds a path, and then strokes it. The PostScript interpreter maintains a graphics state, which for our purposes consists of

You can use the following subset of the PostScript language to construct your PostScript file. In this subset, all operands are decimal numbers (e.g. 0.1, 2.3, 45).

X Y moveto
Set the current point to (X, Y).
X Y lineto
Add a line segment to the current path starting at the current point and going to (X, Y), which becomes the new current point.
stroke
Draw lines with the current line width and color over all the segments in the current path. Clear the current path and undefine the current point.
W setlinewidth
Set the current line width to W. The initial value of the line width is 1.
R G B setrgbcolor
Set the current color to (R, G, B).

To tolerate small errors in floating point computation, the gradebot uses cmpfloat.py (SHA-1: 08ed50ecf4b0356527da25e967b06483876f7f75) to compare the output of your program to that of the reference program. When they are equal, cmpfloat.py outputs nothing.

Hints

Process the input through the following stages:
  1. Tokenzier: reads input, and outputs a sequence of tokens, such as (, ), line, translate, color, etc.
  2. Parser: reads tokens from the tokenizer, and outputs picture elements, transformations, and drawing parameters.
  3. Executor: reads the output from the parser, executes the transformations and sets the drawing parameters, and outputs PostScript.

We provide an incentive against procrastination.

Gradebot instructions

Exit status

Your program must not exit with a non-zero status. This means that if your program calls exit(), the argument must be zero.