Geometrical Predicates
This section discusses how geometrical predicates are defined in this package. The predicates in this package are primarily derived from those implemented in ExactPredicates.jl and AdaptivePredicates.jl. The choice of robust predicates is important for the robustness of the algorithms in this package. Without using robust predicates, you may quickly find issues such as infinite loops or errors in the algorithms, as discussed for example at the start of p.3 of these notes by Shewchuk. A discussion of the three predicate kernels available in this package, namely FastKernel()
, AdaptiveKernel()
, and ExactKernel()
, are discussed in detail here.
Certificates
All predicates defined in this package return a Certificate
which simply specifies the result of the predicate. This is easier than working with Bool
s only as (1) not all predicates have only two outcomes and (2) it is easier to see the certificate than to remember exactly what outcome is represented by a Bool
. For example:
using DelaunayTriangulation
p, q, r = (0.0, 0.0), (1.0, 0.0), (0.0, 1.0)
flag = DelaunayTriangulation.triangle_orientation(p, q, r)
Certificate.PositivelyOriented = 6
We could then inspect the result using e.g.
DelaunayTriangulation.is_positively_oriented(flag)
true
Predicates
The predicates we define are implemented in a function with a _predicate
suffix that then dispatches based on the provided kernel. The base predicates we define are:
These last three predicates are taken from ExactPredicates.jl. Almost all other geometric predicates are derived from these five, e.g. triangle_orientation
and point_position_relative_to_line
. Predicates for working with the boundary and ghost vertices are also implemented, for example, is_ghost_edge
and is_boundary_node
.