代写一个绘图器程序,按照题目要求绘制六个页面。
Requirement
For this assignment, you are to implement three line drawers and a polygon
drawer.
These rendering components should be shown in a program that displays five (or
six) pages. Each of the five required pages consists of four panels, which I
will call panel 1, panel 2, etc., and are as shown in the following diagram:
Each panel should be 300 x 300 pixels, the the white margins and gutters
between panels are all 50 pixels wide or tall. Thus, the total display area is
750 x 750 pixels. Use white and black for the backgrounds, as shown above.
The first three pages will show the output of your line drawers. On each of
these pages, one test is performed using three different renderers (the DDA,
Bresenham’s, and an antialiased line drawer) as follows:
- Panel 1: DDA
- Panel 2: Bresenham’s
- Panel 3: A drawing that alternates between lines with the DDA and Bresenham’s. The first line drawn is with the DDA, the second with Bresenham’s, the third with the DDA, etc.
- Panel 4: An antialiased line renderer
The antialiased line drawer can use any algorithm you choose. The better the
antialiasing, the better your mark. (In other words, a very poor job or a very
good job of antialiasing will get noticed and rewarded appropriately.) The
antialiasing that I discussed in class, with the correct area computation (see
below), is sufficient for getting full marks.
You may code up all eight octants of your line drawers, or you may code up one
and transform the coordinates of the endpoints for the other seven quadrants.
If you do this, then you must apply the opposite transform to the pixel
coordinates that the line drawer produces.
Treat the repetition in the following tests as a design problem (i.e.
eliminate duplication by good design) and not a copy-andpaste problem! Copy-
and-paste results in brittle, buggy code.
Page 1
The test to display on the first page is the “starburst” test. Let c be one of
the four center points of the panel (be consistent across panels). Draw 90
lines from c, each of length approximately 125 pixels, equally spaced in angle
around c. This means one line at 0 degrees, one line at 4 degrees, one at 8
degrees, etc. Parameterize the subroutine you use with c, the length of the
lines, and the number of them to draw. (And any other parameters you need.) Do
not hardwire constants into your codeuse const (C++) or final (java)
quantities declared at class level.
Page 2
The test to display on the second page is the “parallelogram” test. With x
coordinates from left to right in a panel, starting at 0, and y coordinates
from top to bottom in the panel, starting at 0, draw the lines:
(20, 80+p) to (150, 150+p)
For p = 0 to 50.
Also draw the lines:
(160+p, 270) to (240+p, 40)
Again, for p = 0 to 50.
Page 3
The test to display on the third page is the “random” test. Draw 30 random
lines (generate the two endpoints uniformly and independently on the interval
from 0 to 299 in x and in y) with a random color for each line. (Your line
renderers must therefore be capable of handling the color of a line: simply
multiply the color’s R, G, and B by the pixel coverage (which is 1 for DDA and
Bresenham’s) and add this to (1 - pixel’s coverage)*(the color that’s already
in the pixel). Use the same random endpoints and colors for all four panels. I
don’t care how you randomly choose the colors.
Page 4
On the fourth page, display the following four scenes of filled polygons. In
each panel, draw polygons each with a randomly-chosen color. Do no anti-
aliasing.
- The first panel should be like the starburst test, only you are drawing 90 triangles from the center (each with two sides of length approximately 125 pixels, and subtending 4 degrees).
- The second panel should have 162 (= 2 * 81) triangles. Start by spacing out a 10 by 10 array of points as evenly as possible in the panel (with some margin, please!) Then connect these points in the obvious way to form a regular grid of 9 x 9 = 81 squares. In each square, put in the (min x, min y) to (max x, max y) diagonal to form 162 triangles. Render these triangles.
- The third panel is like the second, except that before you create the triangles, you randomly shift each point in x and in y. Shift each point once; do not shift it to a different place for each triangle that uses it. Choose the shift for each coordinate from the range [-12, 12].
- In the fourth panel, generate 20 random triangles (endpoints chosen randomly and uniformly from [0, 299] in both x and y) and render them. They will overlap; this is okay.
Page 5
The fifth page should show the same four scenes of filled polygons as shown on
page four. However, each polygon should have a color of full white (or (1, 1,
- in 0-1 coordinates), and an opacity of some smallish constant, say .14. To
write a pixel x, y with color color and opacity opacity, follow the
pseudocode:
Color oldColor = getPixel(x, y);
Color newColor = opacity * color + (1-opacity) * oldColor
SetPixel(x, y, newColor);
—|—
Here a Color is an (R, G, B) vector. Be sure to multiply by opacity once per
color channel; do not try to multiply opacity by a color packed into a 32-bit
integer (as this can sometimes create “interesting” colored artifacts). Again,
do not store opacity in the “A” or alpha channel.
Page 6 (optional)
Display any number (up to four) of panels that you think highlight the
(positive) attributes of your polygon or line rendering. Do not exceed six
pages.
The program should switch pages at the press of an on-screen GUI button. The
skeleton files provided are already set up to do this.
Include a README file with your project that explains what you did, what you
didn’t do, and what features you are trying to highlight if you include a page
6.
You may not use any graphics software (libraries, etc.) that is not provided
in the skeleton. You may not call OpenGL or Qt or javaFX yourself, for
instance. You may not obtain code from the web or other outside sources, and
you may not share code with any other students.
Note 1
Color is represented by red (R), green (G), and blue (B) values. Each of R, G,
and B is called a color channel.
Abstractly, and oftentimes in the middle of a renderer, the color values are
in the range [0, 1] with 0 being “none” and 1 being “the most intense value of
this color we can make.” Concretely, down in the hardware, most graphics
hardware uses 8 bits for each of these three color values. This leads to some
programs representing each of the colors with an integer value from 0 to 255.
You are expected to be able to quickly switch between thinking of each channel
between 0 and 1, and thinking of each channel between 0 and 255. To convert
from one to the other is simply to multiply or divide by 255.
The libraries that we are using represent the colors with 8 bits per channel.
These three channels are all packed into one 32bit integer with the blue value
(0-255) in the bottom 8 bits, the green in the next lowest 8 bits, and the red
in the next lowest.
This leaves the 8 most significant bits unused. Well, rather than leave them
unused, those 8 bits are often used for an alpha (or opacity) value, which
represents how much of the pixel in question is covered by the object in that
pixel. Since one hexadecimal digit represents 4 bits, we can think of the
color being represented (little-endian) as AARRGGBB which means two digits of
alpha, two digits of red, two digits of green, and two digits of blue (in that
order, from most significant bit to least significant bit). For example, a
color ff104077 means that the alpha value is ff 16 (= 25510), the red value is
1016 (= 1610), the green value is 4016 (= 6410), and the blue value is 7716 =
(11910).
To pack and unpack R, G, and B values from a color represented this way, some
bit manipulation is necessary. For instance (here I’m using the prefix 0x for
hexadecimal numbers).
The bitwise-and operations in the above can be omitted if you know for sure
that r, g, and b are integers between 0 and 255, inclusive. The above
calculation puts 255 (i.e., 0xff) into the alpha bits. You should do this for
all of your colors. One of the libraries I have provided requires it.
The above statement constructs an ARGB color from r, g, and b. Going the other
way also requires bit-shifts and masking, but I’ll leave you to determine how
to do that.
Note 2
The antialiasing I discussed in class requires that you find the area inside
the intersection of a slab with a circle, based on the distance from the edge
of the slab to the center of the circle. In other words, if you know d in the
following diagram, you must find the area of the lightly-shaded part.
Popular choices for r, the radius of the circle representing the pixel, are
0.5 and sqrt(2). (These give cicles barely contained in, and barely
containing, the square for the pixel.)
The area of the full circle is r2. Thus the fraction of the pixel that is
covered is (the area of the lightly-shaded part above) / r2.
The white area in the circle can be divided into two parts: a triangle and a
“pie wedge”. See the diagram below, where everything has been rotated so that
the segment of distance d is vertical.