diff --git a/Project.toml b/Project.toml index 8078202..422a3af 100644 --- a/Project.toml +++ b/Project.toml @@ -5,6 +5,7 @@ version = "0.0.1" [deps] NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +NearestNeighbors = "b8a86587-4115-5ab1-83bc-aa920d37bbce" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" [compat] diff --git a/docs/src/assets/logo.png b/docs/src/assets/logo.png index d2d672c..5be659a 100644 Binary files a/docs/src/assets/logo.png and b/docs/src/assets/logo.png differ diff --git a/docs/src/gallery.md b/docs/src/gallery.md index 0c39875..c9b2166 100644 --- a/docs/src/gallery.md +++ b/docs/src/gallery.md @@ -27,8 +27,15 @@ heatmap(rand(EdgeGradient(), (45, 45))) heatmap(rand(WaveSurface(), (45, 45))) ``` +## Distance gradient + +```@example gallery +sources = unique(rand(1:2025, 15)) +heatmap(rand(DistanceGradient(sources), (45, 45))) +``` + ## Rectangular cluster ```@example gallery heatmap(rand(RectangularCluster(), (45, 45))) -``` \ No newline at end of file +``` diff --git a/docs/src/index.md b/docs/src/index.md index 0bd2ede..ba03c51 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -10,6 +10,7 @@ NoGradient PlanarGradient EdgeGradient WaveSurface +DistanceGradient RectangularCluster ``` diff --git a/src/NeutralLandscapes.jl b/src/NeutralLandscapes.jl index 0662061..b5ca5d7 100644 --- a/src/NeutralLandscapes.jl +++ b/src/NeutralLandscapes.jl @@ -2,6 +2,7 @@ module NeutralLandscapes import NaNMath using Random: rand! +using NearestNeighbors abstract type NeutralLandscapeMaker end export NeutralLandscapeMaker @@ -21,6 +22,9 @@ export EdgeGradient include(joinpath("algorithms", "wavesurface.jl")) export WaveSurface +include(joinpath("algorithms", "distancegradient.jl")) +export DistanceGradient + include(joinpath("algorithms", "rectangularcluster.jl")) export RectangularCluster diff --git a/src/algorithms/distancegradient.jl b/src/algorithms/distancegradient.jl new file mode 100644 index 0000000..f686d58 --- /dev/null +++ b/src/algorithms/distancegradient.jl @@ -0,0 +1,23 @@ +""" + DistanceGradient + +The `sources` field is the *linear* indices of the matrix, from which the +distance must be calculated. +""" +struct DistanceGradient <: NeutralLandscapeMaker + sources::Vector{Integer} +end + +DistanceGradient() = DistanceGradient([1]) + +function _landscape!(mat, alg::DistanceGradient) + @assert maximum(alg.sources) <= length(mat) + @assert minimum(alg.sources) > 0 + coordinates = Matrix{Float64}(undef, (2, prod(size(mat)))) + for (i, p) in enumerate(Iterators.product(axes(mat)...)) + coordinates[1:2, i] .= p + end + tree = KDTree(coordinates[:,alg.sources]) + mat[:] .= nn(tree, coordinates)[2] + return mat +end diff --git a/src/algorithms/nogradient.jl b/src/algorithms/nogradient.jl index 07d6e43..66b0e5f 100644 --- a/src/algorithms/nogradient.jl +++ b/src/algorithms/nogradient.jl @@ -6,4 +6,4 @@ This type is used to generate a random landscape with no gradients struct NoGradient <: NeutralLandscapeMaker end -_landscape!(mat, ::NoGradient) where {IT <: Integer} = rand!(mat) +_landscape!(mat, ::NoGradient) = rand!(mat)