CS-211 Fall 2015 Lab 4 C Control Part I
There are many engineering applications which have a graphical background. We will investigate one such application in today's lab. Specifically, given a convex two dimensional polygon, and a point in two dimentional space, is the point inside the polygon, or outside? This is a relatively simple application, but allows us to get practice using C control structures such as if/then/else statements, and loops.
Coding the complete application would take more time than we have in one lab period, so this lab is broken up into two parts. In today's lab, we will find the bounding box of the polygon, and check to see if our point is inside the bounding box of the rectangle or not. The bounding box of a polygon is a rectangle that completely contains the polygon. It's pretty simple to find the bounding box... just take the minimum and maximum x and y coordinates of all the vertices of the polygon -- that gives you the lower left and upper right corners of the bounding box. Then, to see if the point is inside the bounding box, we check to see if its x and y coordinates are greater than the lower left corener, and less than the upper right corner.
For this lab, we will represent polygons using the list of (x,y) coordinates of the verteces of the polygon. Polygon definitions will be contained in text files that will be provided for you, and you will also be provided with functions to read a polygon file into memory, as well as to get information about polygons, like the number of verteces, or the value of the x or y coordinate of a specific vertex.
After you have logged on to one of the Linux Lab machines, open a terminal window, download lab4.tar.gz and move it into you home directory. Use the command tar -xvzf lab4.tar.gz. This will unpack the tar file and make a new lab4 subdirectory. Make the lab4 directory your current directory, and list the files in the lab4 directory. There should be 7 files... one called Makefile, three program files called contains.c, poly.c and poly.h, and three example polygon files called rectangle.txt, triangle.txt, and diamond.txt
The Polygon Functions
The two C files called poly.h and poly.c contain the declarations and definitions for the functions to handle polygons. You will not need to change anything in these files, but you do need to understand how to call these functions. Feel free to look at this code, but there are some things in these files, like C structures and typedefs, which we haven't studied yet... so don't worry if you can't understand everything.
The poly.h file contains everything you need to invoke the polygon functions. Therefore, we #include "poly.h" in our main C file. The function definitions for these files is in the poly.c file. But the important thing is how these functions work.
First, we need to talk about the polygon data type defined in poly.h. We can declare a variable as a polygon, just like declaring a variable as an integer, by using polygon p;. After such a declaration, we can use the variable "p" to hold a polygon. The "makePolygon" function returns a value of the polygon type, so we can do something like p=makePolygon(x). Several other polygon functions require arguments which have a polygon type. We can provide values by using a variable of type polygon, such as: int n=verteces(p);.
Now we can describe te functions themselves
- polygon makePolygon(char *fromFile) - The makePolygon function takes a string which represents the name of a polygon file (in the current directory). The makePolygon function reads the file associated with this name, and returns a polygon value that can then be used in the rest of the polygon functions. If any problems occur, such as the file does not exist, or the file does not contain information about a polygon as expected, then the makePolygon function will write a message (to stderr) and cause the program to exit. In other words, if makePolygon fails, it will never return to the caller, so you don't need to check the return value.
- void printPolygon(polygon p) - This function will print the number of verteces, and the (x,y) coordinates associated with those verteces for polygon p to the standard output stream.
- void deletePolygon(polygon p) - This function will remove all the information associated with polygon p from memory. You should invoke deletePolygon for every polygon created by the makePolygon function.
- int verteces(polygon p) - Returns the number of (x,y) coordinates that make up the verteces of the polygon p.
- float vertexX(polygon p,int index) - Returns the x coordiante value of the indexth vertex in polygon p. The value for index should be between 0 and (verteces(p)-1).
- float vertexY(polygon p,int index) - Returns the y coordiante value of the indexth vertex in polygon p. The value for index should be between 0 and (verteces(p)-1).
For instance, if I code polygon p=makePolygon("triangle.txt");, then when I invoke printPolygon(p); then the following will get printed to standard output:
(0.000000,0.000000) (10.000000,0.000000) (0.000000,4.000000)
Also, the value of verteces(p) will be 3; the value of vertexX(p,1) will be 10.0; and the value of vertexY(p,1) will be 0.0. I should also call deletePolygon(p); before I exit.
Using The Makefile
The Makefile file in the lab4 directory contains the recipes to build the C program associated with whose "main" function is in contains.c. To build the contains executable, use the make contains.
The Makefile file contains several other "targets" which allow you to do other things using the make command. The following targets are supported:
- make contains - Makes the contains executable if you have changed the source code.
- make test - Makes the contains executable if you have changed the source code, and then runs that executable on three test cases.
- make clean - Removes the contains executable.
Writing the Code for Main
The file contains.c in the lab4 directory contains the beginning of a program to read a polygon definition and determine if a point is inside that polygon. Your job today is to write the main function to complete this job. You can assume that the first parameter passed into your program (after the name of the program itself) is the name of a polygon definition file, the second parameter is an x coordinate, and the third parameter is a y coordinate. The second and third parameters make up the coordinate of the point you want to check.
Your main function should perform the following actions...
- Check to make sure three parameters have been specified by your caller. If not, write an error message and quit.
- Invoke the makePolygon function on the first parameter.
- Print the resulting polygon information.
- Convert the second and third arguments to floating point values.
- Compute the x and y coordinates of the lower left corner of the bounding box and the upper right corner of the bounding box.
- Print a message that tells the user what the lower left and upper right corners of the bounding box are.
- Check and see if the (x,y) coordinate specified as the second and third parameters are inside the bounding box of the polygon.
- Print a message to your caller that specifies the (x,y) coordinate of the user specified point, and tells whether that point is or is not contained in the bounding box of the polygon.
Here are some hints that will help you write this code...
- There are two variables passed into your main function that have information about the parameters to your command. The first, most often specified as int argc, contains the count of the number of arguments (including the command name itself) specified on the command line. The second, usually called char **argv, is an array that contains the values of those arguments. argv is always the name of the command itself. The first user specifed argument string is in argv, the second in argv, and so on, all the way up to argv[argc-1].
- Code and test the capability to check the number of parameters first. Then code and test reading a polygon file and printing the polygon. Once this is working, add the capability to find and print the bounding box and test that. Finally, add the check to see if the user coordinate falls within the bounding box, and test that code. If you test in small chunks like this, it's easier to isolate where you made a mistake if you made one.
- You can convert a string from ASCII to floating point using the standard library atof function. For example, float pi=atof("3.1414"); reads the ASCII characters '3', '.', '1', '4', '1', '4', x00, and creates the floating point number 3.1414 from that string. The atof function is declared in the stdlib.h system header file, and since the contains.c file already has #include < stdlib.h> , then you can use the atof function.
- To find the minimum of a list of numbers, the easiest way to do it is to set the minimum to the first number in the list, and then see if any of the other numbers in the list are less than that minimum. If so, make the minimum that lesser number, and keep checking through the list. When you get to the end of the list, you will have found the lowest number in the list. The same idea can be used to find the maximum number in a list.
- Use printf to print out messages. To print a specific (x,y) coordinate, for instance, code something like printf("Point is (%f,%f)\n",x,y); where x and y are variables of type float.
- Keep track of your results from make test after you debugged your program... the lab report asks about these results.
- Don't delete the lab4 directory when you are done. We will expand on this code in next week's lab.
Good luck and happy coding!
Download and edit the following file: lab4_report.txt. Then submit your editted file on Blackboard in the Lab_04 report area.