From a9bd4e40806b9eb8fa19523a226a9c7fd0e1f0df Mon Sep 17 00:00:00 2001 From: Alec Hammond Date: Wed, 18 Jan 2023 14:41:00 -0800 Subject: [PATCH 1/6] modify findfirst to return index rather than shape --- src/util/kdtree.jl | 32 +++++++++++++++++++++++++------- test/kdtree.jl | 2 +- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/util/kdtree.jl b/src/util/kdtree.jl index 37f0669..7f0536e 100644 --- a/src/util/kdtree.jl +++ b/src/util/kdtree.jl @@ -16,14 +16,16 @@ not shapes of nonzero size.) """ mutable struct KDTree{K,S<:Shape{K}} s::Vector{S} + s_index::Vector{Int} ix::Int x::Float left::KDTree{K,S} # shapes ≤ x in coordinate ix right::KDTree{K,S} # shapes > x in coordinate ix - KDTree{K,S}(s::AbsVec{S}) where {K,S<:Shape{K}} = new(s, 0) + KDTree{K,S}(s::AbsVec{S}) where {K,S<:Shape{K}} = new(s, collect(1:size(s)[1]), 0) + KDTree{K,S}(s::AbsVec{S},s_index::Vector{<:Int}) where {K,S<:Shape{K}} = new(s, s_index, 0) function KDTree{K,S}(ix::Integer, x::Real, left::KDTree{K,S}, right::KDTree{K,S}) where {K,S<:Shape{K}} 1 ≤ ix ≤ K || throw(BoundsError()) - new(S[], ix, x, left, right) + new(S[], Int[], ix, x, left, right) end end @@ -38,8 +40,15 @@ Construct a K-D tree (`KDTree`) representation of a list of When searching the tree, shapes that appear earlier in `s` take precedence over shapes that appear later. """ + function KDTree(s::AbsVec{S}) where {K,S<:Shape{K}} - (length(s) ≤ 4 || K == 0) && return KDTree{K,S}(s) + # If no list of indicies is provided, simply enumerate by the number of + # shapes in `s`. + return KDTree(s,collect(1:size(s)[1])) +end + +function KDTree(s::AbsVec{S}, s_index::Vector{<:Int}) where {K,S<:Shape{K}} + (length(s) ≤ 4 || K == 0) && return KDTree{K,S}(s, s_index) # figure out the best dimension ix to divide over, # the dividing plane x, and the number (nl,nr) of @@ -61,22 +70,26 @@ function KDTree(s::AbsVec{S}) where {K,S<:Shape{K}} end # don't bother subdividing if it doesn't reduce the # of shapes much - 4*max(nl,nr) > 3*length(s) && return KDTree{K,S}(s) + 4*max(nl,nr) > 3*length(s) && return KDTree{K,S}(s,s_index) # create the arrays of shapes in each subtree sl = Vector{S}(undef, nl) + sl_idx = Vector{Int}(undef, nl) sr = Vector{S}(undef, nr) + sr_idx = Vector{Int}(undef, nr) il = ir = 0 for k in eachindex(s) if b[k][1][ix] ≤ x sl[il += 1] = s[k] + sl_idx[il] = s_index[k] end if b[k][2][ix] > x sr[ir += 1] = s[k] + sr_idx[ir] = s_index[k] end end - return KDTree{K,S}(ix, x, KDTree(sl), KDTree(sr)) + return KDTree{K,S}(ix, x, KDTree(sl,sl_idx), KDTree(sr,sr_idx)) end depth(kd::KDTree) = kd.ix == 0 ? 0 : max(depth(kd.left), depth(kd.right)) + 1 @@ -104,7 +117,7 @@ function Base.findfirst(p::SVec{N}, s::Vector{S}) where {N,S<:Shape{N}} for i in eachindex(s) b = bounds(s[i]) if all(b[1] .< p .< b[2]) && p ∈ s[i] # check if p is within bounding box is faster - return s[i] + return i end end return nothing @@ -118,7 +131,12 @@ function Base.findfirst(p::SVec{N}, kd::KDTree{N}) where {N} return findfirst(p, kd.right) end else - return findfirst(p, kd.s) + idx = findfirst(p, kd.s) + if isnothing(idx) + return idx + else + return kd.s_index[idx] + end end end diff --git a/test/kdtree.jl b/test/kdtree.jl index eab9209..9013e3c 100644 --- a/test/kdtree.jl +++ b/test/kdtree.jl @@ -7,7 +7,7 @@ s = Shape2[Ball([i,0], 1) for i in 0:20] kd = KDTree(s) @test GeometryPrimitives.depth(kd) == 3 - @test findfirst([10.1,0], kd).c[1] == 10 + @test s[findfirst([10.1,0], kd)].c[1] == 10 @test findfirst([10.1,1], kd) == nothing @test checktree(kd, s) From e8bce9ef7f73ef63a306adb9640c3ef0a8650149 Mon Sep 17 00:00:00 2001 From: Alec Hammond Date: Thu, 19 Jan 2023 11:09:38 -0800 Subject: [PATCH 2/6] use eachindex instead of 1:size --- src/util/kdtree.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/kdtree.jl b/src/util/kdtree.jl index 7f0536e..4a27328 100644 --- a/src/util/kdtree.jl +++ b/src/util/kdtree.jl @@ -21,7 +21,7 @@ mutable struct KDTree{K,S<:Shape{K}} x::Float left::KDTree{K,S} # shapes ≤ x in coordinate ix right::KDTree{K,S} # shapes > x in coordinate ix - KDTree{K,S}(s::AbsVec{S}) where {K,S<:Shape{K}} = new(s, collect(1:size(s)[1]), 0) + KDTree{K,S}(s::AbsVec{S}) where {K,S<:Shape{K}} = new(s, collect(eachindex(s)), 0) KDTree{K,S}(s::AbsVec{S},s_index::Vector{<:Int}) where {K,S<:Shape{K}} = new(s, s_index, 0) function KDTree{K,S}(ix::Integer, x::Real, left::KDTree{K,S}, right::KDTree{K,S}) where {K,S<:Shape{K}} 1 ≤ ix ≤ K || throw(BoundsError()) @@ -44,7 +44,7 @@ take precedence over shapes that appear later. function KDTree(s::AbsVec{S}) where {K,S<:Shape{K}} # If no list of indicies is provided, simply enumerate by the number of # shapes in `s`. - return KDTree(s,collect(1:size(s)[1])) + return KDTree(s,collect(eachindex(s))) end function KDTree(s::AbsVec{S}, s_index::Vector{<:Int}) where {K,S<:Shape{K}} From 15e38b49a81aa3a98fa0cb9bb10935899b2deffe Mon Sep 17 00:00:00 2001 From: Alec Hammond Date: Fri, 20 Jan 2023 10:25:30 -0800 Subject: [PATCH 3/6] Use `Integer` not `Int` Co-authored-by: Steven G. Johnson --- src/util/kdtree.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/kdtree.jl b/src/util/kdtree.jl index 4a27328..b62c995 100644 --- a/src/util/kdtree.jl +++ b/src/util/kdtree.jl @@ -47,7 +47,7 @@ function KDTree(s::AbsVec{S}) where {K,S<:Shape{K}} return KDTree(s,collect(eachindex(s))) end -function KDTree(s::AbsVec{S}, s_index::Vector{<:Int}) where {K,S<:Shape{K}} +function KDTree(s::AbsVec{S}, s_index::AbstractVector{<:Integer}) where {K,S<:Shape{K}} (length(s) ≤ 4 || K == 0) && return KDTree{K,S}(s, s_index) # figure out the best dimension ix to divide over, From 5994a2895c2cce703da8fc8048ce408f099e4e5d Mon Sep 17 00:00:00 2001 From: Alec Hammond Date: Wed, 26 Jun 2024 10:08:07 -0700 Subject: [PATCH 4/6] Generalize Makie --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 5bc91f9..35ab11b 100644 --- a/Project.toml +++ b/Project.toml @@ -12,7 +12,7 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [compat] -Makie = "0.20" +Makie = ">= 0.20" julia = "1.7" StaticArrays = "1.5" From 44d44d24a85c5e25552ec7571ef014aa3bec914a Mon Sep 17 00:00:00 2001 From: Alec Hammond Date: Wed, 26 Jun 2024 10:09:55 -0700 Subject: [PATCH 5/6] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 35ab11b..46e6704 100644 --- a/Project.toml +++ b/Project.toml @@ -3,7 +3,7 @@ uuid = "17051e67-205e-509e-8301-03b320b998e6" license = "MIT" desc = "geometric primitives for piecewise functions on grids" authors = ["Steven G. Johnson, Wonseok Shin , and contributors"] -version = "0.5" +version = "0.5.1" [deps] LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" From 3755a5c361a49e3519ea4df748e6f637d93d2357 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Fri, 28 Jun 2024 17:48:23 -0400 Subject: [PATCH 6/6] Update Project.toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 46e6704..8008409 100644 --- a/Project.toml +++ b/Project.toml @@ -12,7 +12,7 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [compat] -Makie = ">= 0.20" +Makie = "0.20, 0.21" julia = "1.7" StaticArrays = "1.5"