In this assignment you’ll draw 2D shapes by filling in individual pixels.
You need to write every method you submit yourself. You cannot use other people’s code or find the method in an existing library. For example, you should not use Java’s Graphics
class, PIL’s ImageDraw
module, the CImg draw_
* methods, the Bitmap Draw
* methods, etc.
You are welcome to seek conceptual help from any source, but cite it in a comment if you get it from something other than a TA, the instructor, or class-assigned readings. You may only get coding help from the instructor or TAs.
Half of the points are for completing the required portions. You may add as many points as you wish on optional portions. Points in excess of 100% will carry over to other homework assignments.
All the example images in this writeup are hyperlinks to the input file that generated them. On some older browsers these hyperlinks might interact poorly with the mathematical formula rendering; if you have trouble accessing the files, please let the instructor know.
The same as HW0: your program will read a file from the command line and create a PNG file. The basic structure of the input file (lines with keywords and arguments, skipping unknown keywords, etc) remain unchanged.
The required part is worth 50%
For this homework, when you see a vertex description line (xyc
, xyrgb
, or the optional xyrgba
) you don’t draw it; you store it in an ordered list. Most other commands will refer to earlier vertices in a one-indexed way: 1 is the first vertex listed, −1 the most recent one listed. So, for example, in the following input file
png 20 30 hw1demo.png
xyc 2 3 #ff0000
xyrgb 10 29 0 127 0
xyrgb 19 9 0 0 255
trig 1 -1 2
xyc 0 29 #770099
trig 1 -2 -1
the first trig
has vertices (in order) of (2, 3), (19, 9), and (10, 29); the second trig
has (2, 3), (19, 9), and (0, 29).
Vertex indices will always refer to vertices earlier in the file. Vertex coordinates (x and y) may be decimal numbers. Colors will still be integers. You no longer need to support xy
; all coordinates will have colors specified in this assignment.
Draw an 8-connected line of the given color using the DDA algorithm between the two vertices given. Ignore the colors of the vertices.
If the line extends farther in x than in y, DDA steps in x. At any given integer x, the line itself may have a non-integer y, but pixels have integer coordinates. Draw the pixel at the integer y of ⌊y + 0.5⌋.
The same logic applies to lines that extend farther in y than in x and their pixel’s x coordinates.
In the case where you start or end with an integer endpoint, include the smaller value but not the larger.1 For example, if stepping between 20 and 10, include 10 but not 20. This rule prevents adjacent lines with a shared endpoint from both drawing that endpoint; for example, if one line goes from 5 to 10 and another from 10 to 15, only the second will draw pixel 10.
Fill a triangle between the given vertices, linearly interpolating the vertex colors as you go. Use a DDA-based scanline algorithm2: DDA step in y along the edges, then DDA step in x between these points.3
Fill a vertex if its coordinates are inside the triangle, (e.g., pixel (3, 4) is inside (2.9, 4), (3.1, 4.1), (3.1, 3.9)) on the left (small x) edge of the triangle, or on a perfectly horizontal top (small y) edge. Do not fill it otherwise.
This coloring style is called Gouraud shading, hence the g
in the keyword.
trig
but uses the specified flat color, not linearly-iterpolated color
Accept points xyrgba
with a 4th color being an alpha (opacity) channel, and use that alpha in Gouraud shading (lineg and trig).
And/or, add lineca
and trica
that act like linec
and tric
but take an extra 2 hex digits in the color code, which are alpha (opacity). So #ff0000ff
is opaque red, #0000ff07
is mostly transparent blue, etc.
Use the over operator discussed on Wikipedia: C_{o}={\frac {\alpha_{a}}{\alpha_{o}}}C_{a}+\left(1-{\frac {\alpha _{a}}{\alpha _{o}}}\right)C_{b}.
Fill the given n-vertex polygon using the even-odd rule
, as described in the SVG Spec.
Usually this is best done by going one scanline at a time, finding all of the edges that cross it, and then filling between pairs. Don’t forget to count vertexes that fall exactly on a scanline appropriately.
Fill the given n-vertex polygon using the non-zero rule
, as described in the SVG Spec.
Usually this is best done by going one scanline at a time, finding all of the edges that cross it, and then filling between pairs. Don’t forget to count vertexes that fall exactly on a scanline appropriately.
buttmode in the SVG spec).
Draw a uniform cubic B-spline with the given control points.
A B-spline is just a tool for defining Bezier curves. The B-Spline control points p_1, p_2, p_3, p_4 define the cubic Bezier control points (p_1 + 4p_2 + p_3)\over 6, (2p_2 + p_3) \over 3, (p_2+2p_3) \over 3, (p_2 + 4p_3 + p_4) \over 6.
Feel free to add your own elements to the input set. Submit an input file named additional_.txt
where _
is replaced by some number for each additional element you add. The input file should include a line beginning description
that describes the new element. Points will be added at instructor discretion.
The smaller-but-not-larger rule is the correct rule for triangles, but not always sufficient for lines. However, the correct rule for lines depends on what other lines you want to connect it to, which our input format does not provide, so we’ll use the smaller-but-not-larger rule for lines as well as triangles in this assignment↩︎
Bresenham is fine too, being a mixed-number version of DDA↩︎
If done properly, the (x,y) along the edges will have integer y but non-integer x; the (x,y) of each pixel will both be integers; and you won’t round any x or y coordinates.↩︎