CSCI 1320 - Assignment #7/8



Your bag of tricks for programming has now been improved so that it includes the use of files and hopefully your understanding of pointers and their usage has been improved as well. These problems will require general problem solving, but they will integrate parts of file usage in them as well. They are fairly large in scope so you should certainly get started on them early. If you have problems let me know. The only way I know if people are struggling and something needs to be adjusted is if I hear from students.

After each problem description I've given you sample input and output files. If you run the program with the input I give you should get something pretty much identical to my output. Make sure to look at these files and make sure your program will take one as input and produce something very similar to the other.

As a side note, be sure to save the code from all the programs you do. It is quite possible that later in the semester other assignments will include things that overlap with them and your code will be reusable.

To turn in this assignment just send the code in an e-mail to mlewis@cs.trinity.edu. You can do this with the command "mail mlewis@cs.trinity.edu < assn4.c" if assn4.c is the name of your source file.

Freeform Problem:

At the request of one of your classmates, this problem is one that you come up with all on your own. It needs to involve the use of files as well as other computational resources that we have talked about. You will need to write an English description of exactly what problem you are solving at the top of your code. You should probably pass it by me to make sure it is sufficient for this assignment. That descritpion needs to include not only the description of the problem you are solving, but also the type of inputs and outputs. Basically, it needs to be something like my normal assignment descriptions with enough information that I can determine if your program actually does it. You also need to provide a sample input file and a sample output file. If you pick this option I will be less able to help you with problems because I generally won't know what you are trying to do. The better the description you provide to me the more likely I'll be to be able to assist you. The problem you do will need to require a significant amount of code to be approved. Basically, it needs to be of roughly the same scope as the other problems on this assignment.

Graphics Problem:

For this problem you will be bringing together components of the last two graphics assignments to make something a bit different. You are going to use parts of your raster drawing program to help "render" a scene in 3-D. You are going to use a very simple rendering model to do it so that things aren't too complex. A realy rendering model would have things look smaller as they move away, that is a perspective view. You aren't going to do that. You'll assume that your lines of sight are parallel which makes things a lot easier.

What you will build is something a lot like assignment #5, but now the image will be in 3-D instead of 2-D and you will have some lighting from assignment #4. In this assignment there are two things that you can add to what you are drawing, triangles and light sources. You should be able to handle at least 3 lights and 20 triangles, but you can write your code to handle more than that if you want. When you start the program, you won't have any of either. You will have functions that read lights and triangles from a file as well as a function to write such a file. Your code will also have the simplePrint and printRaster functions you wrote before. The first one will still print to screen just so you can see roughly what it looks like. The second though should write out to file. The user should be prompted for a file name. Make sure your print raster prints a first line with the width and height that you use on it. I left that out of my earlier sample output. I'll be providing you a way that you can view those images in color if you want to. So the functions in your program are the following

  1. Add light
  2. Add triangle
  3. Read geometry file
  4. Write geometry file
  5. Simple print
  6. Print raster to file
  7. Quit

The lights and triangles will have x, y, and z coorodinates. x and y will be just like they were in the earlier program. z will be distance from the viewer. When you draw a triangle (you get to figure out how to do this), you will ignore the z component for where it is on screen. That will only matter for determining the lighting on it. When the user adds a triangle, that should be drawn on the raster with the current lights. When a light is added all the triangles will need to be redrawn so that they use all the lights. Each triangle and light should also have a color specified for it. To determine the color to draw each triangle, you will add up the colors it would be for each light. To determine that, you will use what you did for assignment #4 to get the intensity of the light. One alteration you should make here is that using the pixels distances for the 1/r^2 decrease in intensity causes things to be very dark so instead, take the distance you find and divide it by WIDTH to get a more appropriately scaled value. If we say that value is frac, then the color from that light will be a rgb where each component is determined as follows. r_drawn=frac*r_tri*r_light/255. The reason you divide at the end is because the components aren't between 0 and 1, but between 0 and 255 so to get a value in that same range you multiple the two and divide by 255.

The only geometric shape you are drawing for this is a triangle. Of course, any polygon can be built out of triangles. Drawing triangles isn't a simple task though. My hint to you is that you should figure out where you would draw lines between the points, then for each row in the raster, fill all the pixels between those. Then you only have to worry about the math for drawing a straight line.

The option to read in a geometry file should ask for a file name, clear your current geometry, then read in a file that has new lights and triangles. The format of the file has lines that start with an 'L' for a light or a 'T' for a triangle. You can read a string for that and just examine the first character. Following that will be either 3 numbers for a light or 9 numbers for a triangle. After this is called, the raster needs to be cleared and all the new triangles should be drawn. Note that the reading function will have to check for feof to know when it is done. Writing a geometry file should ask for a file name then write the above format to it.

If you want to do this option and you didn't do the graphics options on assignments #4 or #5, let me know and I can e-mail you code for those.

To view your rasters graphically download this file to the directory you are doing your assignment in. To use it you will need to have a recent version of java installed. The ones on the mab machines should work well. At the command prompt, type "java -cp RasterViewer.jar RasterViewer raster.txt". The raster .txt can be replaced with whatever file name you are using for your output file.

input : output : orginal format geometry file : geometry file : raster file : executable

Baby Mathematica:

For this problem you will use your equation parser from assignment #6 to build a little program that can be used to do some simple function evaluation. You will then give it the ability to output text files that are plots of your functions and can be plotted up using gnuplot. You should also give it the ability to read files that have functions defined in them.

