Sweep Line Algorithm: Intersection Detection & Geometry Problems
Master the sweep line algorithm for intersection detection and geometric problems.
20+ years shipping performance-critical code where algorithms decide the bill. Drawn from code that ran under real load.
- ✓Basic knowledge of sorting and priority queues
- ✓Understanding of balanced binary search trees
- ✓Familiarity with basic geometry concepts (points, lines, segments)
- The sweep line algorithm processes events in order of a sweeping line to solve geometric problems efficiently.
- It reduces time complexity from O(n^2) to O(n log n) for line segment intersection detection.
- Key components: event queue, sweep line status, and event processing.
- Common applications: rectangle union area, skyline problem, closest pair of points.
- Critical for computational geometry, GIS, and computer graphics.
Imagine you have a bunch of straws scattered on a table. To find which straws cross each other, instead of checking every pair, you slide a ruler across the table. As the ruler moves, you keep track of which straws it touches. When a new straw starts or ends, you check only the nearby straws. This is the sweep line algorithm.
Geometric problems often involve detecting intersections among a set of line segments, computing the union area of rectangles, or finding the closest pair of points. A naive approach would check every pair, leading to O(n^2) time complexity. The sweep line algorithm elegantly reduces this to O(n log n) by processing events in order along a sweeping line.
Imagine you're designing a map application that needs to highlight overlapping roads. Checking every pair of road segments would be too slow for millions of segments. The sweep line algorithm processes segments as a vertical line sweeps from left to right, maintaining only active segments and checking for intersections among neighbors. This is the backbone of many computational geometry libraries.
In this tutorial, you'll learn the core concepts, implement a line segment intersection detector, and explore variations like the Bentley-Ottmann algorithm. We'll also cover real-world production incidents where sweep line bugs caused critical failures, and provide debugging guides for common pitfalls.
Core Concepts of the Sweep Line Algorithm
The sweep line algorithm is a paradigm for solving geometric problems by simulating a line sweeping across the plane. It processes events in order of the sweep line's position, maintaining a data structure of active geometric objects.
- Event Queue: A priority queue of events (e.g., segment endpoints, intersection points) sorted by x-coordinate (or y for horizontal sweep).
- Sweep Line Status: A balanced binary search tree (e.g., AVL tree) storing active objects ordered by their intersection with the sweep line.
- Event Processing: For each event, update the status and perform checks (e.g., test for intersections between neighbors).
The algorithm's efficiency comes from the fact that intersections can only occur between objects that are adjacent in the sweep line status. This reduces the number of pairs to check from O(n^2) to O(n log n).
Let's implement a basic line segment intersection detector using a vertical sweep line.
Event Queue and Ordering
The event queue is a priority queue that stores all events sorted by x-coordinate. For vertical sweep lines, events are typically segment endpoints (left and right). However, when intersections are detected, they must also be added as events to handle future intersections (as in Bentley-Ottmann).
Ordering Rules: - Left endpoints before right endpoints when x is equal. - For equal x and same type, use y-coordinate as tie-breaker. - For intersection events, process after endpoints at the same x.
Proper ordering is critical. A common bug is processing right endpoints before left endpoints, which can cause missed intersections or incorrect status updates.
Let's implement a proper event queue using heapq.
Sweep Line Status Data Structure
The sweep line status maintains the set of active segments intersected by the sweep line, ordered by their y-coordinate at the current x. This requires a balanced binary search tree (BST) that supports insertion, deletion, and neighbor queries in O(log n).
In Python, we can use the bisect module on a sorted list for simplicity, but for production, use a library like sortedcontainers or implement a treap/AVL tree.
Operations: - Insert a segment when its left endpoint is encountered. - Delete a segment when its right endpoint is encountered. - Find neighbors (above and below) to check for intersections.
When a segment is inserted, check for intersections with its immediate neighbors. When a segment is deleted, its former neighbors become adjacent and must be checked.
Here's an implementation using a sorted list with bisect (O(n) insertion/deletion, but good for demonstration).
sortedcontainers are acceptable but may have overhead.Bentley-Ottmann Algorithm for Line Segment Intersection
The Bentley-Ottmann algorithm is a sweep line algorithm that finds all intersections among a set of line segments in O((n + k) log n) time, where k is the number of intersections. It handles general position (no three segments intersect at a point, no vertical segments) but can be extended.
Key Differences from Basic Sweep: - Intersection points are added as events. - When an intersection is detected, the order of the two intersecting segments in the status is swapped. - Need to handle multiple segments intersecting at the same point.
Here's a simplified implementation that assumes no three segments intersect at a point and no vertical segments.
Application: Rectangle Union Area
The sweep line algorithm can compute the union area of axis-aligned rectangles efficiently. The idea: sweep a vertical line from left to right, maintaining the set of active rectangles (those intersecting the sweep line). The union area is the sum over x-intervals of (x_next - x_current) * total_y_length, where total_y_length is the length of the union of y-intervals of active rectangles.
Algorithm: 1. Create events for left and right edges of each rectangle. 2. Sort events by x. 3. Maintain a data structure that stores the y-intervals of active rectangles and can compute the total covered length. 4. For each event, update the active intervals and compute area contributed by the previous x-interval.
Let's implement a simple version using a list of intervals.
Application: Skyline Problem
The skyline problem asks for the outline of a city given building rectangles. Sweep line solves it by processing left and right edges, maintaining the current maximum height.
Algorithm: 1. Create events for left (height positive) and right (height negative) edges. 2. Sort events by x; for equal x, process left edges before right edges, and for same x and type, higher height first. 3. Maintain a multiset of current heights. 4. When processing an event, update the multiset and if the maximum height changes, add a point to the skyline.
Here's an implementation using a max-heap with lazy deletion.
sortedcontainers.Common Pitfalls and Best Practices
Sweep line algorithms are subtle. Here are common mistakes and how to avoid them:
- Incorrect Event Ordering: Processing right endpoints before left endpoints can cause active status to be incorrect. Always ensure left events come before right events at the same x.
- Floating-Point Errors: Intersection calculations with floating-point can be imprecise. Use rational numbers or a small epsilon. For integer coordinates, use exact arithmetic.
- Degenerate Cases: Vertical segments, overlapping segments, and multiple intersections at a point require special handling. Many algorithms assume general position.
- Data Structure Choice: Using a list for active segments leads to O(n^2) time. Use a balanced BST or a skip list.
- Memory Management: In Bentley-Ottmann, intersection events can be numerous. Ensure you don't add duplicate events.
Best Practices: - Use a robust geometry library (e.g., CGAL, Shapely) for production. - Test with random and edge-case inputs. - Profile performance with large datasets. - Document assumptions about input (e.g., no vertical segments).
The Overlapping Rectangle Disaster in a Mapping Service
- Always test edge cases like zero-width or zero-height shapes.
- Use stable sorting for events with equal coordinates.
- Include integration tests with real-world data.
- Document assumptions about input geometry.
- Consider using robust geometric predicates to avoid floating-point errors.
print(events)check status updates| File | Command / Code | Purpose |
|---|---|---|
| sweep_line_basic.py | class Point: | Core Concepts of the Sweep Line Algorithm |
| event_queue.py | class Event: | Event Queue and Ordering |
| status_structure.py | class SweepLineStatus: | Sweep Line Status Data Structure |
| bentley_ottmann.py | class Event: | Bentley-Ottmann Algorithm for Line Segment Intersection |
| rectangle_union.py | def rectangle_union_area(rects): | Application |
| skyline.py | def get_skyline(buildings): | Application |
Key takeaways
Interview Questions on This Topic
Explain the sweep line algorithm for finding all intersections among line segments.
Frequently Asked Questions
20+ years shipping performance-critical code where algorithms decide the bill. Drawn from code that ran under real load.
That's Geometry. Mark it forged?
4 min read · try the examples if you haven't