Last week, we wrote a program to determine if a point was inside the bounding box of a convex polygon. If you remember, we defined a polygon as a list of (x,y) coordinates which represent the verteces of the polygon. You were given the code to read a polygon file, and functions to get information about the polygon.
This week, we will complete the job... determine if the point specified in the program's arguments are actually inside the polygon itself. To illustrate this question, consider the following figure, which shows a triange and a point that is inside the bounding box of that triangle, but is not inside the perimeter of the triangle itself.
The question is, how do we tell the computer how to figure out if the point is inside the perimeter or not?
There are different ways to answer this question, but one easy way to think about this problem is to think of a vertical line that goes through the point in question, like the red line in the following figure.
Notice that the red line intersects exactly two line segments that make up the perimeter of the polygon. If we can determine the (x,y) coordinates of the intersection of this line with the perimeter, that will give us the (x,y) coordinates of the two orange/brown dots in the figure above; namely (1,0) and (1,3.6). Then we can check whether our point, (1,3.9) has a y coordinate between 0 and 3.6. If it does, the point is inside the polygon. If not, the point is outside the polygon. In this case, 3.9 is greater than the higher itersection coordinate of 3.6, so the point is in fact, outside of the triangle.
It turns out that since we are dealing with convex polygons, we can draw a vertical line from a point inside the bounding box of the polygon, and be guaranteed that our line crosses either a segment of the polygon boundary or a vertex of the polygon exactly two times - one low and one high.
We can enumerate the line segments of a polygon if we know its verteces by simply taking two adjaced pairs of vertexes. (Note that the last one is also paired with the first one.) Therefore, if we have verteces from 0 to (n-1), the list of line segments in the perimeter is simply
|vertex 0||vertex 1|
|vertex 1||vertex 2|
|vertex n-2||vertex n-1|
|vertex n-1||vertex 0|
It's pretty simple to see if our vertical line crosses a particular segment. Just find the lowest X coordinate of the end-points of the line segment, and if our vertical line X is greater than the lower X, but less than the higher X, then our vertical line crosses that segment.
Once we know that our vertical line crosses a particular segment, we can perform iterpolation to determine the Y coordinate of the intersection of our vertical line with the segment. To do so, we can use the following formula, where the line segment goes from (x1,y1) to (x2,y2), and the vertical line is at xq
y_intersect = y1 + (xq-x1) * (y2-y1)/(x2-x1)
If our vertical line goes through a vertex, then the x coordinate of the vertex must match the x coordinate of the vertical line, and the y coodinate of the intersection is simply the y coordinate of that vertex.
You may either continue using the code you created from last week's lab, or download the Professor's solution to last week's lab as a starting point. (If you didn't finish last week's lab, you may want to just download.) If you want to download the Professor's solution, grab lab5.tar.gz and move it into you home directory. Use the command tar -xvzf lab5.tar.gz. This will unpack the tar file and make a new lab5 subdirectory.
The polygon functions are the same as last week, but I've included the documentation here for reference.
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
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:
verteces: 3 (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.
The Makefile is the same as last week as well...
The Makefile file in the lab5 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:
The file contains.c in the lab5 directory contains the code we used last week to read a polygon definition and determine if a point is inside the boundig box of the polygon. 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 already performs the following actions...
Your job today is to extend the main function to determine if a point that is inside the bounding box is also inside the polygon itself. In order to do that, you will need to do the following...
Here are some hints that will help you write this code...
if (i==verteces(p)-1) to_i=0; else to_i=i+1;
Good luck and happy coding!
Download and edit the following file: lab5_report.txt. Then submit your editted file on Blackboard in the Lab_05 report area.