diff --git a/Project.toml b/Project.toml index c89cb18f2..12e4a9029 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Meshes" uuid = "eacbb407-ea5a-433e-ab97-5258b1ca43fa" authors = ["JĂșlio Hoffimann and contributors"] -version = "0.40.0" +version = "0.40.1" [deps] Bessels = "0e736298-9ec6-45e8-9647-e4fc86a2fe38" diff --git a/docs/make.jl b/docs/make.jl index a1d1334f2..2fea7d09e 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -51,6 +51,7 @@ makedocs( "algorithms/simplification.md", "algorithms/intersection.md", "algorithms/clipping.md", + "algorithms/clamping.md", "algorithms/merging.md", "algorithms/winding.md", "algorithms/sideof.md", diff --git a/docs/src/algorithms/clamping.md b/docs/src/algorithms/clamping.md new file mode 100644 index 000000000..97f52e53e --- /dev/null +++ b/docs/src/algorithms/clamping.md @@ -0,0 +1,31 @@ +# Clamping + +Meshes adds methods to Julia's built-in `clamp` function. The additional methods clamp points to the edges of a box in any number of dimensions. The target points and boxes must have the same number of dimensions and the same numeric type. + +```@docs +clamp(point::Point{Dim,T}, box::Box{Dim,T}) where {Dim,T} +clamp(points::PointSet{Dim,T}, box::Box{Dim,T}) where {Dim,T} +``` + +```@example clamping +using Meshes # hide +import CairoMakie as Mke # hide + +# set of 2D points to clamp +points = PointSet(rand(2, 100)) + +# 2D box defining the clamping boundaries +box = Box((0.25, 0.25), (0.75, 0.75)) + +# clamp point coordinates to the box edges +clamped = clamp(points, box) + +fig = Mke.Figure(size=(800, 400)) +ax = Mke.Axis(fig[1,1], title="unclamped", aspect=1, limits=(0,1,0,1)) +viz!(ax, box) +viz!(ax, points, color=:black, pointsize=6) +ax = Mke.Axis(fig[1,2], title="clamped", aspect=1, limits=(0,1,0,1)) +viz!(ax, box) +viz!(ax, clamped, color=:black, pointsize=6) +fig +``` \ No newline at end of file diff --git a/docs/src/index.md b/docs/src/index.md index c6a3e5842..1189e265b 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -56,7 +56,7 @@ We are happy to improve the ecosystem to meet user's needs. Get the latest stable release with Julia's package manager: -```julia +``` ] add Meshes ``` diff --git a/src/Meshes.jl b/src/Meshes.jl index 8386e78c4..e139e1bfa 100644 --- a/src/Meshes.jl +++ b/src/Meshes.jl @@ -87,6 +87,7 @@ include("measures.jl") include("boundary.jl") include("merging.jl") include("clipping.jl") +include("clamping.jl") include("intersections.jl") include("complement.jl") include("simplification.jl") diff --git a/src/clamping.jl b/src/clamping.jl new file mode 100644 index 000000000..c8168f093 --- /dev/null +++ b/src/clamping.jl @@ -0,0 +1,20 @@ +""" + clamp(point, box) + +Clamp the coordinates of a [`Point`](@ref) to the edges of a [`Box`](@ref). For each dimension, coordinates outside of the box are moved to the nearest edge of the box. The point and box must have an equal number of dimensions.""" +function Base.clamp(point::Point{Dim,T}, box::Box{Dim,T})::Point{Dim,T} where {Dim,T} + x = coordinates(point) + lo = coordinates(minimum(box)) + hi = coordinates(maximum(box)) + ntuple(Dim) do i + clamp(x[i], lo[i], hi[i]) + end |> Point +end + +""" + clamp(pointset, box) + +Clamp each point in a [`PointSet`](@ref) to the edges of a [`Box`](@ref), returning a new set of points.""" +function Base.clamp(points::PointSet{Dim,T}, box::Box{Dim,T})::PointSet{Dim,T} where {Dim,T} + PointSet(map(point -> clamp(point, box), points)) +end \ No newline at end of file diff --git a/test/clamping.jl b/test/clamping.jl new file mode 100644 index 000000000..1dd5352ea --- /dev/null +++ b/test/clamping.jl @@ -0,0 +1,13 @@ +@testset "Clamping" begin + box = Box((zero(T), zero(T)), (one(T), one(T))) + @test clamp(P2(0.5, 0.5), box) == P2(0.5, 0.5) + @test clamp(P2(-1, 0.5), box) == P2(0, 0.5) + @test clamp(P2(0.5, -1), box) == P2(0.5, 0) + @test clamp(P2(2, 0.5), box) == P2(1, 0.5) + @test clamp(P2(0.5, 2), box) == P2(0.5, 1) + @test clamp(P2(2, 2), box) == P2(1, 1) + @test clamp(P2(-1, -1), box) == P2(0, 0) + + points = PointSet(P2(0.5, 0.5), P2(-1, 0.5), P2(0.5, 2)) + @test clamp(points, box) == PointSet(P2(0.5, 0.5), P2(0, 0.5), P2(0.5, 1)) +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 335de3147..4af165d81 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -98,6 +98,7 @@ testfiles = [ "orientation.jl", "merging.jl", "clipping.jl", + "clamping.jl", "intersections.jl", "complement.jl", "simplification.jl",