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