Skip to content

Commit

Permalink
Merge pull request #38 from asinghvi17/patch-1
Browse files Browse the repository at this point in the history
Add comments explaining `compute_bowyer_envelope!`
  • Loading branch information
DanielVandH authored Jul 28, 2024
2 parents 55c837a + d324aa9 commit 13b807d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 13 deletions.
28 changes: 25 additions & 3 deletions src/interpolation/utils.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
function compute_bowyer_envelope!(envelope, tri::Triangulation, history::InsertionEventHistory, temp_adjacent::Adjacent, point; kwargs...) #kwargs are add_point! kwargs
#=
`add_point!` uses the Bowyer-Watson algorithm to add points.
The Bowyer-Watson algorithm removes all triangles whose circumcenters contain
the point to be inserted, creating a hole which is then retriangulated with the
new point included.
What happens here is that we record the new triangles added in `history`, and then
extract those triangles - we know that these changed after the new point was added,
so they are the "natural neighbours" of the new point.
=#
empty!(history)
empty!(envelope)
empty!(get_adjacent(temp_adjacent))
n = num_points(tri)
I = integer_type(tri)
# Note that the `peek` keyword here indicates that the original triangulation
# is never modified - but the new triangles are added to `history`.
V = add_point!(tri, point; store_event_history=Val(true), event_history=history, peek=Val(true), kwargs...)
all_triangles = each_added_triangle(history)
if isempty(all_triangles) # This is possible for constrained triangulations
# To clarify, this means that no triangles were added. This means the point
# has no natural neighbours.
return envelope, temp_adjacent, history, V
end
# Add triangles to the `DelaunayTriangulation.Adjacent` dict,
# which stores the ((u, v)::Edge => w::Point` adjacency relationship.
for T in all_triangles
add_triangle!(temp_adjacent, T)
end
Expand All @@ -17,10 +33,16 @@ function compute_bowyer_envelope!(envelope, tri::Triangulation, history::Inserti
v = i == I(n + 1) ? j : i # get a vertex on the envelope
push!(envelope, v)
for i in 2:num_triangles(all_triangles)
v = get_adjacent(temp_adjacent, I(n + 1), v)
#=
Get the vertex associated with the edge `(point, points[v])` such that the
returned point (the new `v`) forms a positively oriented triangle
with that edge. Then, add the newly found `v` to the envelope.
To be clear, `n+1` is the index of the newly inserted vertex in the triangulation.
=#
v = get_adjacent(temp_adjacent, I(n + 1), v)
push!(envelope, v)
end
push!(envelope, envelope[begin])
push!(envelope, envelope[begin]) # Close out the envelope polygon
return envelope, temp_adjacent, history, V
end
function compute_bowyer_envelope!(envelope, tri::Triangulation, point; kwargs...)
Expand Down Expand Up @@ -241,4 +263,4 @@ function hessian_form(tri, u, v, w, N₀, H) # zᵢ,ⱼₖ
dxᵢₖ = xₖ[1] - xᵢ[1]
dyᵢₖ = xₖ[2] - xᵢ[2]
return dxᵢⱼ * (dxᵢₖ * B₁₁ + dyᵢₖ * B₁₂) + dyᵢⱼ * (dxᵢₖ * B₁₂ + dyᵢₖ * B₂₂)
end
end
20 changes: 10 additions & 10 deletions test/doc_examples/differentiation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ tri = triangulate(points)
∇g = generate_gradients(tri, z)
fig, ε = plot_gradients(∇g, tri, f′, x, y)
@test_reference normpath(@__DIR__, "../..", "docs", "src", "figures", "gradient_data.png") fig
@test ε 10.2511800
@test ε 10.2511800 rtol=1e-3

∇gr, _ = generate_derivatives(tri, z; method=Direct())
fig, ε = plot_gradients(∇gr, tri, f′, x, y)
@test_reference normpath(@__DIR__, "../..", "docs", "src", "figures", "joint_gradient_data.png") fig
@test ε 7.7177915977
@test ε 7.7177915977 rtol=1e-3

# Hessians
to_mat(H::NTuple{3,Float64}) = [H[1] H[3]; H[3] H[2]]
Expand All @@ -128,17 +128,17 @@ function plot_hessians(H, tri, f′′, x, y)
end
_, Hg = generate_derivatives(tri, z)
fig, ε = plot_hessians(Hg, tri, f′′, x, y)
@test ε 42.085578794
@test ε 42.085578794 rtol=1e-3
@test_reference normpath(@__DIR__, "../..", "docs", "src", "figures", "hessian_data.png") fig

_, Hg = generate_derivatives(tri, z, use_cubic_terms=false)
fig, ε = plot_hessians(Hg, tri, f′′, x, y)
@test ε 35.20873081
@test ε 35.20873081 rtol=1e-3
@test_reference normpath(@__DIR__, "../..", "docs", "src", "figures", "hessian_data_no_cubic.png") fig

_, Hg = generate_derivatives(tri, z, method=Iterative()) # the gradients will be generated first automatically
fig, ε = plot_hessians(Hg, tri, f′′, x, y)
@test ε 39.584816
@test ε 39.584816 rtol=1e-3
@test_reference normpath(@__DIR__, "../..", "docs", "src", "figures", "hessian_data_iterative.png") fig

# Away from the data sites
Expand Down Expand Up @@ -190,7 +190,7 @@ function plot_gradients(∇g, f′, xg, yg)
end
fig, ε = plot_gradients(∇g, f′, xg, yg)
@test_reference normpath(@__DIR__, "../..", "docs", "src", "figures", "gradient_surface.png") fig
@test ε 13.1857476
@test ε 13.1857476 rtol=1e-1

other_methods = [Sibson(), Laplace(), Nearest(), Triangle()]
∇gs = [(_x, _y; interpolant_method=method) for method in other_methods]
Expand Down Expand Up @@ -236,8 +236,8 @@ figH, εH = plot_hessians(Hg, f′′, xg, yg)
zlims!(figH.content[4], -25, 25)
@test_reference normpath(@__DIR__, "../..", "docs", "src", "figures", "hessian_surface_direct.png") figH
@test_reference normpath(@__DIR__, "../..", "docs", "src", "figures", "gradient_surface_2_direct.png") fig∇
@test εH 46.7610990050276
@test ε∇ 9.853286514069882
@test εH 46.7610990050276 rtol=1e-1
@test ε∇ 9.853286514069882 rtol=1e-1

function rrmserr(z, ẑ, ∂, x, y)
tri =.interpolant.triangulation
Expand All @@ -259,5 +259,5 @@ end

εH_nohull = rrmserr(f′′.(_x, _y), to_mat.(Hg), ∂, _x, _y)
ε∇_nohull = rrmserr(f′.(_x, _y), ∇g, ∂, _x, _y)
@test ε∇_nohull 7.479964687673911
@test εH_nohull 38.884740966379056
@test ε∇_nohull 7.479964687673911 rtol=1e-2
@test εH_nohull 38.884740966379056 rtol=1e-2

0 comments on commit 13b807d

Please sign in to comment.