Line Intersect
Line Intersect
Algorithms
Abhiram G. Ranade
Line Segment Intersection
Line segment intersection problem
Input: n line segments in the plane.
Output: Do any two intersect?
• Naive algorithm: For all i,j: check if segment i
intersects with segment j.
– O(n2) time.
• Can be done in O(nlog n) time by using
– Creative use of balanced search trees
– “Line sweep” technique
Important operations on Sets implemented
as search trees
#include <set>
set<int> myset; //balanced search tree
// but no explicit mention of nodes.
// will work on any domain having operator <
myset.insert(20);
myset.insert(30);
myset.insert(40);
auto it = myset.find(30);
// it “points to” node having 30
cout << *prev(it) << *it << *next(it);
// prev(it) ”points to” previous to it
// next(it)
// prints 203040
myset.erase(prev(it));
// deletes node having 20
About algorithm design
Try 1 dimensional case.
• Line segments lie in the plane.
• Algorithm for determining intersection:
– Sort all endpoints.
– If right endpoint of any segment does not immediately succeed
the left endpoint in the sorted order – declare “Intersection!”
Key idea: we dont explicitly compare every segment with
every other.
• If segment 1 is to left of 2 which is to the left of 3, then we
never have to compare 1 and 3.
Can we do something like this in the plane?
Line segment intersection: 2d case
• “Sweep” a horizontal line L from top to bottom.
• Let S = segments intersected by L as it moves.
– Segments will enter and leave S
– Maintain segments in S in left to right order of their intersection
with L
• Check for intersection between segments i,j only if i,j are
adjacent in left to right order at some time while sweeping.
Observation: If segments i,j intersect at (x,y), then i,j will be
adjacent in S when L is just above (x,y).
Observation: Many i,j will never be adjacent: we do not
perform intersection calculation for them. Saving!
Algorithm
1. Points[0..2n-1] = Segment endpoints sorted by y coordinate.
2. Ordered_Set S = empty;
3. For i=0 to 2n-1
4. If Points[i] = Points[i].segment.top // if Points[i] is top endpoint of its segment
5. S.Insert(Points[i].segment)
6. If Points[i].segment intersects S.prev(Points[i].segment) return true
7. // segment previous to Points[i] in S
8. if Points[i].segment intersects S.next(Points[i].segment) return true
9. else // if Points[i] is bottom endpoint of its segment
10. if S.prev(Points[i].segment) intersects S.next(Points[i].segment)
11. return true
12. S.Remove(Points[i].segment)
13. End for
14. Return false
Key Fact
• Suppose we are sweeping L, and segment s1 intersects L to the
left of segment s2.
• As L moves, s1 will continue to intersect it to the left of s2,
unless s1 and s2 first intersect.
• But for s1 to intersect s2 they will have to first become adjacent
on L.
• At this point the an intersection check is made, and the
algorithm will stop.
• Once a segment s1 is deemed to be to the left of segment s2
on L and thus placed in S, their relative order will not change.
Implementation of S
Operations needed:
• Insert a segment
• Find
• Get next and previous to current as per left to right order
• Delete
Key idea
• S is implemented as STL set.
• Must define < operator so that next and previous will
refer to next and previous segments intersecting L in x
coordinate order.
The comparison operator on segments
• PQ, RT: segments to compare.
• Assume P, R : top endpoints of PQ, RT
• Assume P.top.y > R.top.y
• P’, R’=R : points where PQ, RT intersect L
• Ordering relation: PQ < RT == P’.x < R.x
cross-product = determinant
= (Q.x– P.x)(R.y – P.y) – (R.x – P.x)(Q.y – P.y)