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