COS 226 Programming Assignment 7

Point location

Write a program to solve the point location problem among line arrangements in the plane. Your program should build a data structure from a set of lines that allows it to, when given a pair of points, quickly determine whether any of the lines goes between the two points. The brute-force solution to this problem is to test that both points are on the same side of each of the N lines. The point of this assignment is to build a data structure that cuts the number of lines to be tested down to be proportional to log N.

For simplicity, you may assume that all the lines cross the unit square (where both coordinates are between 0 and 1), and that you only have to work with points and line segments in that region. Use the following input format:

5
 0.00  0.12 0.23  1.00
 1.00  0.41 0.00  0.52
 1.00  0.20 0.30  1.00
 0.00  0.40 0.10  0.00
 1.00  0.35 0.10  1.00
 
 0.25 0.8 0.60 0.5 
 0.95 0.1 0.11 0.5
The input begins with an integer N, then N lines, each defined by four floats that give the endpoints of the line segments. Since they represent intersections with the edge of the unit square, each line segment endpoint coordinate is 0 or 1 in at least one coordinate. Following the N lines is a sequence of pairs of points (also four floats per input line). You can find the above and larger examples in the files tiny, medium, large, and giant.

An arrangement is the planar subdivison defined by the lines. A diagram of the arrangment for the set of lines given above is given below. Every point in the unit square falls into some region; every region is bounded by some subset of the line segments. Your task is to be able to determine quickly whether or not two given input points fall into the same region or not.

You are welcome to try any method you would like to solve this problem. One approach that you may want to try is based on building a binary tree with internal nodes corresponding to lines and external nodes corresponding to regions in the plane, as shown in the example. This is similar to a 2D tree. A search in this tree involves comparing a point against the line at the root, then going left if it is on one side and right if it is on the other side. If the search for two points ends up at the same external node, they must be in the same region. There are at most N*N regions and one external node corresponding to each region, so we expect that the time should be proportional to log N*N = 2 log N for random data. Figuring out how to build this tree for arbitrary lines is your main task for this assignment.

You probably will want to begin by implementing and debugging a driver that can read the input data and display it graphically. You may use any graphic environment you want. A Postscript example (use gs or lpr to view it) example is available online. It will be very helpful for you to be able to see the lines when it comes to working on the main program. You will also need some geometry primitives: a test whether a point is on one side of a line or the other, and a routine to compute the intersection point of two lines. The former is essentially the {\tt ccw} program from the book and lecture notes; the latter requires some high-school geometry, coupled with some computer-science considerations having to do with precision and degenerate cases (lines consisting of a single point, parallel lines, and so forth).

You do not have to worry about handling all possible degenerate cases, but you shouldn't completely ignore them, either. Certainly you will want to get your program working on straightforward input before worrying about degenerate examples such as three lines intersecting in a point, or where precision in the calculation affects a decision. In your design, you should be cognizant of places where your program might be exposed to trouble for a degenerate case, whether or not you get around to fixing it up. In your readme file, be sure to explain which kinds of input you have thought about.

As usual, first get your program running for the tiny sample data set with five lines, and move to the larger files as your program can handle them. Instrument your program to count number of nodes and the average path length (external path length divided by number of nodes) for the trees that you construct. Include a table with these numbers, and a discussion of how they grow, in your writeup.

Extra Credit. Convert your program to print out the all sets of three or more points that are collinear in a set of N points. This is not as hard as it looks: by duality this is equivalent to finding the places where three or more of a set of N lines intersect. Take a point (a, b) to correspond to the line ax + by = 1.

Due: 11:59PM Thursday, April 9.