CSc 220 Assignment 2

The Plot Thickens

Assigned
Due

Aug 29
90 pts
Sep 12

You are to write a C++ program to read in several numerical parameters describing a quadratic function and plot the function. The plot will be a simple text-oriented graph, turned sideways from the usual: the x axis will be vertical and y horizontal.

Input

The input consists of the following numbers:
  1. The coefficients A, B, and C of the equation
    y=Ax2+Bx+C
    These are floating point (float or double) quantities which should be read as double.
  2. The range of x values to plot, two floating point quantities giving the low and high x bound: startx and endx.
  3. The range of y values to plot, also floating point lower and upper bounds, starty and endy.
  4. The integer number of x values to plot, nx. This is also the number of printed lines which will appear on the main part of the graph. The first and last x values printed (the top and bottom lines of your plot) will be the first and last values in the x range, and nx2 evenly-spaced values will be given between them. (The x range will be divided into nx1 equal steps.)
  5. The number nxsep of x steps separating numbers printed on the x axis. Also an integer.

Note that the input numbers must appear in the correct order, but their arrangement on lines is indifferent. The C++ input package will read them this way.

You may assume that the input is correct, but it is possible to give startx, endx, starty and endy values such that no curve appears in the displayed area.

Output

Print the quadratic equation, followed by a text-based graph of it. Its (horizontal) y axis takes up 70 characters of space, and its (vertical) x axis uses nx lines. Place a 70-character line made of dashes above and below the graph, with a statement of the y value range to which it corresponds above the top and below the bottom line. At the left, make a vertical line of | characters with, and place a scale of x values to the left. The number of these lines is the nx input. Display the associated x value on the first line, then on each nxstepth line thereafer.

Inside the area defined by the axes, place one * on each line for which its y value is in range. Place it correctly according to the y value.

The y axis markings are very basic. Feel free to create something nicer, but don't do it until you have the required functions working.

Notes

Each line of the output will represent one x value. The first one being startx, and the others being spaced at increments of (endxstartx)÷(nx1). Loop through these values. For each one, compute the corresponding y value. If it is within the range starty to endy, compute its distance beyond starty, and scale to the distance of 70 characters. Print the *, with the spaces to locate it correctly.

Examples

tom@laptop:~/courses/cs220/asst$ ./plotter Enter the polynomial coefficients: -1.5 18.0 -16.5 Enter the range of x values: 0.0 10.0 Enter the range of y values: -5.0 40.0 Enter the number of x values, and display step: 41 5 y = -1.50x^2 + 18.00x + -16.50 y = -5.00 - 40.00 ---------------------------------------------------------------------- 0.00 | | | | * | * 1.25 | * | * | * | * | * 2.50 | * | * | * | * | * 3.75 | * | * | * | * | * 5.00 | * | * | * | * | * 6.25 | * | * | * | * | * 7.50 | * | * | * | * | * 8.75 | * | * | * | * | * 10.00 | * ---------------------------------------------------------------------- y = -5.00 - 40.00 tom@laptop:~/courses/cs220/asst$ ./plotter Enter the polynomial coefficients: 0.25 3.0 5.0 Enter the range of x values: -8.0 2.0 Enter the range of y values: -5.0 10.0 Enter the number of x values, and display step: 41 4 y = 0.25x^2 + 3.00x + 5.00 y = -5.00 - 10.00 ---------------------------------------------------------------------- -8.00 | * | * | * | * -7.00 | * | * | * | * -6.00 | * | * | * | * -5.00 | * | * | * | * -4.00 | * | * | * | * -3.00 | * | * | * | * -2.00 | * | * | * | * -1.00 | * | * | * | * 0.00 | * | * | * | * 1.00 | * | * | | 2.00 | ---------------------------------------------------------------------- y = -5.00 - 10.00

Some Hints

Of course, start by reading the input values into appropriate variables. Then print the opening y value specification and the top line.

To print the graph itself, you want a loop that will run for nx iterations. Each iteration will print one line of the output. For that to work, you will need to know the correct x value for each iteration. Create a variable to hold the current x value, initialize it before the main loop to startx. For each iteration, you will increment it by the amount x changes from line to line. That quantity is to the total amount that x changes divided by the number of between-line increments, or (endxstartx)÷(nx1). Compute this increment before the loop starts and place it into a variable with a descriptive name. Then, add it to your current x at the bottom of each iteration.

xstartx dx ← (endxstartx) / (nx − 1) repeat nx times: y ← the value of the polynomial at x Place a * on the line at the position corresponding to y Space onward and print the | or the x value as required. xx + dx

Now, within each iteration you will have the correct value for x. Compute the corresponding value of y from the formula

y=Ax2+Bx+C
Once you have y, you have to put the * at the right place in the line. If the computed y value falls outside the range starty to endy, then there is no * at all; just print 70 blanks. Otherwise, you need to figure out where the * needs to go. This is a matter of proportion. Consider the horizontal positions to be numbered 0 to 69, and suppose, for example starty and endy are -10 and 200 respectively. Further, suppose you must plot the computed y value of 127.3.
0
45
69
*
-10
127.3
200
The distance from the left side to the point is 127.310=137.3. The whole distance across is 20010=210. Therefore, the mark is 137.3÷210=0.6538 (about 65%) of the way across the page. Since the whole distance in characters is 69, the y position in characters is 0.6538×69=45.1129, which you round to 45. Formally,
cy=69
ystarty

endystarty

Once you know the y position in characters (cy), you need to create a line of mostly spaces with the * correctly positioned. Print cy spaces, print *, then print enough spaces to fill the line to 70 characters. Then print a | or a + followed by the current x value, as required. Now you can print endl.

To round a double to an integer, you may use the library round function, x = round(x). To use this, you must #include the header cmath. Alternatively, if you know the value is positive, you can round it by simply adding 0.5 then assigning it to an integer (discarding the fractional part). You might think about why that works.

When you print the value of the x at the left, you should control the format of the value printed. A simple way to do this might be:
#include <iomanip> ... cout << setw(6) << setprecision(2) << x;
Here, the iomanip header acquires the setw and setprecision. The output number is padded with spaces on the left to the width 6, and the number of decimal places is 2. Use appropriate figures, of course. This allows you to print the number in a controlled amount of space to keep from damaging the spacing.

Submission

When your program works, submit over the web here.