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