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