



Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
An algorithm to detect intersections between line segments. The algorithm first introduces the concept of line segment intersection and discusses the case of two segments. It then presents a sweep line algorithm to detect intersections in a set of more than two segments. The sweep line algorithm uses a balanced binary tree to store and manage segment labels, and performs pairwise intersection tests when the sweep line hits an endpoint or an intersection point. The overall running time is o(n log n.
Typology: Study notes
1 / 6
This page cannot be seen from the preview
Don't miss anything!




Spengler: There’s something very important I forgot to tell you. Venkman: What? Spengler: Don’t cross the streams. Venkman: Why? Spengler: It would be bad. Venkman: I’m fuzzy on the whole good/bad thing. What do you mean, “bad”? Spengler: Try to imagine all life as you know it stopping instantaneously and every molecule in your body exploding at the speed of light. Stantz: Total protonic reversal. Venkman: Right. That’s bad. Okay. All right. Important safety tip. Thanks, Egon. — Ghostbusters (1984)
In this lecture, I’ll talk about detecting line segment intersections. A line segment is the convex hull of two points, called the endpoints (or vertices ) of the segment. We are given a set of n line segments, each specified by the x- and y-coordinates of its endpoints, for a total of 4 n real numbers, and we want to know whether any two segments intersect. To keep things simple, just as in the previous lecture, I’ll assume the segments are in general position.
This general position assumption lets us avoid several annoying degenerate cases. Of course, in any real implementation of the algorithm I’m about to describe, you’d have to handle these cases. Real-world data is full of degeneracies!
Degenerate cases of intersecting segments that we’ll pretend never happen: Overlapping colinear segments, endpoints inside segments, and shared endpoints.
The first case we have to consider is n = 2. (The problem is obviously trivial when n ≤ 1 !) How do we tell whether two line segments intersect? One possibility, suggested by a student in class, is to construct the convex hull of the segments. Two segments intersect if and only if the convex hull is a quadrilateral whose vertices alternate between the two segments. In the figure below, the first pair of segments has a triangular convex hull. The last pair’s convex hull is a quadrilateral, but its vertices don’t alternate.
Some pairs of segments.
Fortunately, we don’t need (or want!) to use a full-fledged convex hull algorithm just to test two segments; there’s a much simpler test.
Two segments ab and cd intersect if and only if
cd , and
ab.
To test whether two points are on opposite sides of a line through two other points, we use the same counterclockwise test that we used for building convex hulls. Specifically, a and b are on opposite
sides of line
cd if and only if exactly one of the two triples a, c, d and b, c, d is in counterclockwise order. So we have the following simple algorithm.
INTERSECT(a, b, c, d): if CCW(a, c, d) = CCW(b, c, d) return FALSE else if CCW(a, b, c) = CCW(a, b, d) return FALSE else return TRUE
Or even simpler:
INTERSECT(a, b, c, d): return
[ CCW(a, c, d) 6 = CCW(b, c, d)
] ∧
[ CCW(a, b, c) 6 = CCW(a, b, d)
]
To detect whether there’s an intersection in a set of more than just two segments, we use something called a sweep line algorithm. First let’s give each segment a unique label. I’ll use letters, but in a real implementation, you’d probably use pointers/references to records storing the endpoint coordinates. Imagine sweeping a vertical line across the segments from left to right. At each position of the sweep line, look at the sequence of (labels of) segments that the line hits, sorted from top to bottom. The only times this sorted sequence can change is when the sweep line passes an endpoint or when the sweep line passes an intersection point. In the second case, the order changes because two adjacent labels swap places.^1 Our algorithm will simulate this sweep, looking for potential swaps between adjacent segments. The sweep line algorithm begins by sorting the 2 n segment endpoints from left to right by comparing their x-coordinates, in O(n log n) time. The algorithm then moves the sweep line from left to right, stopping at each endpoint. We store the vertical label sequence in some sort of balanced binary tree that supports the following operations in O(log n) time. Note that the tree does not store any explicit search keys, only segment labels.
The functions INSERT, DELETE, PREDECESSOR, and SUCCESSOR modify or search through the sorted label sequence. Finally, INTERSECT tests whether two line segments intersect.
ANYINTERSECTIONS(S[1 .. n]): sort the endpoints of S from left to right create an empty label sequence for i ← 1 to 2 n ← _label_ [i] if _isleft_ [i] INSERT() if INTERSECT(S[], S[SUCCESSOR()]) return TRUE if INTERSECT(S[], S[PREDECESSOR()]) return TRUE else if INTERSECT(S[SUCCESSOR()], S[PREDECESSOR()]) return TRUE DELETE( label [i]) return FALSE
Note that the algorithm doesn’t try to avoid redundant pairwise tests. In the figure below, the top and bottom segments would be checked n − 1 times, once at the top left endpoint, and once at the right endpoint of every short segment. But since we’ve already spent O(n log n) time just sorting the inputs, O(n) redundant segment intersection tests make no difference in the overall running time.
The same pair of segments might be tested n − 1 times.
(a) Describe and analyze and algorithm to determine whether any two rectangles in X intersect, in O(n log n) time. (b) Describe and analyze an algorithm to find a point that lies inside the largest number of rectangles in X, in O(n log n) time. (c) Describe and analyze an algorithm to compute the area of the union of the rectangles in X, in O(n log n) time.
(a) Manhattan: Each building is a rectangle whose bottom edge lies on the x-axis, specified by the left and right x-coordinates and the top y-coordinate.
The Manhattan skyline
(b) Giza: Each building is a right isosceles triangle whose base lies on the x-axis, specified by the (x, y)-coordinates of its apex.
The Egyptian skyline
(c) Nome: Each building is a semi-circular disk whose center lies on the x-axis, specified by its center x-coordinate and radius.
(a) Prove that there is a set of n disjoint line segments, each joining one Ghostbuster to one ghost. [Hint: Consider the matching of minimum total length.] (b) Prove that the non-collinearity assumption is necessary in part (a). (c) A partitioning line is a line in the plane such that the number of ghosts on one side of the line is equal to the number of Ghostbusters on the same side of that line. Describe an algorithm to compute a partitioning line in O(n log n) time. (d) Prove that there is a partitioning line with exactly bn/ 2 c ghosts and exactly bn/ 2 c Ghost- busters on either side. This is a special case of the so-called ham sandwich theorem. Describe an algorithm to compute such a line as quickly as possible.