Handouts: Handout on Bentley-Ottmann sweep; Handout on Kirkpatrick's algorithm (on web)
5/5/08: Intersection problems: Bentley-Ottman sweep

Some final remarks on duality/arrangments: (1) degeneracy testing; (2) connection between arrangements and Voronoi diagrams

Given n line segments in the plane, we want to DETECT or to REPORT all intersection points (say, proper crossings, though we can also handle various degenerate intersesctions).
I showed the situation in 1D: detecting and reporting intersections among a set of segments (intervals) is done in optimal time using sorting. We proved a lower bound of Omega(n log n), which follows from the "Element Uniqueness Problem": Given n numbers, are the all unique? (yes/no) (The lower bound is NOT from sorting!)
I went through in detail a plane sweep algorithm (Bentley-Ottmann sweep), which spends O((k+n) log n) time to REPORT all k intersections. (It spends O(n log n) time to DETECT if there are any intersections. The detection version is basically a stream-lined version of the reporting algorithm of Bentley-Ottmann: it stops when a crossing is detected and reports that crossing as a "witness".)
The idea is to sweep a horizontal line downwards. Events occur when the line hits a segment endpoint or encounters a crossing point. (In the DETECT version, events only take place at the segment endpoints.) The endpoint events can be sorted in advance (in O(n log n) time) and put in the Event Queue; however, the crossing events are discovered "on the fly" and inserted and deleted in the Event Queue during the algorithm, as they are discovered.
We maintain a Sweep Line Status (SLS), which stores the segments that are crossed by the sweepline in sorted order, left to right. Any standard data structure for maintaining a sorted list will work here (e.g., balanced binary tree). The important thing is that we can insert, delete, and look up in the SLS, in time O(log n) (by binary search, essentially).
We specified in detail how to handle each type of event: (1) hit a top endpoint, a_i; (2) hit a bottom endpoint b_i; (3) hit a crossing point x_ij, where s_i crosses s_j. (We assume for simplicity that any two segments are either completely disjoint or have a proper crossing point, so that we need not worry about degeneracies.) In each case, we update the SLS and perform O(1) tests for intersection (between any newly adjacent segments in the SLS), inserting or deleting events from the Event Queue as needed.
The method described so far potentially has lots of events in the Event Queue (at most k+2n, but k can be very large in some cases). In the "modified" Bentley-Ottmann sweep (discussed in the next lecture), we are able to keep the Event Queue "small" (O(n)) by REMOVING from the EQ any x_ij that does not correspond to adjacent segments in the SLS any more (such a crossing will be added again later, when the segments s_i and s_j become adjacent in the SLS again).
Since there are 2n+k events and each event costs O(log n) time, the total time is O((n+k) log n), and the memory used is just O(n) for the modified Bentley-Ottmann sweep. This is NOT the best that is known. The best that is known is the optimal time O(k+ n log n), using only O(n) memory to keep the data structures.