1+ # Implementation of Bentley-Ottmann algorith
2+ # https://en.wikipedia.org/wiki/Bentley%E2%80%93Ottmann_algorithm
3+
4+ using BinaryTrees
5+
6+
7+ """
8+ bentleyottmann(segments)
9+
10+ Compute pairwise intersections between n `segments`
11+ in O(nβ
log(n)) time using Bentley-Ottmann sweep line
12+ algorithm.
13+ """
14+ function bentleyottmann (segments)
15+ # adjust vertices of segments
16+ segs = map (segments) do s
17+ a, b = extrema (s)
18+ a > b ? reverse (s) : s
19+ end
20+
21+ # retrieve relevant info
22+ s = first (segs)
23+ p = minimum (s)
24+ P = typeof (p)
25+ S = Tuple{P,P}
26+
27+ # initialization
28+ π¬ = AVLTree {P} ()
29+ π― = AVLTree {S} ()
30+ β = Dict {P,Vector{S}} ()
31+ π° = Dict {P,Vector{S}} ()
32+ π = Dict {P,Vector{S}} ()
33+ for s in segs
34+ a, b = extrema (s)
35+ BinaryTrees. insert! (π¬, a)
36+ BinaryTrees. insert! (π¬, b)
37+ haskey (β, a) ? push! (β[a], (a, b)) : (β[a] = [(a, b)])
38+ haskey (π°, b) ? push! (π°[b], (a, b)) : (π°[b] = [(a, b)])
39+ haskey (β, b) || (β[b] = S[])
40+ haskey (π°, a) || (π°[a] = S[])
41+ haskey (π, a) || (π[a] = S[])
42+ haskey (π, b) || (π[b] = S[])
43+ end
44+ m = Point (- Inf , - Inf )
45+ M = Point (Inf , Inf )
46+ BinaryTrees. insert! (π―, (m, m))
47+ BinaryTrees. insert! (π―, (M, M))
48+
49+ # sweep line
50+ I = Dict {P,Vector{S}} ()
51+ while ! isnothing (BinaryTrees. root (π¬))
52+ p = _key (BinaryTrees. root (π¬))
53+ BinaryTrees. delete! (π¬, p)
54+ handle! (I, p, π¬, π―, β, π°, π)
55+ end
56+ I
57+ end
58+
59+ function handle! (I, p, π¬, π―, β, π°, π)
60+ ss = β[p] βͺ π°[p] βͺ π[p]
61+ if length (ss) > 1
62+ I[p] = ss
63+ end
64+ for s in β[p] βͺ π[p]
65+ BinaryTrees. delete! (π―, s)
66+ end
67+ for s in π°[p] βͺ π[p]
68+ BinaryTrees. insert! (π―, s)
69+ end
70+ if length (π°[p] βͺ π[p]) == 0
71+ # n = BinaryTrees.search(π―, p)
72+ else
73+ end
74+ end
75+
76+ _key (node:: BinaryTrees.AVLNode ) = node. key
0 commit comments