Skip to content

Commit 993586b

Browse files
committed
adding Sweep line algorithm script adapted to BinaryTrees.jl. This is not behaving as expected with a test ring from src/clipping/greinerhormann.jl line 239.
1 parent 41ad8d4 commit 993586b

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

src/utils/sweepline.jl

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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

Comments
 (0)