Plane Sweeping Algorithm
Plane Sweeping Algorithm
25 Plane-sweep:
A general-purpose algorithm
for two-dimensional problems
illustrated using line segment intersection
Plane-sweep is an algorithm schema for two-dimensional geometry of great
generality and effectiveness, and algorithm designers are well advised to try it first. It
works for a surprisingly large set of problems, and when it works, tends to be very
efficient. Plane-sweep is easiest to understand under the assumption of nondegenerate
configurations. After explaining plane-sweep under this assumption, we remark on
how degenerate cases can be handled with plane-sweep.
We present a plane-sweep algorithm [SH 76] for the line segment intersection test:
Given n line segments in the plane, determine whether any two intersect;
and if so, compute a witness (i.e., a pair of segments that intersect).
Bounds on the complexity of this problem are easily obtained. The literature on
computational geometry (e.g., [PS 85]) proves a lower bound Ω(n · log n). The
obvious brute force approach of testing all n · (n – 1) / 2 pairs of line segments
requires Θ(n2) time. This wide gap between n · log n and n2 is a challenge to the
algorithm designer, who strives for an optimal algorithm whose asymptotic running
time O(n · log n) matches the lower bound.
n' = 3 n" = 6
divide the given data set divide the embedding space
In the first case, we hope for a separation into subsets S1 and S2 that permits an
efficient test whether any line segment in S1 intersects some line segment in S2.
Figure 25.1 shows the ideal case where S1 and S2 do not interact, but of course this
cannot always be achieved in a nontrivial way; and even if S can be separated as the
figure suggests, finding such a separating line looks like a more formidable problem
than the original intersection problem. Thus, in general, we have to test each line
segment in S1 against every line segment in S2, a test that may take Θ(n2) time.
The second approach of dividing the embedding space has the unfortunate
consequence of effectively increasing our data set. Every segment that straddles the
dividing line gets "cut" (i.e., processed twice, once for each half space). The two
resulting subproblems will be of size n' and n", respectively, with n' + n" > n, in the
worst case n' + n" = 2 · n. At recursion depth d we may have 2d · n subsegments to
process. No optimal algorithm is known that uses this technique.
The key idea in designing an optimal algorithm is the observation that those line
segments that intersect a vertical line L at abscissa x are totally ordered: A segment s
lies below segment t, written s <L t, if both intersect L at the current position x and the
intersection of s with L lies below the intersection of t with L. With respect to this
order a line segment may have an upper and a lower neighbor, and Fig. 25.2 shows
that s and t are neighbors at x.
Plane-sweep: A general-purpose algorithm for 2-d problems … 3
s
L
Figure 25.2: The sweep line L totally orders the segments that intersect L.
We describe the intersection test algorithm under the assumption that the
configuration is nondegenerate (i.e., no three segments intersect in the same point).
For simplicity's sake we also assume that no segment is vertical, so every segment has
a left endpoint and a right endpoint. The latter assumption entails no loss of
generality: For a vertical segment, we can arbitrarily define the lower endpoint to be
the "left endpoint", thus imposing a lexicographic (x, y)-order to refine the x-order.
With the important assumption of non-degeneracy, two line segments s and t can
intersect at x0 only if there exists an abscissa x < x0 where s and t are neighbors. Thus
it suffices to test all segment pairs that become neighbors at some time during a left-
to-right sweep of L - a number that is usually significantly smaller than n · (n – 1) / 2.
As the sweep line L moves from left to right across the configuration, the order <L
among the line segments intersecting L changes only at endpoints of a segment or at
intersections of segments. As we intend to stop the sweep as soon as we discover an
intersection, we need to perform the intersection test only at the left and right
endpoints of segments. A segment t is tested at its left endpoint for intersection with
its lower and upper neighbors. At the right endpoint of t we test its lower and upper
neighbor for intersection (Fig. 25.3).
t ?
?
The name plane-sweep is derived from the image of sweeping the plane from left to
right with a vertical line (front, or cross section), stopping at every transition point
(event) of a geometric configuration to update the cross section. All processing is done
at this moving front, without any backtracking, with a look-ahead of only one point.
The events are stored in the x-queue, and the current cross section is maintained by the
y-table. The skeleton of a plane-sweep algorithm is as follows:
initX; initY;
while not emptyX do { e := nextX; transition(e) }
The procedures 'initX' and 'initY' initialize the x-queue and the y-table. 'nextX' returns
the next event in the x-queue, 'emptyX' tells us whether the x-queue is empty. The
procedure 'transition', the advancing mechanism of the sweep, embodies all the work
to be done when a new event is encountered; it moves the front from the slice to the
left of an event e to the slice immediately to the right of e.
Plane-sweep: A general-purpose algorithm for 2-d problems … 5
For the line segment intersection test, the x-queue stores the left and right endpoints of
the given line segments, ordered by their x-coordinate, as events to be processed when
updating the vertical cross section. Each endpoint stores a reference to the
corresponding line segment. We compare points by their x-coordinates when building
the x-queue. For simplicity of presentation we assume that no two endpoints of line
segments have equal x- or y-coordinates. The only operation to be performed on the x-
queue is 'nextX': it returns the next event (i.e., the next left or right endpoint of a line
segment to be processed). The cost for initializing the x-queue is O(n · log n), the cost
for performing the 'nextX' operation is O(1).
The y-table contains those line segments that are currently intersected by the sweep
line, ordered according to <L. In the slice between two events, this order does not
change, and the y-table needs no updating (Fig. 25.4). The y-table is a dictionary that
supports the operations 'insertY', 'deleteY', 'succY', and 'predY'. When entering the left
endpoint of a line segment s we find the place where s is to be inserted in the ordering
of the y-table by comparing s to other line segments t already stored in the y-table. We
can determine whether s <L t or t <L s by determining on which side of t the left
endpoint of s lies. As we have seen in Section 14.1, this tends to be more efficient
than computing and comparing the intersection points of s and t with the sweep line. If
we implement the dictionary as a balanced tree (e.g., an AVL tree), the operations
'insertY' and 'deleteY' are performed in O(log n) time, and 'succY' and 'predY' are
performed in O(1) time if additional pointers in each node of the tree point to the
successor and predecessor of the line segment stored in this node. Since there are 2 · n
events in the x-queue and at most n line segments in the y-table the space complexity
of this plane-sweep algorithm is O(n).
6 Interaction between algorithms and data structures: Case studies in geometric computation
x-queue
Figure 25.4: The y-table records the varying state of the sweep line L.
The procedure 'transition' maintains the order <L of the line segments intersecting the
sweep line and performs intersection tests. At a left endpoint of a segment t, t is
inserted into the y-table and tested for intersection with its lower and upper neighbors.
At the right endpoint of t, t is deleted from the y-table and its two former neighbors
are tested. The algorithm terminates when an intersection has been found or all events
in the x-queue have been processed without finding an intersection:
With at most 2 · n events, and a call of 'transition' costing time O(log n), this plane-
sweep algorithm needs O(n · log n) time to perform the line segment intersection test.
The plane-sweep algorithm for the line segment intersection test is easily adapted to
the following more general problem [BO 79]:
In addition to the left and right endpoints, the x-queue now stores intersection points
as events - any intersection detected is inserted into the x-queue as an event to be
processed. When the sweep line reaches an intersection event the two participating
line segments are swapped in the y-table (Fig. 25.5). The major increase in complexity
as compared to the segment intersection test is that now we must process not only
2 · n events, but 2 · n + k events, where k is the number of intersections discovered as
we sweep the plane. A configuration with n / 2 segments vertical and n / 2 horizontal
shows that, in the worst case, k ∈ Θ(n2), which leads to an O(n2 · log n) algorithm,
certainly no improvement over the brute-force comparison of all pairs. But in most
realistic configurations, say engineering drawings, the number of intersections is much
less than O(n2), and thus it is informative to introduce the parameter k in order to get
an output-sensitive bound on the complexity of this algorithm (i.e., a bound that
adapts to the amount of data needed to report the result of the computation).
x-queue
Other changes are comparatively minor. The x-queue must be a priority queue that
supports the operation 'insertX'; it can be implemented as a heap. The cost for
initializing the x-queue remains O(n · log n). Without further analysis one might
presume that the storage requirement of the x-queue is O(n + k), which implies that
the cost for calling 'insertX' and 'nextX' remains O(log n), since k ∈ O(n2). A more
detailed analysis [PS 91], however, shows that the size of the x-queue never exceeds
O(n · (log n)2). With a slight modification of the algorithm [Bro 81] it can even be
guaranteed that the size of the x-queue never exceeds O(n). The cost for exchanging
two intersecting line segments in the y-table is O(log n), the costs for the other
operations on the y-table remain the same. Since there are 2 · n left and right endpoints
and k intersection events, the total cost for this algorithm is O((n + k) · log n). As most
realistic applications are characterized by k ∈ O(n), reporting all intersections often
remains an O(n · log n) algorithm in practice. A time-optimal algorithm that finds all
intersecting pairs of line segments in O(n · log n + k) time using O(n + k) storage
space is described in [CE 92].
t
s
u
1 2 3 4 5 6
The trace of the plane-sweep for reporting intersections may look as follows:
1 s is inserted into the y-table.
2 t is inserted above s into the y-table, and s and t are tested for intersection: No
intersection is found.
3 u is inserted below s in the y-table (since the evaluation of the function s(x) may
conclude that the left endpoint of u lies below s); s and u are tested for intersection,
but the intersection routine may conclude that s and u do not intersect: u remains
below s.
4 Delete u from the y-table.
5 Delete s from the y-table.
6 Delete t from the y-table.
Notice the calamity that struck at the critical step 3. The evaluation of a linear
expression s(x) and the intersection routine for two segments both arrived at a result
that, in isolation, is reasonable within the tolerance of the underlying arithmetic. But
the two results together are inconsistent! If the evaluation of s(x) concludes that the
left endpoint of u lies below s, the intersection routine must conclude that s and u
intersect! If these two geometric primitives fail to coordinate their answers,
catastrophy may strike. In our example, u and t never become neighbors in the y-table,
so their intersection gets lost.
Exercises
2. Design a plane-sweep algorithm that determines in O(n · log n) time whether two
simple polygons with a total of n vertices intersect.
10 Interaction between algorithms and data structures: Case studies in geometric computation
3. Design a plane-sweep algorithm that determines in O(n · log n) time whether any
two disks in a set of n disks intersect.
4. Design a plane-sweep algorithm that solves the line visibility problem discussed in
section 24.4 in time O((n + k) · log n), where k ∈ O(n2) is the number of
intersections of the line segments.
5. Give a configuration with the smallest possible number of line segments for which
the first intersection point reported by the plane-sweep algorithm in Section 25.5 is
not the leftmost intersection point.
7. Design a plane-sweep algorithm that finds all intersections among a given set of n
rectangles all of whose sides are parallel to the coordinate axes. What is the time
complexity of your algorithm?