Skip to content

Commit

Permalink
Upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielVandH committed Sep 15, 2024
1 parent 6f24f16 commit 55a9848
Show file tree
Hide file tree
Showing 21 changed files with 531 additions and 283 deletions.
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 1.4.0

- Updated to AdaptivePredicates.jl v1.2, now allowing caches to be passed to the predicates involving `incircle` and `orient3`. These are only useful when using the `AdaptiveKernel()` kernel. Outside of triangulating, these caches are not passed by default, but can be provided. The functions `get_incircle_cache` and `get_orient3_cache` can be used for this purpose on a triangulation (without a triangulation, refer to AdaptivePredicate.jl's `incircleadapt_cache` and `orient3adapt_cache`).

## 1.3.1

- Fix an issue with a weighted triangulation where the lifted points' convex hull was entirely coplanar. See [#184](https://github.com/JuliaGeometry/DelaunayTriangulation.jl/pull/184)
Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "DelaunayTriangulation"
uuid = "927a84f5-c5f4-47a5-9785-b46e178433df"
authors = ["Daniel VandenHeuvel <danj.vandenheuvel@gmail.com>"]
version = "1.3.1"
version = "1.4.0"

[deps]
AdaptivePredicates = "35492f91-a3bd-45ad-95db-fcad7dcfedb7"
Expand All @@ -10,7 +10,7 @@ ExactPredicates = "429591f6-91af-11e9-00e2-59fbe8cec110"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[compat]
AdaptivePredicates = "1"
AdaptivePredicates = "1.2"
EnumX = "1.0"
ExactPredicates = "2.2"
Random = "1"
Expand Down
1 change: 1 addition & 0 deletions src/DelaunayTriangulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import EnumX
import Random

abstract type AbstractPredicateKernel end # needs to be defined early for use in data_structures.jl
const PredicateCacheType = Union{Nothing, <:Tuple}

include("data_structures.jl")
include("predicates.jl")
Expand Down
12 changes: 9 additions & 3 deletions src/algorithms/point_location/brute_force.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,22 @@ function brute_force_search(tri::Triangulation, q; itr = each_triangle(tri), pre
end

"""
brute_force_search_enclosing_circumcircle(tri::Triangulation, i, predicates::AbstractPredicateKernel=AdaptiveKernel()) -> Triangle
brute_force_search_enclosing_circumcircle(tri::Triangulation, i, predicates::AbstractPredicateKernel=AdaptiveKernel(); cache = nothing) -> Triangle
Searches for a triangle in `tri` containing the vertex `i` in its circumcircle using brute force. If
`tri` is a weighted Delaunay triangulation, the triangle returned instead has the lifted vertex `i`
below its witness plane. If no such triangle exists, `($∅, $∅, $∅)` is returned. You can control
the method used for computing predicates via the `predicates` argument.
The `cache` argument is passed to [`point_position_relative_to_circumcircle`] and should be one of
- `nothing`: No cache is used.
- `get_incircle_cache(tri)`: The cache stored inside `tri`.
- `AdaptivePredicates.incircleadapt_cache(number_type(tri))`: Compute a new cache.
The cache is only needed if an `AdaptiveKernel()` is used.
"""
function brute_force_search_enclosing_circumcircle(tri::Triangulation, i, predicates::AbstractPredicateKernel = AdaptiveKernel())
function brute_force_search_enclosing_circumcircle(tri::Triangulation, i, predicates::AbstractPredicateKernel = AdaptiveKernel(); cache::PredicateCacheType = nothing)
for V in each_triangle(tri)
cert = point_position_relative_to_circumcircle(predicates, tri, V, i)
cert = point_position_relative_to_circumcircle(predicates, tri, V, i; cache)
!is_outside(cert) && return V
end
tri_type = triangle_type(tri)
Expand Down
2 changes: 1 addition & 1 deletion src/algorithms/triangulation/basic_operations/add_point.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function add_point!(
end
q = get_point(tri, new_point)
if is_weighted(tri)
cert = point_position_relative_to_circumcircle(predicates, tri, V, new_point) # redirects to point_position_relative_to_witness_plane
cert = point_position_relative_to_circumcircle(predicates, tri, V, new_point; cache = get_orient3_cache(tri)) # redirects to point_position_relative_to_witness_plane
is_outside(cert) && return V # If the point is submerged, then we don't add it
end
flag = point_position_relative_to_triangle(predicates, tri, V, q)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ There is no output, as `tri` is updated in-place.
so that at a triangle that might have appeared in both will only appear in one.
"""
function legalise_edge!(tri::Triangulation, i, j, r, store_event_history = Val(false), event_history = nothing; predicates::AbstractPredicateKernel = AdaptiveKernel())
cert = is_legal(predicates, tri, i, j)
cert = is_legal(predicates, tri, i, j; cache = get_incircle_cache(tri))
if is_illegal(cert)
e = get_adjacent(tri, j, i)
flip_edge!(tri, i, j, e, r, store_event_history, event_history)
Expand Down
2 changes: 1 addition & 1 deletion src/algorithms/triangulation/constrained_triangulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ function add_point_cavity_cdt!(tri::Triangulation, u, v, w, marked_vertices, pre
insert_flag = true
else
p, q, r, s = get_point(tri, w, v, x, u) # Don't want to deal with boundary handling here
incircle_test = point_position_relative_to_circle(predicates, p, q, r, s)
incircle_test = point_position_relative_to_circle(predicates, p, q, r, s; cache = get_incircle_cache(tri))
orient_test = triangle_orientation(predicates, tri, u, v, w)
insert_flag = !is_inside(incircle_test) && is_positively_oriented(orient_test)
end
Expand Down
2 changes: 1 addition & 1 deletion src/algorithms/triangulation/triangulate_convex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ to make.
"""
function add_point_convex_triangulation!(tri::Triangulation, u, v, w, S, predicates::AbstractPredicateKernel = AdaptiveKernel())
x = get_adjacent(tri, w, v)
if edge_exists(x) && is_inside(point_position_relative_to_circumcircle(predicates, tri, u, v, w, x))
if edge_exists(x) && is_inside(point_position_relative_to_circumcircle(predicates, tri, u, v, w, x; cache = get_incircle_cache(tri)))
# uvw and wvx are not Delaunay
delete_triangle!(tri, w, v, x; protect_boundary = true, update_ghost_edges = false)
add_point_convex_triangulation!(tri, u, v, x, S, predicates)
Expand Down
6 changes: 3 additions & 3 deletions src/algorithms/triangulation/unconstrained_triangulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ function add_point_bowyer_watson!(tri::Triangulation, new_point, initial_search_
q = get_point(tri, _new_point)
V = find_triangle(tri, q; predicates, m = nothing, point_indices = nothing, try_points = nothing, k = initial_search_point, rng)
if is_weighted(tri)
cert = point_position_relative_to_circumcircle(predicates, tri, V, _new_point) # redirects to point_position_relative_to_witness_plane
cert = point_position_relative_to_circumcircle(predicates, tri, V, _new_point; cache = get_orient3_cache(tri)) # redirects to point_position_relative_to_witness_plane
is_outside(cert) && return V # If the point is submerged, then we don't add it
end
flag = point_position_relative_to_triangle(predicates, tri, V, q)
Expand Down Expand Up @@ -298,9 +298,9 @@ Determines whether to enter the cavity in `tri` through the edge `(i, j)` when i
function enter_cavity(tri::Triangulation, r, i, j, ℓ, predicates::AbstractPredicateKernel = AdaptiveKernel())
contains_segment(tri, i, j) && return false
if is_ghost_vertex(ℓ)
cert = point_position_relative_to_circumcircle(tri, j, i, ℓ, r)
cert = point_position_relative_to_circumcircle(predicates, tri, j, i, ℓ, r; cache = get_incircle_cache(tri))
else
cert = point_position_relative_to_circumcircle(tri, r, i, j, ℓ)
cert = point_position_relative_to_circumcircle(predicates, tri, r, i, j, ℓ; cache = get_incircle_cache(tri))
end
return is_weighted(tri) ? !is_outside(cert) : is_inside(cert)
end
Expand Down
36 changes: 26 additions & 10 deletions src/data_structures/triangulation/methods/weights.jl
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,24 @@ function get_power_distance(tri::Triangulation, i, j)
end

""""
get_distance_to_witness_plane(tri::Triangulation, i, V) -> Number
get_distance_to_witness_plane([kernel::AbstractPredicateKernel = AdaptiveKernel(), ] tri::Triangulation, i, V; cache = nothing) -> Number
Computes the distance between the lifted companion of the vertex `i` and the witness plane to the triangle `V`. If `V` is a ghost triangle
and `i` is not on its solid edge, then the distance is `-Inf` if it is below the ghost triangle's witness plane and `Inf` if it is above. If `V` is a ghost triangle and `i`
is on its solid edge, then the distance returned is the distance associated with the solid triangle adjoining `V`.
In general, the distance is positive if the lifted vertex is above the witness plane, negative if it is below,
and zero if it is on the plane.
The `kernel` argument determines how this result is computed, and should be
one of [`ExactKernel`](@ref), [`FastKernel`](@ref), and [`AdaptiveKernel`](@ref) (the default).
See the documentation for more information about these choices.
The `cache` keyword argument is passed to [`point_position_relative_to_circumcircle`]. Please see the documentation for that function for more information.
See also [`point_position_relative_to_witness_plane`](@ref) and [`get_distance_to_plane`](@ref).
"""
function get_distance_to_witness_plane(tri::Triangulation, i, V)
function get_distance_to_witness_plane(kernel::AbstractPredicateKernel, tri::Triangulation, i, V; cache::PredicateCacheType = nothing)
if !is_ghost_triangle(V)
u, v, w = triangle_vertices(V)
p⁺ = get_lifted_point(tri, u)
Expand All @@ -118,17 +124,19 @@ function get_distance_to_witness_plane(tri::Triangulation, i, V)
s⁺ = get_lifted_point(tri, i)
return get_distance_to_plane(p⁺, q⁺, r⁺, s⁺)
else
cert = point_position_relative_to_circumcircle(tri, V, i)
cert = point_position_relative_to_circumcircle(kernel, tri, V, i; cache)
if is_inside(cert)
return -Inf
elseif is_outside(cert)
return Inf
else # is_on(cert)
V′ = replace_ghost_triangle_with_boundary_triangle(tri, V)
return get_distance_to_witness_plane(tri, i, V′)
return get_distance_to_witness_plane(kernel, tri, i, V′; cache)
end
end
end
get_distance_to_witness_plane(tri::Triangulation, i, V; cache::PredicateCacheType = nothing) = get_distance_to_witness_plane(AdaptiveKernel(), tri, i, V; cache)


"""
get_weighted_nearest_neighbour(tri::Triangulation, i, j = rand(each_solid_vertex(tri))) -> Vertex
Expand Down Expand Up @@ -164,24 +172,32 @@ function _get_weighted_nearest_neighbour(tri, i, j)
end

@doc """
is_submerged(tri::Triangulation, i) -> Bool
is_submerged(tri::Triangulation, i, V) -> Bool
is_submerged([kernel::AbstractPredicateKernel = AdaptiveKernel(), ] tri::Triangulation, i; cache = nothing) -> Bool
is_submerged([kernel::AbstractPredicateKernel = AdaptiveKernel(), ] tri::Triangulation, i, V; cache = nothing) -> Bool
Returns `true` if the vertex `i` is submerged in `tri` and `false` otherwise. In the
second method, `V` is a triangle containing `tri`.
The `kernel` argument determines how this result is computed, and should be
one of [`ExactKernel`](@ref), [`FastKernel`](@ref), and [`AdaptiveKernel`](@ref) (the default).
See the documentation for more information about these choices.
The `cache` keyword argument is passed to [`point_position_relative_to_circumcircle`]. Please see the documentation for that function for more information.
"""
is_submerged
function is_submerged(tri::Triangulation, i)
function is_submerged(kernel::AbstractPredicateKernel, tri::Triangulation, i; cache::PredicateCacheType = nothing)
# A source that mentions that testing if `i` is submerged only needs to consider the triangle that contains it
# is given in https://otik.uk.zcu.cz/bitstream/11025/21574/1/Zemek.pdf on p.17.
# (If the link dies, it is the PhD thesis of Michal Zemek, "Regular Triangulation in 3D and Its Applications".)
is_ghost_vertex(i) && return false
q = get_point(tri, i)
V = find_triangle(tri, q)
return is_submerged(tri, i, V)
return is_submerged(kernel, tri, i, V; cache)
end
function is_submerged(tri::Triangulation, i, V)
function is_submerged(kernel::AbstractPredicateKernel, tri::Triangulation, i, V; cache::PredicateCacheType = nothing)
is_ghost_vertex(i) && return false
cert = point_position_relative_to_circumcircle(tri, V, i)
cert = point_position_relative_to_circumcircle(kernel, tri, V, i; cache)
return is_outside(cert)
end
is_submerged(tri::Triangulation, i; cache::PredicateCacheType = nothing) = is_submerged(AdaptiveKernel(), tri, i; cache)
is_submerged(tri::Triangulation, i, V; cache::PredicateCacheType = nothing) = is_submerged(AdaptiveKernel(), tri, i, V; cache)
Loading

0 comments on commit 55a9848

Please sign in to comment.