You can define 3 functions: f, g, and h. They are all functions of a single variable x. They are definied in terms of numbers, x, and the other functions. You only have to have the four basic operators (+, -, *, /), but you can add extra ones if you want extra credit. If you do this, there needs to be a big comment at the top of the code telling me what you did so I can try it and give you the extra credit.

Options:

This program won't use a numeric menu. Instead, it will be more command line like, similar to what we wrote in class for the text editor. You can read in a string for the command and check the first character to see what they picked. Use the strings shown above after each option. See the sample input file for an idea of how this would work.

The define option lets the user define a function. The format for that should look something like this "define f=x*x" or "def g=f(x-1)+2". After the keyword (beginning with 'd') you have the function letter ('f', 'g', or 'h'), followed by an equals sign and the string for the function. I recommend that you store the functions in an array of 3 strings.

The evaluate option allows the user to evalutate one of the functions at a particular value. So they could type in something like "evaluate f(4)" or "eval h(5+3)". To get this to work, you will add a bit to your parse function from assignment #6. Earlier it needed three arguments, a string for the equation and two ints for start and end. You will need to add two more arguments to that. The first is a double for the value of x. The second is a 2D array of chars that holds the three strings defining f, g, and h. You need that because the functions can call other functions. The second example in this paragraph and the second one in the define paragraph might scare you a bit, but don't let them. Instead think about the power of your parse function and how you can use that to make evaluating those expressions easier.

In addition to adding the two extra arguments to parse, you will also add some extra possible cases in the function. Where you earlier just called atof, now you will need to check for 3 possibilities and all can be easily distinguished by the value of str[start] (or whatever name you use for the string argument. If it is an 'x' then you need to return the value that was passed in for x. If it begins with an f, g, or h, you need to parse the argument and then use that as the x value for a call to parse on the proper function definition string.

The view option just prints out the formulas that have been entered in case you forget them.

The read and write options are fairly straight forward. You need to write some code that will read in definitions for your three functions from a file or write out to it. In both cases, the use needs to specify a file name. For example "read forms.txt" or "w cooleqs.txt". You can choose your own format for this as long as it works for reading and writing when you don't have all of them defined. Consider that using something close to what I have asked you to do for define might be helpful because you could call a single function for define and for the read function.

The last option is to plot. You aren't going to write the graphics code, but you will write a file that has x and y values in it so that it can be plotted with gnuplot. See the description of the physics problem in assignment #5 for information on that. For this to work, they need to specify which function, a minimum x, a maximum x, and a file name. Your code should evaluate the function at 100 evenly spaced points between the min and max and write 100 lines where each has the x value followed by the y value on it. For example, they might give the command "plot f(x) 2.3 6.7 funcPlot.txt".

If you choose this option you might want to look at the strcmp and strcpy functions in string.h using the man pages or your text. You can certainly write those functions yourself, but calling those will make your code shorter.

Just as a side note, I think this might be the most exciting problem of all the ones I've given so far this year (for me). It can really show you the power of a simple recursive algorithm and once it is done, you will have written a program that is far more powerful than what most people in a PAD1 class would even dream of doing. That doesn't mean it is harder though, just more powerful.

If you want to do this option and you didn't do the symbolic algebra options on assignment #5, let me know and I can e-mail you code for it, mainly the parse function.

input file : output file : function file : plot file : plot2 file : executable

Grade Book:

For this option you will write a program that I could use to keep track of grades for the class. It needs to give me the following abilities:

  1. Add student names
  2. Enter a grade for everyone in the class for an assignment, quiz, test, or class participation
  3. Enter a single grade for one student
  4. Prints grades and average for one student
  5. Print class average and standard deviation for any grade
  6. Write gradebook to a file
  7. Read gradebook from a file
  8. Quit

The way that you should do this is to keep 2D arrays with all the names and grades. You can decide exactly how you want to do this. It could be done with one big array for all grades or separate arrays for assignment, quizzes, tests, and class participation. Whatever you choose, the whole program needs to work that way. Grade values that are negative imply that a grade has not yet been entered for that and it should be ignored in the calculation of averages.

The first option will add a new student to the class. It asks for the students name. You can assume that the names given won't have spaces in them. Your program doesn't have to handle more than 30 students and names can't be more than 40 characters long. After the name is entered you should set all the grades for that student to -1.

For the second option, the user specifies which grade they are giving values for (ex. "a 2" or "q 3", you can read in the a, t, q, or c as a string and only look at the first character of that string). It will then print the name of each student in the class and wait for the user to input that student's grade. A -1 can be input to say that that students grade hasn't been determined yet.

In the third option the user is prompted both for what grade and who to give it to. If the name entered isn't in the class an error message should be given. You can use strcmp or write your own function to compare the strings to figure out the index of a given student. Once the student has been found the user can input a grade for them.

The fourth option also has to get a specific student name and find that student. It then prints all the assignment grades and their average, the quiz grades and their average (with the smallest valid grade dropped, be careful here), the tests and their average, the class participation, and the final average for the class. Fields that are negative should not be factored into the averages at all.

For the fifth option the user tell you what grade they are interested in and the program gives the class average and standard deviation for that one. The standard deviation is the square root of the sum of the squares of the difference between each grade and the average.

The sixth and seventh options simply write out the entire grade book to a specified file or load on in from there. This way I could entere some grades, write it to disk, then quite and when I come back later I could load it back in and start adding more grades. How you choose to write this file is up to you, it just has to work.

input file : output file : gradebook : executable