Lecture 16: Fortune's Algorithm and Voronoi diagramsProperties of the Voronoi diagram:
Here are some observations about the structure of Voronoi diagrams in the plane. Voronoi edges: Each point on an edge of the Voronoi diagram is equidistant from its two nearest neighbors pi and pj. Thus, there is a circle centered at such a point such that pi and pj lie on this circle, and no other site is interior to the circle. Voronoi vertices: It follows that vertex at which three Voronoi cells V(pi), V(pj), and V(pk) intersect is equidistant from all sites. Thus it is the center of the circle passing through these sites, and this circle contains no other sites in its interior. Degree: If we assume that no four points are cocircular, then the vertices of the Voronoi diagram all have degree three. Convex hull: A cell of the Voronoi diagram is unbounded if and only if the corresponding site lies on the convex hull. (Observe that a point is on the convex hull if and only if it is the closest point from some point at infinity.) Size: If n denotes the number of sites, then the Voronoi diagram is a planar graph (if we imagine all the unbounded edges as going to a common vertex infinity) with exactly n faces. It follows from Euler's formula that the number of Voronoi vertices is at most 2n - 5 and the number of edges is at most 3n - 6. (See the text for details.) Computing Voronoi Diagrams: There are a number of algorithms for computing Voronoi diagrams. Of course, there is a naive O(n2 log n) time algorithm, which operates by computing V(pi) by intersecting the n - 1 bisector halfplanes h(pi, pj), for j != i. However, there are much more efficient ways, which run in O(n log n) time. Since the convex hull can be extracted from the Voronoi diagram in O(n) time, it follows that this is asymptotically optimal in the worst case. Historically, O(n2) algorithms for computing Voronoi diagrams were known for many years (based on incremental constructions). When computational geometry came along, a more complex, but asymptotically superior O(n log n) algorithm was discovered. This algorithm was based on divide and conquer. But it was rather complex, and somewhat difficult to understand. Later, Steven Fortune invented a plane sweep algorithm for the problem, which provided a simpler O(n log n) solution to the problem. It is his algorithm that we will discuss. Somewhat later still, it was discovered that the incremental algorithm is actually quite efficient, if it is run as a randomized incremental algorithm. We will discuss this algorithm later when we talk about the dual structure, called a Delaunay triangulation. Fortune's Algorithm: Before discussing Fortune's algorithm, it is interesting to consider why this algorithm wasn't invented much earlier. In fact, it is quite a bit trickier than any plane sweep algorithm we have seen so far. The key to any plane sweep algorithm is the ability to discover all ``upcoming'' events in an efficient manner. For example, in the line segment intersection algorithm we considered all pairs of line segments that were adjacent in the sweep line status, and inserted their intersection point in the queue of upcoming events. The problem with the Voronoi diagram is that of predicting where the upcoming events will occur. The reason is that a site that lies ahead of the sweep line may generate a Voronoi vertex that lies behind the sweep line. It is these ``unanticipated events'' that make the design of a plane sweep algorithm challenging. Fortune made the clever observation of rather than computing the Voronoi diagram through plane sweep in its final form, instead to compute a ``distorted'' but topologically equivalent version of the diagram. This distorted version of the diagram was based on a transformation that alters the way that distances are measured in the plane. The resulting diagram had the same structure as the Voronoi diagram, but its edges were parabolic arcs, rather than straight line segments. Once this distorted diagram was generated, it was an easy matter to ``undistort'' it to produce the correct Voronoi diagram. Our presentation will be different from Fortune's. Rather than distort the diagram, we can think of this algorithm as distorting the sweep line. Actually, we will think of two objects that control the sweeping process. First, there will be a horizontal sweep line, moving from top to bottom. We will also maintain a x monotonic curve called a beach line (I guess because it looks like waves rolling up on a beach.) The beach line is formed from parabolic arcs. As the sweep line moves downward, the beach line moves downward as well, but the beach line's shape depends on the locations of the sites. We will see that the Voronoi diagram ``grows out'' of the beach line.Figure 57: Plane sweep Voronoi diagrams. The Beach Line: In order to make these ideas more concrete, recall that the problem with ordinary plane sweep is that sites that lie below the sweep line may affect the diagram that lies above the sweep line. To avoid this problem, we will maintain only the portion of the diagram that cannot be affected by anything that lies below the sweep line. To do this, we will ``cut'' the halfplane lying above the sweep line into two regions: those points that are closer to some site p above the sweep line than they are to the sweep line itself, and those points that are closer to the sweep line than any site above the sweep line. The set of points q that are equidistant from the sweep line to their nearest site above the sweep line is called the beach line. (Hey, you, reader! THIS NEXT PARAGRAPH IS THE WHOLE TRICK. everything else is just implementation) Observe that for any point q above the beach line, we know that its closest point cannot be affected by any site that lies below the sweep line. Hence, the portion of the Voronoi diagram that lies above the beach line is ``safe'' in the sense that we have all the information that we need in order to compute it (without knowing abouts what points are still to appear below the sweep line). (GOT IT?, ok, now go on...) What does the beach line look like? We know from high school geometry that the set of points that are equidistant from a site lying above a horizontal line and the line itself forms a parabola that is open on top. With a little analytic geometry, it is easy to show that the parabola becomes ``skinnier'' as the site becomes closer to the line, the parabola degenerates into a vertical ray emanating from the site. (You should work out the equations to see why this is so.) Thus, the beach line consists of the lower envelope of these parabolas. (By the way, if we were interested in computing the Voronoi diagram of line segments, the beach line is the boundary of the Voronoi cell of the sweep line itself.) Because the parabolas are x monotone, so is the beach line. Also observe that the vertex where two arcs of the beach line intersect, which we call a breakpoint, is a point that is equidistant from two sites and the sweep line, and hence must lie on some Voronoi edge. In particular, if the beach line arcs corresponding to points pi and pj share a common breakpoint on the beach line, then this breakpoint lies on the Voronoi edge between pi and pj. From this we have the following important characterization. Lemma: The beach line is an x monotone curve made up of parabolic arcs. The breakpoints of the beach line lie on Voronoi edges of the final diagram. Fortune's algorithm consists of simulating the growth of the beach line as the sweep line moves downward, and in particular tracing the paths of the breakpoints as they travel along the edges of the Voronoi diagram. Of course, as the sweep line moves the parabolas forming the beach line change their shapes continuously. As with all plane sweep algorithms, we will be interested in simulating the discrete event points where there is a ``significant event'', that is, any event that changes the topological structure of the beach line. It turns out these significant events will be of two varieties: Site events: When the sweep line passes over a new site a new arc will be inserted into the beach line. Vertex events: (What our text calls circle events.) When the length of a parabolic arc shrinks to zero, the arc disappears and a new Voronoi vertex will be created at this point. The algorithm consists of processing these two types of events. As the Voronoi vertices are being discovered by vertex events, it will be an easy matter to update a DCEL for the diagram as we go, and so to link the entire diagram together. Next time we will show how these two events are discovered and processed. Fortune's Algorithm finally Fortune's Algorithm: Last time we introduced Voronoi diagrams, which for given a set of sites partitions the plane into regions according to which site is the closest. We also introduced Fortune's algorithm, a plane sweep algorithm for computing Voronoi diagrams in the plane. Recall that (because of the unanticipated events) rather than just sweeping a straight line, Fortune's algorithm sweeps two objects, the standard horizontal sweep line and curved line called the beach line. The beach line is the set of points that are equidistant from some virtual sweep line and the nearest site. It consists of pieces of parabolic arcs, joined end to end at points called breakpoints. The breakpoints lie on the Voronoi diagram. Fortune's algorithm simulates the growth of the beach line as the sweep line moves downward, and in doing so, traces the paths of the breakpoints as they travel along the edges of the Voronoi diagram. Last time we noted that there are two types of events, site events when the horizontal sweep line sweeps over a new site and vertex events when two breakpoints on the beach line collide with each other, resulting in the generation of a vertex of the Voronoi diagram. Today we discuss how to handle these two types of events. Site events: A site event is generated whenever the horizontal sweep line passes over a site. As we mentioned before, at the instant that the sweep line touches the point, its associated parabolic arc will degenerate to a vertical ray shooting up from the point to the current beach line. As the sweep line proceeds downwards, this ray will widen into an arc along the beach line. To process a site event we will determine the arc of the sweep line that lies directly above the new site. (Let us make the general position assumption that it does not fall immediately below a vertex of the beach line.) We then split this arc of the beach line in two by inserting a new infinitesimally small arc at this point. As the sweep proceeds, this arc will start to widen, and eventually will join up with other edges in the diagram. (See the figure below.) Figure 58: Site events. It is important to consider whether this is the only way that new arcs can be introduced into the sweep line. In fact it is. We will not prove it, but a careful proof is given in the text. As a consequence of this proof, it follows that the maximum number of arcs on the beach line can be at most 2n - 1, since each new point can result in creating one new arc, and splitting an existing arc, for a net increase of two arcs per point (except the first). The nice thing about site events is that they are all known in advance. Thus, after sorting the points by y coordinate, all these events are known. Vertex events: In contrast to site events, vertex events are generated dynamically as the algorithm runs. As with the line segment plane sweep algorithm, the important idea is that each such event is generated by objects that are neighbors on the beach line. However, unlike the segment intersection where pairs of consecutive segments generated events, here triples of points generate the events. In particular, consider any three consecutive points pi, pj, and pk whose arcs appear consecutively on the beach line from left to right. (See the figure below.) Further, suppose that the circumcircle for these three sites lies at least partially below the current sweep line (meaning that the Voronoi vertex has not yet been generated), and that this circumcircle contains no points lying below the sweep line (meaning that no future point will block the creation of the vertex). Consider the moment at which the sweep line falls to a point where it is tangent to the lowest point of this circle. At this instant the circumcenter of the circle is equidistant from all three sites and from the sweep line. Thus all three parabolic arcs pass through this center point, implying that the contribution of the arc from pj has disappeared from the beach line. In terms of the Voronoi diagram, the bisectors (pi, pj) and (pj, pk) have met each other at the Voronoi vertex, and a single bisector (pi, pk) remains. Figure 59: Vertex events. Sweep line algorithm: We can now present the algorithm is greater detail. The main structures that we will maintain are the following: (Partial) Voronoi diagram: The partial Voronoi diagram that has been constructed so far will be stored in a DCEL. There is one technical difficulty caused by the fact that the diagram contains unbounded edges. To handle this we will assume that the entire diagram is to be stored within a large bounding box. (This box should be chosen large enough that all of the Voronoi vertices fit within the box.) Beach line: The beach line is represented using a dictionary (e.g. a balanced binary tree or skip list). An important fact of the construction is that we do not explicitly store the parabolic arcs. They are just their for the purposes of deriving the algorithm. Instead for each parabolic arc on the current beach line, we store the site that gives rise to this arc. Notice that a site may appear multiple times on the beach line (in fact linearly many times in n). But the total length of the beach line will never exceed 2n-1. Between each consecutive pair of sites pi and pj, there is a breakpoint. Although the breakpoint moves as a function of the sweep line, observe that it is possible to compute the exact location of the breakpoint as a function of pi, pj, and the current y coordinate of the sweep line. Thus, as with beach lines, we do not explicitly store breakpoints. Rather, we compute them only when we need them. The important operations that we will have to support on the beach line are (1) Given a fixed location of the sweep line, determine the arc of the beach line that intersects a given vertical line. This can be done by a binary search on the breakpoints, which are computed ``on the fly''. (Think about this.) (2) Compute predecessors and successors on the beach line. (3) Insert an new arc pi within a given arc pj, thus splitting the arc for pj into two. This creates three arcs, pj, pi, and pj. (4) Delete an arc from the beach line. It is not difficult to modify a standard dictionary data structure to perform these opera tions in O(log n) time each. Event queue: The event queue is a priority queue with the ability both to insert and delete new events. Also the event with the largest y coordinate can be extracted. For each site we store its y coordinate in the queue. For each consecutive triple pi, pj, pk on the beach line, we compute the circumcircle of these points. (We'll leave the messy algebraic details as an exercise, but this can be done in O(1) time.) If the lower endpoint of the circle (the minimum y coordinate on the circle) lies below the sweep line, then we create a vertex event whose y coordinate is the y coordinate of the bottom endpoint of the circumcircle. We store this in the priority queue. Each such event in the priority queue has a cross link back to the triple of sites that generated it, and each consecutive triple of sites has a cross link to the event that it generated in the priority queue. The algorithm proceeds like any plane sweep algorithm. We extract an event, process it, and go on to the next event. Each event may result in a modification of the Voronoi diagram and the beach line, and may result in the creation or deletion of existing events. Here is how the two types of events are handled: Site event: Let pi be the current site. We shoot a vertical ray up to determine the arc that lies immediately above this point in the beach line. Let p j be the corresponding site. We split this arc, replacing it with the triple of arcs pj, pi, pj which we insert into the beach line. Also we create new (dangling) edge for the Voronoi diagram which lies on the bisector between pi and pj. Any old triple that involved pj as its center arc is deleted from the priority queue, and we generate new events for each of the possible three new triples that result from this insertion. Vertex event: Let pi, pj, and pk be the three sites that generate this event (from left to right). We delete the arc for for p j from the beach line. We create a new vertex in the Voronoi diagram, and tie the edges for the bisectors (pi, pj), (pj,pk ) to it, and start a new edge for the bisector (pi, pk) that starts growing down below. Finally, we delete any events that arose from triples involving this arc of pj, and generate new events corresponding to consecutive triples involving pi and pk (there are two of them). The analysis follows a typical analysis for plane sweep. Each event involves O(1) processing time plus a constant number accesses to the various data structures. Each of these accesses takes O(logn) time, and the data structures are all of size O(n). Thus the total time is O(n log n), and the total space is O(n).