`DelaunayTriangulation.InvalidBoundingBox`

— Constant`InvalidBoundingBox`

A constant for representing an invalid rectangle, i.e. a rectangle with `NaN`

endpoints.

`DelaunayTriangulation.InvalidBoundingInterval`

— Constant`InvalidBoundingInterval`

A constant for representing an invalid interva`BoundingInterval`

, i.e. an interval with `NaN`

endpoints.

`DelaunayTriangulation.AbstractBoundingShape`

— Type`abstract type AbstractBoundingShape`

Abstract type for representing a bounding box.

`DelaunayTriangulation.AbstractEachEdge`

— Type`AbstractEachEdge{E}`

An abstract type for an iterator over edges in a triangulation.

`DelaunayTriangulation.AbstractEachTriangle`

— Type`AbstractEachTriangle{T}`

An abstract type for an iterator over triangles in a triangulation.

`DelaunayTriangulation.AbstractEachVertex`

— Type`AbstractEachVertex{V}`

An abstract type for an iterator over vertices in a triangulation.

`DelaunayTriangulation.AbstractNode`

— Type`abstract type AbstractNode end`

Abstract type for representing a node in an R-tree.

`DelaunayTriangulation.AbstractParametricCurve`

— Type`abstract type AbstractParametricCurve <: Function end`

Abstract type for representing a parametric curve parametrised over `0 ≤ t ≤ 1`

. The curves represented by this abstract type should not be self-intersecting, with the exception of allowing for closed curves.

The structs that subtype this abstract type must implement are:

`differentiate`

.`twice_differentiate`

.`thrice_differentiate`

(only if you have not manually defined`total_variation`

).- The struct must be callable so that
`c(t)`

, where`c`

an instance of the struct, returns the associated value of the curve at`t`

. - If the struct does not implement
`point_position_relative_to_curve`

, then the struct must implement`get_closest_point`

. Alternatively, rather than implementing`get_closest_point`

, the struct should have a`lookup_table`

field as a`Vector{NTuple{2,Float64}}`

, which returns values on the curve at a set of points, where`lookup_table[i]`

is the value of the curve at`t = (i - 1) / (length(lookup_table) - 1)`

.

Functions that are defined for all `AbstractParametricCurve`

subtypes are:

The curves in this package evaluate the total variation not by evaluating the integral itself, but by taking care of the changes in orientation in the curve to efficiently compute it. This is done by using the orientation markers of the curves, obtained using `orientation_markers`

, that stored in the field `orientation_markers`

of these curves. The function `marked_total_variation`

is then used to evaluate it. You may like to consider using these functions for any curve you wish to implement yourself, using e.g. the `BezierCurve`

struct's implementation as a reference.

`DelaunayTriangulation.Adjacent`

— Type`Adjacent{IntegerType, EdgeType}`

Struct for storing adjacency relationships for a triangulation.

**Fields**

`adjacent::Dict{EdgeType, IntegerType}`

The map taking edges `(u, v)`

to `w`

such that `(u, v, w)`

is a positively oriented triangle in the underlying triangulation.

**Constructors**

```
Adjacent{IntegerType, EdgeType}()
Adjacent(adjacent::Dict{EdgeType, IntegerType})
```

`DelaunayTriangulation.Adjacent2Vertex`

— Type`Adjacent2Vertex{IntegerType, EdgesType}`

Struct for connectivity information about edges relative to vertices for a triangulation.

**Fields**

`adjacent2vertex::Dict{IntegerType, EdgesType}`

The map taking `w`

to the set of all `(u, v)`

such that `(u, v, w)`

is a positively oriented triangle in the underlying triangle.

**Constructors**

```
Adjacent2Vertex{IntegerType, EdgesType}()
Adjacent2Vertex(adj2v::Dict{IntegerType, EdgesType})
```

`DelaunayTriangulation.BSpline`

— Type`BSpline <: AbstractParametricCurve`

Curve for representing a BSpline, parametrised over `0 ≤ t ≤ 1`

. This curve can be evaluated using `b_spline(t)`

and returns a tuple `(x, y)`

of the coordinates of the point on the curve at `t`

.

See also `BezierCurve`

and `CatmullRomSpline`

.

Our implementation of a BSpline is based on https://github.com/thibauts/b-spline.

This curve is only tested on loop-free curves (and closed curves that otherwise have no self-intersections). It is not guaranteed to work on curves with loops, especially for finding the nearest point on the curve to a given point.

Remember that B-spline curves are not interpolation curves. They only go through the first and last control points, but not the intermediate ones. For an interpolating spline, see `CatmullRomSpline`

.

**Fields**

`control_points::Vector{NTuple{2,Float64}}`

: The control points of the BSpline. The curve goes through the first and last control points, but not the intermediate ones.`knots::Vector{Int}`

: The knots of the BSpline. You should not modify or set this field directly (in particular, do not expect any support for non-uniform B-splines).`cache::Vector{NTuple{2,Float64}}`

: A cache of the points on the curve. This is used to speed up evaluation of the curve using de Boor's algorithm.`lookup_table::Vector{NTuple{2,Float64}}`

: A lookup table for the B-spline curve, used for finding the point on the curve closest to a given point. The`i`

th entry of the lookup table corresponds to the`t`

-value`i / (length(lookup_table) - 1)`

.`orientation_markers::Vector{Float64}`

: The orientation markers of the curve. These are defined so that the orientation of the curve is monotone between any two consecutive markers. The first and last markers are always`0`

and`1`

, respectively. See`orientation_markers`

.

**Constructor**

You can construct a `BSpline`

using

`BSpline(control_points::Vector{NTuple{2,Float64}}; degree=3, lookup_steps=5000, kwargs...)`

The keyword argument `lookup_steps`

is used to build the lookup table for the curve. Note that the default `degree=3`

corresponds to a cubic B-spline curve. The `kwargs...`

are keyword arguments passed to `orientation_markers`

.

`DelaunayTriangulation.BalancedBST`

— Type`mutable struct BalancedBST{K}`

Struct representing a balanced binary search tree.

**Fields**

`root::Union{Nothing,BalancedBSTNode{K}}`

: The root of the tree.`count::Int32`

: The number of nodes in the tree.

Nodes with duplicate keys are not supported. If a duplicate key is inserted, the tree will not be modified.

`DelaunayTriangulation.BalancedBST`

— Method`BalancedBST{K}() where {K}`

Constructs a new empty balanced binary search tree.

`DelaunayTriangulation.BalancedBSTNode`

— Type`mutable struct BalancedBSTNode{K}`

Struct representing a node in a balanced binary search tree.

**Fields**

`key::K`

: The key associated with the node.`height::Int8`

: The height of the node.`count::Int32`

: The number of nodes in the subtree rooted at this node, including this node.`parent::Union{Nothing,BalancedBSTNode{K}}`

: The parent of the node.`left::Union{Nothing,BalancedBSTNode{K}}`

: The left child of the node.`right::Union{Nothing,BalancedBSTNode{K}}`

: The right child of the node.

**Constructor**

`BalancedBSTNode(key::K) where {K}`

Constructs a new node with key `key`

, height `1`

, and count `1`

. The parent, left child, and right child are set to `nothing`

.

`DelaunayTriangulation.BezierCurve`

— Type`BezierCurve <: AbstractParametricCurve`

Curve for representing a Bezier curve, parametrised over `0 ≤ t ≤ 1`

. This curve can be evaluated using `bezier_curve(t)`

and returns a tuple `(x, y)`

of the coordinates of the point on the curve at `t`

.

A good reference on Bezier curves is this.

See also `BSpline`

and `CatmullRomSpline`

.

This curve is only tested on loop-free curves (and closed curves that otherwise have no self-intersections). It is not guaranteed to work on curves with loops, especially for finding the nearest point on the curve to a given point.

Remember that Bezier curves are not interpolation curves. They only go through the first and last control points, but not the intermediate ones. If you want an interpolation curve, use `CatmullRomSpline`

.

**Fields**

`control_points::Vector{NTuple{2,Float64}}`

: The control points of the Bezier curve. The curve goes through the first and last control points, but not the intermediate ones.`cache::Vector{NTuple{2,Float64}}`

: A cache of the points on the curve. This is used to speed up evaluation of the curve using de Casteljau's algorithm.`lookup_table::Vector{NTuple{2,Float64}}`

: A lookup table for the Bezier curve, used for finding the point on the curve closest to a given point. The`i`

th entry of the lookup table corresponds to the`t`

-value`i / (length(lookup_table) - 1)`

.`orientation_markers::Vector{Float64}`

: The orientation markers of the curve. These are defined so that the orientation of the curve is monotone between any two consecutive markers. The first and last markers are always`0`

and`1`

, respectively. See`orientation_markers`

.

The cache is not thread-safe, and so you should not evaluate this curve in parallel.

**Constructor**

You can construct a `BezierCurve`

using

`BezierCurve(control_points::Vector{NTuple{2,Float64}}; lookup_steps=5000, kwargs...)`

The keyword argument `lookup_steps=100`

controls how many time points in `[0, 1]`

are used for the lookup table. The `kwargs...`

are keyword arguments passed to `orientation_markers`

.

`DelaunayTriangulation.BoundaryEnricher`

— Type`BoundaryEnricher{P,B,C,I,BM,S}`

Struct used for performing boundary enrichment on a curve-bounded boundary.

See also `enrich_boundary!`

.

**Fields**

`points::P`

: The point set.`boundary_nodes::B`

: The boundary nodes.`segments::S`

: The segments.`boundary_curves::C`

: The boundary curves.`polygon_hierarchy::PolygonHierarchy{I}`

: The polygon hierarchy.`parent_map::Dict{NTuple{2,I},I}`

: A map from an edge, represented as a`Tuple`

, to the index of the parent curve in`boundary_curves`

.`curve_index_map::Dict{I,I}`

: A map from a curve index to the index of the curve in`boundary_curves`

.`boundary_edge_map::B`

: A map from a boundary node to the index of the curve in`boundary_curves`

that it belongs to. See`construct_boundary_edge_map`

.`spatial_tree::BoundaryRTree{P}`

: The`BoundaryRTree`

used for spatial indexing.`queue::Queue{I}`

: A queue used for processing vertices during enrichment.`small_angle_complexes::Dict{I,Vector{SmallAngleComplex{I}}}`

: A map from an apex vertex to a list of all curves that define a small angle complex associated with that apex vertex.

The first three fields should be those associated with `convert_boundary_curves!`

.

**Constructor**

`BoundaryEnricher(points, boundary_nodes; IntegerType=Int, n=4096, coarse_n=0)`

This constructor will use `convert_boundary_curves!`

to convert `points`

and `boundary_nodes`

into a set of boundary curves and modified boundary nodes suitable for enrichment. The boundary nodes field will no longer aliased with the input `boundary_nodes`

, although `points`

will be. The polygon hierarchy is computed using `construct_polygon_hierarchy`

. The argument `n`

is used in `polygonise`

for filling out the boundary temporarily in order to construct the `PolygonHierarchy`

. The argument `coarse_n`

defines the initial coarse discretisation through `coarse_discretisation!`

; the default `n=0`

means that the coarse discretisation will be performed until the maximum total variation of a subcurve is less than π/2.

`DelaunayTriangulation.BoundaryRTree`

— Type`BoundaryRTree{P}`

Type for representing an R-tree of a boundary with an associated point set. The rectangular elements of the R-tree are the bounding box of the diametral circles of the boundary edges.

**Fields**

`tree::RTree`

: The R-tree.`points::P`

: The point set.

**Constructors**

`BoundaryRTree(points)`

`DelaunayTriangulation.BoundingBox`

— Type`BoundingBox <: AbstractBoundingShape`

Type for representing an axis-aligned bounding box, represented as a pair of interval `I`

and `J`

so that the bounding box is `I × J`

.

**Fields**

`x::BoundingInterval`

: The interval for the x-axis.`y::BoundingInterval`

: The interval for the y-axis.

**Constructors**

```
BoundingBox(x::BoundingInterval, y::BoundingInterval)
BoundingBox(a::Float64, b::Float64, c::Float64, d::Float64) = BoundingBox(BoundingInterval(a, b), BoundingInterval(c, d))
BoundingBox(p::NTuple{2,<:Number}) = BoundingBox(p[1], p[1], p[2], p[2])
```

`DelaunayTriangulation.BoundingInterval`

— Type`BoundingInterval <: AbstractBoundingShape`

Type for representing a bounding interval `[a, b]`

.

**Fields**

`a::Float64`

: The left endpoint.`b::Float64`

: The right endpoint.

`DelaunayTriangulation.Branch`

— Type`mutable struct Branch <: AbstractNode`

Type for representing a branch node in an R-tree.

**Fields**

`parent::Union{Branch, Nothing}`

: The parent of the branch node.`bounding_box::BoundingBox`

: The bounding box of the branch node.`children::Union{Vector{Branch},Vector{Leaf{Branch}}}`

: The children of the branch node.`level::Int`

: The level of the branch node.

**Constructor**

`Branch(parent::Union{Branch,Nothing}=nothing, ::Type{C}=Branch) where {C<:AbstractNode} = new(parent, InvalidBoundingBox, C[], 1)`

`DelaunayTriangulation.BranchCache`

— Type`BranchCache`

Type for representing a cache of branch nodes.

`DelaunayTriangulation.CatmullRomSpline`

— Type`CatmullRomSpline <: AbstractParametricCurve`

Curve for representing a Catmull-Rom spline, parametrised over `0 ≤ t ≤ 1`

. This curve can be evaluated using `catmull_rom_spline(t)`

and returns a tuple `(x, y)`

of the coordinates of the point on the curve at `t`

.

For information on these splines, see e.g. this article and this article. Additionally, this article lists some nice properties of these splines.

This curve is only tested on loop-free curves (and closed curves that otherwise have no self-intersections). It is not guaranteed to work on curves with loops, especially for finding the nearest point on the curve to a given point.

Typically, Catmull-Rom splines are defined on segments of four control points, and drawn between the two interior control points. This creates an issue in that the first and last control points will not be joined to the spline. To overcome this, we extend the spline to the left and right during the evaluation of a spline, using the fields `left`

and `right`

defined below. The rules used for extending these points come from CatmullRom.jl, which extrapolates based on a Thiele-like cubic polynomial.

**Fields**

`control_points::Vector{NTuple{2,Float64}}`

: The control points of the Catmull-Rom spline. The curve goes through each point.`knots::Vector{Float64}`

: The parameter values of the Catmull-Rom spline. The`i`

th entry of this vector corresponds to the`t`

-value associated with the`i`

th control point. With an alpha parameter`α`

, these values are given by`knots[i+1] = knots[i] + dist(control_points[i], control_points[i+1])^α`

, where`knots[1] = 0`

, and the vector is the normalised by dividing by`knots[end]`

.`lookup_table::Vector{NTuple{2,Float64}}`

: A lookup table for the Catmull-Rom spline, used for finding the point on the curve closest to a given point. The`i`

th entry of the lookup table corresponds to the`t`

-value`i / (length(lookup_table) - 1)`

.`alpha::Float64`

: The alpha parameter of the Catmull-Rom spline. This controls the type of the parametrisation, where`alpha = 0`

corresponds to uniform parametrisation,`alpha = 1/2`

corresponds to centripetal parametrisation, and`alpha = 1`

corresponds to chordal parametrisation. Must be in`[0, 1]`

. For reasons similar to what we describe for`tension`

below, we only support`alpha = 1/2`

for now. (If you do really want to change it, use the`_alpha`

keyword argument in the constructor.)`tension::Float64`

: The tension parameter of the Catmull-Rom spline. This controls the tightness of the spline, with`tension = 0`

being the least tight, and`tension = 1`

leading to straight lines between the control points. Must be in`[0, 1]`

. You can not currently set this to anything except`0.0`

due to numerical issues with boundary refinement. (For example, equivariation splits are not possible if`tension=1`

since the curve is piecewise linear in that case, and for`tension`

very close to`1`

, the equivariation split is not always between the provided times. If you*really*want to change it, then you can use the`_tension`

keyword argument in the constructor - but be warned that this may lead to numerical issues and potentially infinite loops.)`left::NTuple{2,Float64}`

: The left extension of the spline. This is used to evaluate the spline on the first segment.`right::NTuple{2,Float64}`

: The right extension of the spline. This is used to evaluate the spline on the last segment.`lengths::Vector{Float64}`

: The lengths of the individual segments of the spline.`segments::Vector{CatmullRomSplineSegment}`

: The individual segments of the spline.`orientation_markers::Vector{Float64}`

: The orientation markers of the curve. These are defined so that the orientation of the curve is monotone between any two consecutive markers. The first and last markers are always`0`

and`1`

, respectively. See`orientation_markers`

.

**Constructor**

To construct a `CatmullRomSpline`

, use

`CatmullRomSpline(control_points::Vector{NTuple{2,Float64}}; lookup_steps=5000, kwargs...)`

The keyword argument `lookup_steps`

is used to build the lookup table for the curve, with `lookup_steps`

giving the number of time points in `[0, 1]`

used for the lookup table. The `kwargs...`

are keyword arguments passed to `orientation_markers`

.

`DelaunayTriangulation.CatmullRomSplineSegment`

— Type`CatmullRomSplineSegment <: AbstractParametricCurve`

A single segment of a Camtull-Rom spline, representing by a cubic polynomial. Note that evaluating this curve will only draw within the two interior control points of the spline.

Based on this article.

**Fields**

`a::NTuple{2,Float64}`

: The coefficient on`t³`

.`b::NTuple{2,Float64}`

: The coefficient on`t²`

.`c::NTuple{2,Float64}`

: The coefficient on`t`

.`d::NTuple{2,Float64}`

: The constant in the polynomial.`p₁::NTuple{2,Float64}`

: The second control point of the segment.`p₂::NTuple{2,Float64}`

: The third control point of the segment.

With these fields, the segment is parametrised over `0 ≤ t ≤ 1`

by `q(t)`

, where

`q(t) = at³ + bt² + ct + d,`

and `q(0) = p₁`

and `q(1) = p₂`

, where the segment is defined by four control points `p₀`

, `p₁`

, `p₂`

, and `p₃`

.

This struct is callable, returning the interpolated point `(x, y)`

at `t`

as a `NTuple{2,Float64}`

.

**Constructor**

To construct this segment, use

`catmull_rom_spline_segment(p₀, p₁, p₂, p₃, α, τ)`

Here, `p₀`

, `p₁`

, `p₂`

, and `p₃`

are the four points of the segment (not `a`

, `b`

, `c`

, and `d`

), and `α`

and `τ`

are the parameters of the spline. The parameter `α`

controls the type of the parametrisation, where

`α = 0`

: Uniform parametrisation.`α = 1/2`

: Centripetal parametrisation.`α = 1`

: Chordal parametrisation.

The parameter `τ`

is the tension, and controls the tightness of the segment. `τ = 0`

is the least tight, while `τ = 1`

leads to straight lines between the control points. Both `α`

and `τ`

must be in `[0, 1]`

.

`DelaunayTriangulation.Cell`

— Type`Cell{T}`

A cell in a grid. The cell is a square with side length `2half_width`

. The cell is centered at `(x, y)`

. The cell is assumed to live in a polygon.

**Fields**

`x::T`

The x-coordinate of the center of the cell.

`y::T`

The y-coordinate of the center of the cell.

`half_width::T`

The half-width of the cell.

`dist::T`

The distance from the center of the cell to the polygon.

`max_dist::T`

The maximum distance from the center of the cell to the polygon. This is `dist + half_width * sqrt(2)`

.

**Constructors**

`Cell(x::T, y::T, half_width::T, points, boundary_nodes)`

Constructs a cell with center `(x, y)`

and half-width `half_width`

. The cell is assumed to live in the polygon defined by `points`

and `boundary_nodes`

.

`DelaunayTriangulation.CellQueue`

— Type`CellQueue{T}`

A struct representing the priority queue of `Cell`

s, used for sorting the cells in a grid according to their maximum distance.

**Fields**

`queue::MaxPriorityQueue{Cell{T},T}`

: The priority queue of cells, sorting according to maximum distance.

**Constructors**

`CellQueue{T}()`

Constructs a new `CellQueue`

with elements of type `Cell{T}`

.

`DelaunayTriangulation.CircularArc`

— Type`CircularArc <: AbstractParametricCurve`

Curve for representing a circular arc, parametrised over `0 ≤ t ≤ 1`

. This curve can be evaluated using `circular_arc(t)`

and returns a tuple `(x, y)`

of the coordinates of the point on the curve at `t`

.

**Fields**

`center::NTuple{2,Float64}`

: The center of the arc.`radius::Float64`

: The radius of the arc.`start_angle::Float64`

: The angle of the initial point of the arc, in radians.`sector_angle::Float64`

: The angle of the sector of the arc, in radians. This is given by`end_angle - start_angle`

, where`end_angle`

is the angle at`last`

, and so might be negative for negatively oriented arcs.`first::NTuple{2,Float64}`

: The first point of the arc.`last::NTuple{2,Float64}`

: The last point of the arc.`pqr::NTuple{3, NTuple{2, Float64}}`

: Three points on the circle through the arc. This is needed for`point_position_relative_to_curve`

.

The angles `start_angle`

and `end_angle`

should be setup such that `start_angle > end_angle`

implies a positively oriented arc, and `start_angle < end_angle`

implies a negatively oriented arc. Moreover, they must be in `[0°, 2π°)`

.

**Constructor**

You can construct a `CircularArc`

using

`CircularArc(first, last, center; positive=true)`

It is up to you to ensure that `first`

and `last`

are equidistant from `center`

- the radius used will be the distance between `center`

and `first`

. The `positive`

keyword argument is used to determine if the arc is positively oriented or negatively oriented.

`DelaunayTriangulation.ConvexHull`

— Type`ConvexHull{PointsType, IntegerType}`

Struct for representing a convex hull. See also `convex_hull`

.

**Fields**

`points::PointsType`

: The underlying point set.`vertices::Vector{IntegerType}`

: The vertices of the convex hull, in counter-clockwise order. Defined so that`vertices[begin] == vertices[end]`

.

**Constructors**

```
ConvexHull(points, vertices)
convex_hull(points; IntegerType=Int)
```

`DelaunayTriangulation.DiametralBoundingBox`

— Type`DiametralBoundingBox`

Type for representing a bounding box generated from an edge's diametral circle.

**Fields**

`bounding_box::BoundingBox`

: The bounding box.`edge::NTuple{2,Int}`

: The generator edge.

`DelaunayTriangulation.EachGhostEdge`

— Type`EachGhostEdge{E,T}`

An iterator over all ghost edges in a triangulation.

**Fields**

`edges::E`

: The iterator over all edges in the triangulation.`tri::T`

: The triangulation.

`DelaunayTriangulation.EachGhostTriangle`

— Type`EachGhostTriangle{V,T}`

An iterator over all ghost triangles in a triangulation.

**Fields**

`triangles::V`

: The iterator over all triangles in the triangulation.`tri::T`

: The triangulation.

`DelaunayTriangulation.EachGhostVertex`

— Type`EachGhostVertex{V,T}`

An iterator over all ghost vertices in a triangulation.

**Fields**

`vertices::V`

: The iterator over all vertices in the triangulation.`tri::T`

: The triangulation.

`DelaunayTriangulation.EachSolidEdge`

— Type`EachSolidEdge{E,T}`

An iterator over all solid edges in a triangulation.

**Fields**

`edges::E`

: The iterator over all edges in the triangulation.`tri::T`

: The triangulation.

`DelaunayTriangulation.EachSolidTriangle`

— Type`EachSolidTriangle{V,T}`

An iterator over all solid triangles in a triangulation.

**Fields**

`triangles::V`

: The iterator over all triangles in the triangulation.`tri::T`

: The triangulation.

`DelaunayTriangulation.EachSolidVertex`

— Type`EachSolidVertex{V,T}`

An iterator over all solid vertices in a triangulation.

**Fields**

`vertices::V`

: The iterator over all vertices in the triangulation.`tri::T`

: The triangulation.

`DelaunayTriangulation.EllipticalArc`

— Type`EllipticalArc <: AbstractParametricCurve`

Curve for representing an elliptical arc, parametrised over `0 ≤ t ≤ 1`

. This curve can be evaluated using `elliptical_arc(t)`

and returns a tuple `(x, y)`

of the coordinates of the point on the curve at `t`

.

**Fields**

`center::NTuple{2,Float64}`

: The center of the ellipse.`horz_radius::Float64`

: The horizontal radius of the ellipse.`vert_radius::Float64`

: The vertical radius of the ellipse.`rotation_scales::NTuple{2,Float64}`

: If`θ`

is the angle of rotation of the ellipse, then this is`(sin(θ), cos(θ))`

.`start_angle::Float64`

: The angle of the initial point of the arc measured from`center`

, in radians. This angle is measured from the center prior to rotating the ellipse.`sector_angle::Float64`

: The angle of the sector of the arc, in radians. This is given by`end_angle - start_angle`

, where`end_angle`

is the angle at`last`

, and so might be negative for negatively oriented arcs.`first::NTuple{2,Float64}`

: The first point of the arc.`last::NTuple{2,Float64}`

: The last point of the arc.

**Constructor**

You can construct an `EllipticalArc`

using

`EllipticalArc(first, last, center, major_radius, minor_radius, rotation; positive=true)`

where `rotation`

is the angle of rotation of the ellipse, in degrees. The `positive`

keyword argument is used to determine if the arc is positively oriented or negatively oriented.

`DelaunayTriangulation.EnlargementValues`

— Type`EnlargementValues`

Type for representing the values used in the minimisation of enlargement.

**Fields**

`enlargement::Float64`

: The enlargement of the bounding box of the child being compared with.`idx::Int`

: The index of the child being compared with.`area::Float64`

: The area of the child being compared with.`bounding_box::BoundingBox`

: The bounding box being compared with for enlargement.

**Constructor**

```
EnlargementValues(enlargement, idx, area, bounding_box)
EnlargementValues(bounding_box)
```

`DelaunayTriangulation.Graph`

— Type`Graph{IntegerType}`

Struct for storing neighbourhood relationships between vertices in a triangulation. This is an undirected graph.

**Fields**

`vertices::Set{IntegerType}`

The set of vertices in the underlying triangulation.

`edges::Set{NTuple{2, IntegerType}}`

The set of edges in the underlying triangulation.

`neighbours::Dict{IntegerType, Set{IntegerType}}`

The map taking vertices `u`

to the set of all `v`

such that `(u, v)`

is an edge in the underlying triangulation.

**Constructors**

```
Graph{IntegerType}()
Graph(vertices::Set{IntegerType}, edges::Set{NTuple{2, IntegerType}}, neighbours::Dict{IntegerType, Set{IntegerType}})
```

`DelaunayTriangulation.IndividualTriangleStatistics`

— Type`IndividualTriangleStatistics{T}`

Struct storing statistics of a single triangle.

**Fields**

`area::T`

: The area of the triangle.`lengths::NTuple{3,T}`

: The lengths of the edges of the triangle, given in sorted order.`circumcenter::NTuple{2,T}`

: The circumcenter of the triangle.`circumradius::T`

: The circumradius of the triangle.`angles::NTuple{3, T}`

: The angles of the triangle, given in sorted order.`radius_edge_ratio::T`

: The ratio of the circumradius to the shortest edge length.`edge_midpoints::NTuple{3,NTuple{2,T}}`

: The midpoints of the edges of the triangle.`aspect_ratio::T`

: The ratio of the inradius to the circumradius.`inradius::T`

: The inradius of the triangle.`perimeter::T`

: The perimeter of the triangle.`centroid::NTuple{2,T}`

: The centroid of the triangle.`offcenter::NTuple{2,T}`

: The offcenter of the triangle with radius-edge ratio cutoff`β=1`

. See this paper.`sink::NTuple{2,T}`

: The sink of the triangle relative to the parent triangulation. See this paper.

**Constructors**

The constructor is

`IndividualTriangleStatistics(p, q, r, sink = (NaN, NaN))`

where `p`

, `q`

, and `r`

are the coordinates of the triangle given in counter-clockwise order. `sink`

is the triangle's sink. This must be provided separately since it is only computed relative to a triangulation, and so requires vertices rather than coordinates; see `triangle_sink`

.

**Extended help**

The relevant functions used for computing these statistics are

`DelaunayTriangulation.InsertionEventHistory`

— Type`InsertionEventHistory{T,E}`

A data structure for storing the changes to the triangulation during the insertion of a point.

**Fields**

`added_triangles::Set{T}`

: The triangles that were added.`deleted_triangles::Set{T}`

: The triangles that were deleted.`added_segments::Set{E}`

: The interior segments that were added.`deleted_segments::Set{E}`

: The interior segments that were deleted.`added_boundary_segments::Set{E}`

: The boundary segments that were added.`deleted_boundary_segments::Set{E}`

: The boundary segments that were deleted.

**Constructor**

The default constructor is available, but we also provide

`InsertionEventHistory(tri::Triangulation)`

which will initialise this struct with empty, appropriately `sizehint!`

ed, sets.

`DelaunayTriangulation.InsertionEventHistory`

— Method`InsertionEventHistory(tri::Triangulation) -> InsertionEventHistory`

Initialises an `InsertionEventHistory`

for the triangulation `tri`

.

`DelaunayTriangulation.Leaf`

— Type`mutable struct Leaf <: AbstractNode`

Type for representing a leaf node in an R-tree.

Technically, this type should be referred to by `Leaf{Branch}`

. Due to a lack of support for mutually recursive types or forward declarations, we have a parametric type in this struct's definition since Branch is not yet defined. In particular, `Leaf`

is not a concrete type, whereas `Leaf{Branch}`

is.

**Fields**

`parent::Union{Branch, Nothing}`

: The parent of the leaf node.`bounding_box::BoundingBox`

: The bounding box of the leaf node.`children::Vector{DiametralBoundingBox}`

: The children of the leaf node.

**Constructor**

`Leaf(parent::Union{Branch,Nothing}=nothing) = Leaf{Branch}(parent, InvalidBoundingBox, DiametralBoundingBox[])`

`DelaunayTriangulation.LeafCache`

— Type`LeafCache`

Type for representing a cache of leaf nodes.

`DelaunayTriangulation.LineSegment`

— Type`LineSegment <: AbstractParametricCurve`

Curve for representing a line segment, parametrised over `0 ≤ t ≤ 1`

. This curve can be using `line_segment(t)`

and returns a tuple `(x, y)`

of the coordinates of the point on the curve at `t`

.

**Fields**

`first::NTuple{2,Float64}`

: The first point of the line segment.`last::NTuple{2,Float64}`

: The last point of the line segment.`length::Float64`

: The length of the line segment.

**Constructor**

You can construct a `LineSegment`

using

`LineSegment(first, last)`

`DelaunayTriangulation.MaxPriorityQueue`

— Type`MaxPriorityQueue{K, V}`

Struct for a max priority queue.

**Fields**

`data::Vector{Pair{K, V}}`

: The data of the queue, stored in a vector of key-value pairs mapping elements to their priority.`map::Dict{K, Int}`

: A dictionary mapping elements to their index in the data vector.

`DelaunayTriangulation.NodeCache`

— Type`NodeCache{Node,Child}`

Type for representing a cache of nodes whose children are of type `Child`

. This is used for caching nodes that are detached from the R-tree, e.g. when a node is split.

**Fields**

`cache::Vector{Node}`

: The cache of nodes.`size_limit::Int`

: The maximum number of nodes that can be cached.

**Constructor**

`NodeCache{Node,Child}(size_limit::Int) where {Node,Child} = new{Node,Child}(Node[], size_limit)`

`DelaunayTriangulation.PiecewiseLinear`

— Type`PiecewiseLinear <: AbstractParametricCurve`

Struct for representing a piecewise linear curve. This curve should not be interacted with or constructed directly. It only exists so that it can be an `AbstractParametricCurve`

. Instead, triangulations use this curve to know that its `boundary_nodes`

field should be used instead.

This struct does have fields, namely `points`

and `boundary_nodes`

(and boundary*nodes should be a contiguous section). These are only used so that we can use this struct in [`angle*between`](@ref) easily. In particular, we need to allow for evaluating this curve at`

t=0`and at`

t=1`, and similarly for differentiating the curve at`

t=0`and at`

t=1`. For this, we have defined, letting`

L`be a`

PiecewiseLinear`curve,`

L(0)`to return the first point on the curve, and the last point otherwise (meaning`

L(h)`is constant for`

h > 0`), and similarly for differentiation. Do NOT rely on the implementation of these methods.

`DelaunayTriangulation.PointLocationHistory`

— Type`PointLocationHistory{T,E,I}`

History from using `jump_and_march`

.

**Fields**

`triangles::Vector{T}`

: The visited triangles.`collinear_segments::Vector{E}`

: Segments collinear with the original line`pq`

using to jump.`collinear_point_indices::Vector{I}`

: This field contains indices to segments in`collinear_segments`

that refer to points that were on the original segment, but there is no valid segment for them. We use manually fix this after the fact. For example, we could add an edge`(1, 14)`

, when really we mean something like`(7, 14)`

which isn't a valid edge.`left_vertices::Vector{I}`

: Vertices from the visited triangles to the left of`pq`

.`right_verices::Vector{I}`

: Vertices from the visited triangles to the right of`pq`

.

`DelaunayTriangulation.Polygon`

— Type`Polygon{T,V,P} <: AbstractVector{T}`

A struct for representing a polygon. The `vertices`

are to be a counter-clockwise list of integers, where the integers themselves refer to points in `points`

.

**Fields**

`vertices::V`

: A list of integers that refer to points in`points`

. The last vertex shokuld not be the same as the first.`points::P`

: A list of points.

In the case where `vertices[begin] ≠ vertices[end]`

, the `vertices`

field is exactly the same as the input `vertices`

. Where `vertices[begin] = vertices[end]`

, the `vertices`

field is a view of `vertices`

that excludes the last element.

`DelaunayTriangulation.PolygonHierarchy`

— Type`PolygonHierarchy{I}`

Struct used to define a polygon hierarchy. The hierarchy is represented as a forest of `PolygonTree`

s.

The polygons must not intersect any other polygon's boundaries.

**Fields**

`polygon_orientations::BitVector`

: A`BitVector`

of length`n`

where`n`

is the number of polygons in the hierarchy. The`i`

th entry is`true`

if the`i`

th polygon is positively oriented, and`false`

otherwise.`bounding_boxes::Vector{BoundingBox}`

: A`Vector`

of`BoundingBox`

s of length`n`

where`n`

is the number of polygons in the hierarchy. The`i`

th entry is the`BoundingBox`

of the`i`

th polygon.`trees::Dict{I,PolygonTree{I}}`

: A`Dict`

mapping the index of a polygon to its`PolygonTree`

. The keys of`trees`

are the roots of each individual tree, i.e. the outer-most polygons.`reorder_cache::Vector{PolygonTree{I}}`

: A`Vector used for caching trees to be deleted in [`

reorder_subtree!`](@ref).

Note that the vector definitions for `poylgon_orientations`

and `bounding_boxes`

are treating the curves with the assumption that they are enumerated in the order 1, 2, 3, ....

**Constructor**

`PolygonHierarchy{I}() where {I}`

Constructs a `PolygonHierarchy`

with no polygons.

`DelaunayTriangulation.PolygonTree`

— Type`mutable struct PolygonTree{I}`

A tree structure used to define a polygon hierarchy.

**Fields**

`parent::Union{Nothing,PolygonTree{I}}`

: The parent of the tree. If`nothing`

, then the tree is the root.`children::Set{PolygonTree{I}}`

: The children of the tree.`index::I`

: The index of the tree. This is the index associated with the polygon.`height::Int`

: The height of the tree. This is the number of polygons in the tree that`index`

is inside of. The root has height`0`

.

**Constructor**

`PolygonTree{I}(parent::Union{Nothing,PolygonTree{I}}, index, height) where {I}`

Constructs a `PolygonTree`

with `parent`

, `index`

, and `height`

, and no children.

`DelaunayTriangulation.Queue`

— Type`Queue{T}`

Struct for a first-in first-out queue.

Under the hood, `Queue`

simply uses a `Vector`

. This may not be as optimised compared to other implementations, e.g. DataStructure.jl's block-based approach with a `Dequeue`

.

`DelaunayTriangulation.RTree`

— Type`mutable struct RTree`

Type for representing an R-tree with linear splitting.

**Fields**

`root::Union{Branch,Leaf{Branch}}`

: The root of the R-tree.`num_elements::Int`

: The number of elements in the R-tree.`branch_cache::BranchCache`

: The cache of branch nodes.`twig_cache::TwigCache`

: The cache of twig nodes.`leaf_cache::LeafCache`

: The cache of leaf nodes.`fill_factor::Float64`

: The fill factor of the R-tree, i.e. the percentage of a node's capacity that should be filled after splitting.`free_cache::BitVector`

: A bit vector for keeping track of which indices in`detached_cache`

are free.`detached_cache::Vector{Union{Branch,Leaf{Branch}}}`

: A cache of detached nodes, i.e. nodes that have been split from the R-tree. This is used for deleting nodes.`intersection_cache::NTuple{2,IntersectionCache}`

: Cache used for identifying intersections. Each element of the`Tuple`

is its own cache, allowing for up to two intersection queries to be performed simultaneously. Note that this makes the R-tree non-thread-safe, and even non-safe when considering three or more intersection queries simultaneously.

**Constructor**

` RTree(; size_limit=100, fill_factor=0.7)`

The `size_limit`

is the node capacity. All node types have the same capacity.

`DelaunayTriangulation.RTreeIntersectionCache`

— Type`RTreeIntersectionCache`

Type for representing a cache used for identifying intersections in an R-tree.

**Fields**

`node_indices::Vector{Int}`

: A cache of indices used for identifying intersections.`need_tests::BitVector`

: A`BitVector`

cache for keeping track of which indices in`node_indices`

need to be tested for intersections.

`DelaunayTriangulation.RTreeIntersectionIterator`

— Type`RTreeIntersectionIterator`

Type for representing an iterator over the elements in an R-tree that intersect with a bounding box.

**Fields**

`tree::RTree`

: The R-tree.`bounding_box::BoundingBox`

: The bounding box to test for intersections with.`cache::RTreeIntersectionCache`

: The cache used for identifying intersections.

`DelaunayTriangulation.RTreeIntersectionIteratorState`

— Type`RTreeIntersectionIteratorState`

The state of an `RTreeIntersectionIterator`

.

**Fields**

`leaf::Leaf{Branch}`

: The current leaf node.`node_indices::Vector{Int}`

: The indices of the current node at each level.`need_tests::BitVector`

: A`BitVector`

cache for keeping track of which indices in`node_indices`

need to be tested for intersections.

`DelaunayTriangulation.RefinementArguments`

— Type`RefinementArguments{Q,C,H,I,E,T,R}`

A struct for storing arguments for mesh refinement.

**Fields**

`queue::Q`

: The`RefinementQueue`

.`constraints::C`

: The`RefinementConstraints`

.`events::H`

: The`InsertionEventHistory`

.`min_steiner_vertex::I`

: The minimum vertex of a Steiner point. All vertices greater than or equal to this can be considered as Steiner vertices.`segment_list::Set{E}`

: The set of segments in the triangulation before refinement.`segment_vertices::Set{I}`

: Set of vertices that are vertices of segments in`segment_list`

.`midpoint_split_list::Set{I}`

: Set of vertices that are centre-splits of encroached edges.`offcenter_split_list::Set{I}`

: Set of vertices that are off-centre splits of encroached edges.`use_circumcenter::Bool`

: Whether to use circumcenters for Steiner points, or the more general approach of Erten and Üngör (2009).`use_lens::Bool`

: Whether to use diametral lens (`true`

) or diametral circles (`false`

) for the defining encroachment.`steiner_scale::T`

: The factor by which to scale the Steiner points closer to the triangle's shortest edge.`locked_convex_hull::Bool`

: Whether the convex hull of the triangulation had to be locked for refinement.`had_ghosts::Bool`

: Whether the triangulation initially had ghost triangles or not.`rng::R`

: The random number generator.`concavity_protection::Bool`

: Whether to use concavity protection or not for`jump_and_march`

. Most likely not needed, but may help in pathological cases.

**Constructors**

In addition to the default constructor, we provide

`RefinementArguments(tri::Triangulation; kwargs...)`

for constructing this struct. This constructor will lock the convex hull and add ghost triangles to `tri`

if needed (`refine!`

will undo these changes once the refinement is finished))

`DelaunayTriangulation.RefinementArguments`

— Method`RefinementArguments(tri::Triangulation; kwargs...) -> RefinementArguments`

Initialises the `RefinementArguments`

for the given `Triangulation`

, `tri`

. The `kwargs...`

match those from `refine!`

.

If `tri`

has no ghost triangles, it will be mutated so that it has them. Similarly, if the triangulation has no constrained boundary, then the convex hull will be locked so that it is treated as a constrained boundary. These changes will be undone in `refine!`

once the refinement is finished.

`DelaunayTriangulation.RefinementConstraints`

— Type`RefinementConstraints{F}`

A struct for storing constraints for mesh refinement.

**Fields**

`min_angle=0.0`

: The minimum angle of a triangle.`max_angle=180.0`

: The maximum angle of a triangle.`min_area=0.0`

: The minimum area of a triangle.`max_area=Inf`

: The maximum area of a triangle.`max_radius_edge_ratio=csd(min_angle) / 2`

: The maximum radius-edge ratio of a triangle. This is computed from`min_angle`

- you cannot provide a value for it yourself.`max_points=typemax(Int)`

: The maximum number of vertices allowed in the triangulation. Note that this refers to`num_solid_vertices`

, not the amount returned by`num_points`

.`seiditous_angle=20.0`

: The inter-segment angle used to define seditious edges in degrees. Should not be substantially smaller than 20.0° or any greater than 60.0°.`custom_constraint::F=(tri, triangle) -> false`

: A custom constraint function. This should take a`Triangulation`

and a`triangle`

as arguments, and return`true`

if the`triangle`

violates the constraints and`false`

otherwise.

`DelaunayTriangulation.RefinementQueue`

— Type`RefinementQueue{T,E,F}`

Struct defining a pair of priority queues for encroached segments and poor-quality triangles.

**Fields**

`segments::MaxPriorityQueue{E,F}`

: A priority queue of encroached segments, where the priorities are the squared edge lengths.`triangles::MaxPriorityQueue{T,F}`

: A priority queue of poor-quality triangles, where the priorities are the radius-edge ratios.

**Constructor**

The default constructor is available, but we also provide

`RefinementQueue(tri::Triangulation)`

which will initialise this struct with empty queues with the appropriate types.

`DelaunayTriangulation.RepresentativeCoordinates`

— Type`RepresentativeCoordinates{IntegerType, NumberType}`

A mutable struct for representing the coordinates of a representative point of polygon or a set of points.

**Fields**

`x::NumberType`

: The x-coordinate of the representative point.`y::NumberType`

: The y-coordinate of the representative point.`n::IntegerType`

: The number of points represented by the representative point.

`DelaunayTriangulation.ShuffledPolygonLinkedList`

— Type`ShuffledPolygonLinkedList{I,T}`

Data structure for representing a polygon as a doubly-linked list. In the descriptions below, `π`

is used to denote the `shuffled_indices`

vector.

**Fields**

`next::Vector{I}`

: The`next`

vertices, so that`next[π[i]]`

is the vertex after`S[π[i]]`

.`prev::Vector{I}`

: The`prev`

vertices, so that`prev[π[i]]`

is the vertex before`S[π[i]]`

.`shuffled_indices::Vector{I}`

: The shuffled indices of the vertices, so that`S[π[i]]`

is the`i`

th vertex.`k::I`

: The number of vertices in the polygon.`S::T`

: The vertices of the polygon. This should not be a circular vector, i.e.`S[begin] ≠ S[end]`

, and must use one-based indexing. Additionally, the vertices must be provided in counter-clockwise order - this is NOT checked.

**Constructor**

To construct this, use

`ShuffledPolygonLinkedList(S::Vector; rng::AbstractRNG=Random.default_rng())`

The argument `rng`

is used for shuffling the `shuffled_indices`

vector.

`DelaunayTriangulation.SmallAngleComplex`

— Type`SmallAngleComplex{I}`

Struct for representing a small-angle complex.

**Fields**

`apex::I`

: The apex vertex of the complex.`members::Vector{SmallAngleComplexMember{I}}`

: The members of the complex.

**Extended help**

A small-angle complex is a set of curves that form a contiguous set of small angles, i.e. the angle between each consecutive pair of curves is less than 60°. The apex of the complex is the vertex that is shared by all of the curves.

`DelaunayTriangulation.SmallAngleComplexMember`

— Type`SmallAngleComplexMember{I}`

Struct for representing a member of a small-angle complex.

**Fields**

`parent_curve::I`

: The index of the parent curve in the boundary curves assoicated with the member. If this is`0`

, then this is instead a member of a complex around an interior segment.`next_edge::I`

: The next vertex after the apex in the boundary nodes associated with the member.

`DelaunayTriangulation.Triangulation`

— Type`Triangulation{P,T,BN,W,I,E,Es,BC,BCT,BEM,GVM,GVR,BPL,C,BE}`

Struct representing a triangulation, as constructed by `triangulate`

.

**Fields**

`points::P`

The point set of the triangulation. Please note that this may not necessarily correspond to each point in the triangulation, e.g. some points may have been deleted - see `each_solid_vertex`

for an iterator over each vertex in the triangulation.

`triangles::T`

The triangles in the triangulation. Each triangle is oriented counter-clockwise. If your triangulation has ghost triangles, some of these triangles will contain ghost vertices (i.e., vertices negative indices). Solid triangles can be iterated over using `each_solid_triangle`

.

`boundary_nodes::BN`

The boundary nodes of the triangulation, if the triangulation is constrained; the assumed form of these boundary nodes is outlined in the docs. If your triangulation is unconstrained, then `boundary_nodes`

will be empty and the boundary should instead be inspected using the convex hull field, or alternatively you can see `lock_convex_hull!`

.

`interior_segments::Es`

Constrained segments appearing in the triangulation. These will only be those segments appearing off of the boundary. If your triangulation is unconstrained, then `segments`

will be empty.

`all_segments::Es`

This is similar to `segments`

, except this includes both the interior segments and the boundary segments. If your triangulation is unconstrained, then `all_segments`

will be empty.

`weights::W`

The weights of the triangulation. If you are not using a weighted triangulation, this will be given by `ZeroWeight()`

. Otherwise, the weights must be such that `get_weight(weights, i)`

is the weight for the `i`

th vertex. The weights should be `Float64`

.

`adjacent::Adjacent{I,E}`

The `Adjacent`

map of the triangulation. This maps edges `(u, v)`

to vertices `w`

such that `(u, v, w)`

is a positively oriented triangle in `triangles`

(up to rotation).

`adjacent2vertex::Adjacent2Vertex{I,Es}`

The `Adjacent2Vertex`

map of the triangulation. This maps vertices `w`

to sets `S`

such that `(u, v, w)`

is a positively oriented triangle in `triangles`

(up to rotation) for all `(u, v) ∈ S`

.

`graph::Graph{I}`

The `Graph`

of the triangulation, represented as an undirected graph that defines all the neighbourhood information for the triangulation.

`boundary_curves::BC`

Functions defining the boundary curves of the triangulation, incase you are triangulating a curve-bounded domain. By default, this will be an empty `Tuple`

, indicating that the boundary is as specified in `boundary_nodes`

- a piecewise linear curve. If you are triangulating a curve-bounded domain, then these will be the parametric curves (see `AbstractParametricCurve`

) you provided as a `Tuple`

, where the `i`

th element of the `Tuple`

is associated with the ghost vertex `-i`

, i.e. the `i`

th section as indicated by `ghost_vertex_map`

. If the `i`

th boundary was left was a sequence of edges, then the function will be a `PiecewiseLinear()`

.

`boundary_edge_map::BEM`

This is a `Dict`

from `construct_boundary_edge_map`

that maps boundary edges `(u, v)`

to their corresponding position in `boundary_nodes`

.

`ghost_vertex_map::GVM`

This is a `Dict`

that maps ghost vertices to their corresponding section in `boundary_nodes`

, constructed by `construct_ghost_vertex_map`

.

`ghost_vertex_ranges::GVR`

This is a `Dict`

that maps ghost vertices to a range of all other ghost vertices that appear on the curve corresponding to the given ghost vertex, constructed by `construct_ghost_vertex_ranges`

.

`convex_hull::ConvexHull{P,I}`

The `ConvexHull`

of the triangulation, which is the convex hull of the point set `points`

.

`representative_point_list::BPL`

The `Dict`

of points giving `RepresentativeCoordinates`

for each boundary curve, or for the convex hull if `boundary_nodes`

is empty. These representative points are used for interpreting ghost vertices.

`polygon_hierarchy::PolygonHierarchy{I}`

The `PolygonHierarchy`

of the boundary, defining the hierarchy of the boundary curves, giving information about which curves are contained in which other curves.

`boundary_enricher::BE`

The `BoundaryEnricher`

used for triangulating a curve-bounded domain. If the domain is not curve-bounded, this is `nothing`

.

`cache::C`

A `TriangulationCache`

used as a cache for `add_segment!`

which requires a separate `Triangulation`

structure for use. This will not contain any segments or boundary nodes. Also stores segments useful for `lock_convex_hull!`

and `unlock_convex_hull!`

.

`DelaunayTriangulation.Triangulation`

— Method`Triangulation(points; kwargs...) -> Triangulation`

Initialises an empty `Triangulation`

for triangulating `points`

. The keyword arguments `kwargs...`

match those of `triangulate`

.

`DelaunayTriangulation.Triangulation`

— Method`Triangulation(points, triangles, boundary_nodes; kwargs...) -> Triangulation`

Returns the `Triangulation`

corresponding to the triangulation of `points`

with `triangles`

and `boundary_nodes`

.

**Arguments**

`points`

: The points that the triangulation is of.`triangles`

: The triangles of the triangulation. These should be given in counter-clockwise order, with vertices corresponding to`points`

. These should not include any ghost triangles.`boundary_nodes`

: The boundary nodes of the triangulation. These should match the specification given in the documentation or in`check_args`

.

**Keyword Arguments**

`IntegerType=Int`

: The integer type to use for the triangulation. This is used for representing vertices.`EdgeType=isnothing(segments) ? NTuple{2,IntegerType} : (edge_type ∘ typeof)(segments)`

: The edge type to use for the triangulation.`TriangleType=NTuple{3,IntegerType}`

: The triangle type to use for the triangulation.`EdgesType=isnothing(segments) ? Set{EdgeType} : typeof(segments)`

: The type to use for storing the edges of the triangulation.`TrianglesType=Set{TriangleType}`

: The type to use for storing the triangles of the triangulation.`weights=ZeroWeight()`

: The weights associated with the triangulation.`delete_ghosts=false`

: Whether to delete the ghost triangles after the triangulation is computed. This is done using`delete_ghost_triangles!`

.

**Output**

`tri`

: The`Triangulation`

.

`DelaunayTriangulation.TriangulationCache`

— Type`TriangulationCache{T,M,I,S}`

A cache to be used as a field in `Triangulation`

.

**Fields**

`triangulation::T`

: The cached triangulation. This will only refer to an unconstrained triangulation, meaning it cannot have any segments or boundary nodes. It will contain the`weights`

. This is used for constrained triangulations.`triangulation_2::T`

: An extra cached triangulation. This is needed for retriangulating fans for constrained triangulations.`marked_vertices::M`

: Marked vertices cache for use in constrained triangulations.`interior_segments_on_hull::I`

: Interior segments in the triangulation that also appear on the convex hull of`tri`

. This is needed for`lock_convex_hull!`

in case the convex hull also contains interior segments.`surrounding_polygon::S`

: The polygon surrounding the triangulation. This is needed for`delete_point!`

.`fan_triangles::F`

: Triangles in a fan. This is needed for sorting fans for constrained triangulations.

The triangulation cache itself does not have a cache. Instead, it stores a `TriangulationCache(nothing)`

.

The `points`

of the cache's `triangulation`

will be aliased to the `points`

of the parent triangulation.

`DelaunayTriangulation.TriangulationStatistics`

— Type`TriangulationStatistics{T,V,I}`

A struct containing statistics about a triangulation.

**Fields**

`num_vertices::I`

: The number of vertices in the triangulation.`num_solid_vertices::I`

: The number of solid vertices in the triangulation.`num_ghost_vertices::I`

: The number of ghost vertices in the triangulation.`num_edges::I`

: The number of edges in the triangulation.`num_solid_edges::I`

: The number of solid edges in the triangulation.`num_ghost_edges::I`

: The number of ghost edges in the triangulation.`num_triangles::I`

: The number of triangles in the triangulation.`num_solid_triangles::I`

: The number of solid triangles in the triangulation.`num_ghost_triangles::I`

: The number of ghost triangles in the triangulation.`num_boundary_segments::I`

: The number of boundary segments in the triangulation.`num_interior_segments::I`

: The number of interior segments in the triangulation.`num_segments::I`

: The number of segments in the triangulation.`num_convex_hull_vertices::I`

: The number of vertices on the convex hull of the triangulation.`smallest_angle::V`

: The smallest angle in the triangulation.`largest_angle::V`

: The largest angle in the triangulation.`smallest_area::V`

: The smallest area of a triangle in the triangulation.`largest_area::V`

: The largest area of a triangle in the triangulation.`smallest_radius_edge_ratio::V`

: The smallest radius-edge ratio of a triangle in the triangulation.`largest_radius_edge_ratio::V`

: The largest radius-edge ratio of a triangle in the triangulation.`area::V`

: The total area of the triangulation.`individual_statistics::Dict{T,IndividualTriangleStatistics{V}}`

: A map from triangles in the triangulation to their individual statistics. See`IndividualTriangleStatistics`

.

**Constructors**

To construct these statistics, use `statistics`

, which you call as `statistics(tri::Triangulation)`

.

`DelaunayTriangulation.TwigCache`

— Type`TwigCache`

Type for representing a cache of twig nodes, i.e. branch nodes at level 2.

`DelaunayTriangulation.VoronoiTessellation`

— Type`VoronoiTessellation{Tr<:Triangulation,P,I,T,S,E}`

Struct for representing a Voronoi tessellation.

See also `voronoi`

.

**Fields**

`triangulation::Tr`

: The underlying triangulation. The tessellation is dual to this triangulation, although if the underlying triangulation is constrained then this is no longer the case (but it is still used).`generators::Dict{I,P}`

: A`Dict`

that maps vertices of generators to coordinates. These are simply the points present in the triangulation. A`Dict`

is needed in case the triangulation is missing some points.`polygon_points::Vector{P}`

: The points defining the coordinates of the polygons. The points are not guaranteed to be unique if a circumcenter appears on the boundary or you are considering a clipped tessellation. (See also`get_polygon_coordinates`

.)`polygons::Dict{I,Vector{I}}`

: A`Dict`

mapping polygon indices (which is the same as a generator vertex) to the vertices of a polygon. The polygons are given in counter-clockwise order and the first and last vertices are equal.`circumcenter_to_triangle::Dict{I,T}`

: A`Dict`

mapping a circumcenter index to the triangle that contains it. The triangles are sorted such that the minimum vertex is last.`triangle_to_circumcenter::Dict{T,I}`

: A`Dict`

mapping a triangle to its circumcenter index. The triangles are sorted such that the minimum vertex is last.`unbounded_polygons::Set{I}`

: A`Set`

of indices of the unbounded polygons.`cocircular_circumcenters::S`

: A`Set`

of indices of circumcenters that come from triangles that are cocircular with another triangle's vertices, and adjoin said triangles.`adjacent::Adjacent{I,E}`

: The adjacent map. This maps an oriented edge to the polygon that it belongs to.`boundary_polygons::Set{I}`

: A`Set`

of indices of the polygons that are on the boundary of the tessellation. Only relevant for clipped tessellations, otherwise see`unbounded_polygons`

.

`DelaunayTriangulation.ZeroWeight`

— Type`ZeroWeight`

Struct used for indicating that a triangulation has zero weights. The weights are `Float64`

.

`Base.:∩`

— Method```
intersect(r1::BoundingBox, r2::BoundingBox) -> BoundingBox
r1::BoundingBox ∩ r2::BoundingBox -> BoundingBox
```

Returns the intersection of `r1`

and `r2`

. If the intersection is empty, returns `InvalidBoundingBox`

.

`Base.:∩`

— Method```
intersect(I::BoundingInterval, J::BoundingInterval) -> BoundingInterval
I::BoundingInterval ∩ J::BoundingInterval -> BoundingInterval
```

Returns the intersection of `I`

and `J`

. If the intersection is empty, returns `InvalidBoundingInterval`

.

`Base.:∪`

— Method```
union(r1::BoundingBox, r2::BoundingBox) -> BoundingBox
r1::BoundingBox ∪ r2::BoundingBox -> BoundingBox
```

Returns the union of `r1`

and `r2`

, i.e. the smallest bounding box that contains both `r1`

and `r2`

.

`Base.:∪`

— Method```
union(I::BoundingInterval, J::BoundingInterval) -> BoundingInterval
I::BoundingInterval ∪ J::BoundingInterval -> BoundingInterval
```

Returns the union of `I`

and `J`

, combining their bounds; i.e. the smallest interval that contains both `I`

and `J`

.

`Base.append!`

— Method`append!(complex::SmallAngleComplex, new_complex::SmallAngleComplex)`

Appends the members of `new_complex`

onto the members of `complex`

.

`Base.append!`

— Method`append!(node::AbstractNode, child)`

Appends `child`

to `node`

's children. Also updates `node`

's bounding box.

`Base.delete!`

— Method`delete!(tree::BalancedBST{K}, key::K) -> BalancedBST{K}`

Deletes the node in `tree`

with key `key`

if it exists. Returns `tree`

.

`Base.delete!`

— Method`delete!(tree::BoundaryRTree, i, j)`

Deletes the bounding box of the diametral circle of the edge between `i`

and `j`

in `tree`

.

`Base.delete!`

— Method`delete!(tree::RTree, id_bounding_box::DiametralBoundingBox)`

Deletes `id_bounding_box`

from `tree`

.

`Base.eltype`

— Method`eltype(queue::Queue{T}) -> Type{T}`

Returns the type of elements stored in `q`

.

`Base.empty!`

— Method`empty!(events::InsertionEventHistory)`

Empties `events`

by emptying all of its fields.

`Base.empty!`

— Method`empty!(cache::TriangulationCache)`

Empties the cache by emptying the triangulation stored in it.

`Base.findfirst`

— Method`findfirst(tree::BalancedBST{K}, key::K) -> Union{Nothing,BalancedBSTNode{K}}`

Returns the node in `tree`

with key `key`

. If no such node exists, returns `nothing`

.

`Base.first`

— Method`first(queue::MaxPriorityQueue) -> Pair{K, V}`

Returns the element with the highest priority in a `queue`

, without removing it from `queue`

.

`Base.getindex`

— Method```
getindex(queue::MaxPriorityQueue, key)
queue[key]
```

Returns the priority of the element with key `key`

in a `queue`

.

`Base.getindex`

— Method```
getindex(queue::RefinementQueue{T,E,F}, triangle::T) -> F
queue[triangle] -> F
```

Return the radius-edge ratio of `triangle`

in `queue`

.

`Base.haskey`

— Method`haskey(tree::BalancedBST{K}, key::K) -> Bool`

Returns `true`

if `tree`

has a node with key `key`

, `false`

otherwise.

`Base.haskey`

— Method`haskey(queue::MaxPriorityQueue, key) -> Bool`

Returns `true`

if the `queue`

has an element with key `key`

.

`Base.haskey`

— Method`haskey(queue::RefinementQueue{T,E,F}, segment::E) -> Bool`

Return `true`

if `queue`

has `segment`

or its reverse, and `false`

otherwise.

`Base.haskey`

— Method`haskey(queue::RefinementQueue{T,E,F}, triangle::T) -> Bool`

Return `true`

if `queue`

has `triangle`

or any of its counter-clockwise rotations, and `false`

otherwise.

`Base.in`

— Method```
in(r1::BoundingBox, r2::BoundingBox) -> Bool
r1::BoundingBox ∈ r2::BoundingBox -> Bool
```

Tests whether `r1`

is in `r2`

.

`Base.in`

— Method```
in(I::BoundingInterval, J::BoundingInterval) -> Bool
I::BoundingInterval ∈ J::BoundingInterval -> Bool
```

Tests whether the interval `I`

is in the interval `J`

.

`Base.in`

— Method```
in(a::Float64, I::BoundingInterval) -> Bool
a::Float64 ∈ I::BoundingInterval -> Bool
```

Tests whether `a`

is in `I`

.

`Base.in`

— Method```
in(p::NTuple{2,<:Number}, r::BoundingBox) -> Bool
p::NTuple{2,<:Number} ∈ r::BoundingBox -> Bool
```

Tests whether `p`

is in `r`

.

`Base.insert!`

— Method`insert!(node::AbstractNode, child, tree::RTree) -> Bool`

Inserts `child`

into `node`

in `tree`

. Returns `true`

if the `tree`

's bounding boxes had to be adjusted and `false`

otherwise.

`Base.insert!`

— Method`insert!(tree::BoundaryRTree, i, j) -> Bool`

Inserts the diametral circle of the edge between `i`

and `j`

into `tree`

. Returns `true`

if the `tree`

's bounding boxes had to be adjusted and `false`

otherwise.

`Base.insert!`

— Method`insert!(tree::RTree, bounding_box[, level = 1]) -> Bool`

Inserts `bounding_box`

into `tree`

. Returns `true`

if the `tree`

's bounding boxes had to be adjusted and `false`

otherwise.

`Base.isempty`

— Method`isempty(r::BoundingBox) -> Bool`

Returns `true`

if `r`

is empty, i.e. if `r.x`

or `r.y`

is empty.

`Base.isempty`

— Method`isempty(I::BoundingInterval) -> Bool`

Returns `true`

if `I`

is empty, i.e. if `I.a`

or `I.b`

is `NaN`

or if `length(I) < 0`

.

`Base.isempty`

— Method`isempty(queue::CellQueue) -> Bool`

Returns `true`

if the `queue`

is empty, and `false`

otherwise.

`Base.isempty`

— Method`isempty(queue::MaxPriorityQueue) -> Bool`

Returns `true`

if the `queue`

is empty.

`Base.isempty`

— Method`isempty(cache::NodeCache) -> Bool`

Returns `true`

if `cache`

is empty.

`Base.isempty`

— Method`isempty(queue::Queue) -> Bool`

Returns `true`

if the `queue`

is empty, `false`

otherwise.

`Base.isempty`

— Method`isempty(queue::RefinementQueue) -> Bool`

Return `true`

if `queue`

has no segments or triangles, `false`

otherwise.

`Base.iterate`

— Method`iterate(itr::RTreeIntersectionIterator, state...)`

Iterate over the next state of `itr`

to find more intersections with the bounding box in `RTreeIntersectionIterator`

.

`Base.length`

— Method`length(I::BoundingInterval) -> Float64`

Returns the length of the interval `I`

.

`Base.length`

— Method`Base.length(queue::MaxPriorityQueue) -> Int`

Returns the number of elements in `queue`

.

`Base.length`

— Method`length(cache::NodeCache) -> Int`

Returns the number of nodes in `cache`

.

`Base.length`

— Method`length(queue::Queue) -> Int`

Returns the number of elements in the `queue`

.

`Base.minimum`

— Method`minimum(node::Union{BalancedBSTNode,Nothing}) -> Union{BalancedBSTNode,Nothing}`

Returns the node with the minimum key in the subtree rooted at `node`

. If `node`

is `nothing`

, returns `nothing`

.

`Base.pop!`

— Method`pop!(cache::NodeCache) -> Node`

Removes and returns the last node in `cache`

.

`Base.popfirst!`

— Method`popfirst!(queue::MaxPriorityQueue{K, V}) where {K, V} -> Pair{K, V}`

Removes and returns the element with the highest priority from the `queue`

.

`Base.popfirst!`

— Method`popfirst!(queue::Queue)`

Removes the element from the front of the `queue`

and returns it.

`Base.push!`

— Method`push!(tree::BalancedBST{K}, key::K)`

Inserts `key`

into `tree`

if it is not already present.

`Base.push!`

— Method`push!(queue::MaxPriorityQueue, pair)`

Adds the key-value pair `pair`

to the `queue`

.

`Base.push!`

— Method`push!(cache::NodeCache, node)`

`Base.push!`

— Method`push!(queue::Queue, item)`

Adds `item`

to the end of the `queue`

.

`Base.push!`

— Method`push!(complex::SmallAngleComplex, member::SmallAngleComplexMember)`

Pushes `member`

onto the members of `complex`

.

`Base.setindex!`

— Method```
setindex!(branch::Branch, child, i::Integer)
branch[i] = child
```

Sets the `i`

th child of `branch`

to be `child`

, also updating the parent of `child`

to be `branch`

.

`Base.setindex!`

— Method```
Bassetindex!(queue::RefinementQueue{T,E,F}, ρ::F, triangle::T) where {T,E,F}
queue[triangle] = ρ
```

Add a `triangle`

to `queue`

whose radius-edge ratio is `ρ`

. If the `triangle`

is already in the `queue`

, its priority is updated to `ρ`

.

`Base.setindex!`

— Method```
setindex!(queue::RefinementQueue{T,E,F}, ℓ²::F, segment::E) where {T,E,F}
queue[segment] = ℓ²
```

Add a `segment`

to `queue`

whose squared length is `ℓ²`

. If the `segment`

is already in the `queue`

, its priority is updated to `ℓ`

.

`Base.setindex!`

— Method```
setindex!(queue::MaxPriorityQueue, priority, key)
queue[key] = priority
```

Sets the priority of the element with key `key`

in a `queue`

to `priority`

, or adds the element to the `queue`

if it is not already present.

`DelaunayTriangulation._centroidal_smooth_itr`

— Method`_centroidal_smooth_itr(vorn::VoronoiTessellation, set_of_boundary_nodes, points, rng; kwargs...) -> (VoronoiTessellation, Number)`

Performs a single iteration of the centroidal smoothing algorithm.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`set_of_boundary_nodes`

: The set of boundary nodes in the underlying triangulation.`points`

: The underlying point set. This is a`deepcopy`

of the points of the underlying triangulation.`rng`

: The random number generator.

**Keyword Arguments**

`kwargs...`

: Extra keyword arguments passed to`retriangulate`

.

**Outputs**

`vorn`

: The updated`VoronoiTessellation`

.`max_dist`

: The maximum distance moved by any generator.

`DelaunayTriangulation._get_interval_for_get_circle_intersection`

— Method`_get_interval_for_get_circle_intersection(c::AbstractParametricCurve, t₁, t₂, r) -> (Float64, Float64, NTuple{2, Float64})`

Given a circle centered at `c(t₁)`

with radius `r`

, finds an initial interval for `get_circle_intersection`

to perform bisection on to find a point of intersection. The returned interval is `(tᵢ, tⱼ)`

, where `tᵢ`

is the parameter value of the first point in the interval and `tⱼ`

is the parameter value of the last point in the interval. (The interval does not have to be sorted.) The third returned value is `p = c(t₁)`

.

`DelaunayTriangulation._get_ray`

— Method`_get_ray(vorn, i, ghost_vertex) -> (Point, Point)`

Extracts the ray from the `i`

th polygon of `vorn`

corresponding to the `ghost_vertex`

, where `ghost_vertex`

here means that `get_polygon(vorn, i)[ghost_vertex]`

is a ghost vertex.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`i`

: The index of the polygon.`ghost_vertex`

: The index of the ghost vertex in the polygon.

**Outputs**

`p`

: The first point of the ray.`q`

: A second point of the ray, so that`pq`

gives the direction of the ray (which extends to infinity).

`DelaunayTriangulation._getx`

— Method`_getx(p) -> Float64`

Get the x-coordinate of `p`

as a `Float64`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> p = (0.37, 0.7);
julia> DelaunayTriangulation._getx(p)
0.37
julia> p = (0.37f0, 0.7f0);
julia> DelaunayTriangulation._getx(p)
0.3700000047683716
```

`DelaunayTriangulation._getxy`

— Method`_getxy(p) -> NTuple{2, Float64}`

Get the coordinates of `p`

as a `Tuple`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> p = [0.3, 0.5];
julia> DelaunayTriangulation._getxy(p)
(0.3, 0.5)
julia> p = [0.3f0, 0.5f0];
julia> DelaunayTriangulation._getxy(p)
(0.30000001192092896, 0.5)
```

`DelaunayTriangulation._gety`

— Method`_gety(p) -> Float64`

Get the y-coordinate of `p`

as a `Float64`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> p = (0.5, 0.5);
julia> DelaunayTriangulation._gety(p)
0.5
julia> p = (0.5f0, 0.5f0);
julia> DelaunayTriangulation._gety(p)
0.5
```

`DelaunayTriangulation._safe_get_adjacent`

— Method`_safe_get_adjacent(tri::Triangulation, uv) -> Vertex`

This is the safe version of `get_adjacent`

, which is used when the triangulation has multiple sections, ensuring that the correct ghost vertex is returned in case `uv`

is a ghost edge.

`DelaunayTriangulation._split_subsegment_curve_bounded!`

— Method`_split_subsegment_curve_bounded!(tri::Triangulation, args::RefinementArguments, e)`

Splits a subsegment `e`

of `tri`

at a position determined by `split_subcurve!`

for curve-bounded domains. See `split_subsegment!`

. See also `_split_subsegment_curve_bounded_standard!`

and `_split_subsegment_curve_bounded_small_angle!`

, as well as the original functions `_split_subsegment_curve_standard!`

and `_split_subcurve_complex!`

, respectively, used during boundary enrichment.

`DelaunayTriangulation._split_subsegment_piecewise_linear!`

— Method`_split_subsegment_piecewise_linear!(tri::Triangulation, args::RefinementArguments, e)`

Splits a subsegment `e`

of `tri`

at a position determined by `compute_split_position`

for piecewise linear domains. See `split_subsegment!`

.

`DelaunayTriangulation.add_adjacent!`

— Method```
add_adjacent!(adj::Adjacent, uv, w)
add_adjacent!(adj::Adjacent, u, v, w)
```

Adds the adjacency relationship `(u, v, w)`

to `adj`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj = DelaunayTriangulation.Adjacent{Int64, NTuple{2, Int64}}();
julia> DelaunayTriangulation.add_adjacent!(adj, 1, 2, 3)
Adjacent{Int64, Tuple{Int64, Int64}}, with map:
Dict{Tuple{Int64, Int64}, Int64} with 1 entry:
(1, 2) => 3
julia> DelaunayTriangulation.add_adjacent!(adj, (2, 3), 1)
Adjacent{Int64, Tuple{Int64, Int64}}, with map:
Dict{Tuple{Int64, Int64}, Int64} with 2 entries:
(1, 2) => 3
(2, 3) => 1
julia> DelaunayTriangulation.add_adjacent!(adj, 3, 1, 2)
Adjacent{Int64, Tuple{Int64, Int64}}, with map:
Dict{Tuple{Int64, Int64}, Int64} with 3 entries:
(1, 2) => 3
(3, 1) => 2
(2, 3) => 1
```

`DelaunayTriangulation.add_adjacent!`

— Method```
add_adjacent!(tri::Triangulation, uv, w)
add_adjacent!(tri::Triangulation, u, v, w)
```

Adds the key-value pair `(u, v) ⟹ w`

to the adjacency map of `tri`

.

`DelaunayTriangulation.add_adjacent!`

— Method```
add_adjacent!(vor::VoronoiTessellation, ij, k)
add_adjacent!(vor::VoronoiTessellation, i, j, k)
```

Adds the adjacency relationship `(i, j) ⟹ k`

between the oriented edge `(i, j)`

and polygon index `k`

to the Voronoi tessellation `vor`

.

`DelaunayTriangulation.add_adjacent2vertex!`

— Method```
add_adjacent2vertex!(tri::Triangulation, w, uv)
add_adjacent2vertex!(tri::Triangulation, w, u, v)
```

Adds the edge `(u, v)`

into the set of edges returned by `get_adjacent2vertex(tri, w)`

.

`DelaunayTriangulation.add_adjacent2vertex!`

— Method```
add_adjacent2vertex!(adj2v::Adjacent2Vertex, w, uv)
add_adjacent2vertex!(adj2v::Adjacent2Vertex, w, u, v)
```

Adds the edge `uv`

to the set of edges `E`

such that `(u, v, w)`

is a positively oriented triangle in the underlying triangulation for each `(u, v) ∈ E`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj2v = DelaunayTriangulation.Adjacent2Vertex{Int64, Set{NTuple{2, Int64}}}()
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}}()
julia> DelaunayTriangulation.add_adjacent2vertex!(adj2v, 1, (2, 3))
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 1 entry:
1 => Set([(2, 3)])
julia> DelaunayTriangulation.add_adjacent2vertex!(adj2v, 1, 5, 7)
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 1 entry:
1 => Set([(5, 7), (2, 3)])
julia> DelaunayTriangulation.add_adjacent2vertex!(adj2v, 17, (5, -1))
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 2 entries:
17 => Set([(5, -1)])
1 => Set([(5, 7), (2, 3)])
```

`DelaunayTriangulation.add_all_boundary_polygons!`

— Method`add_all_boundary_polygons!(vorn::VoronoiTessellation, boundary_sites)`

Add all of the boundary polygons to the Voronoi tessellation.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`boundary_sites`

: A dictionary of boundary sites.

**Outputs**

There are no outputs, but the boundary polygons are added in-place.

`DelaunayTriangulation.add_boundary_information!`

— Method`add_boundary_information!(tri::Triangulation)`

Updates `tri`

so that the ghost triangle information defined by the boundary nodes in `tri`

is added to the triangulation.

`DelaunayTriangulation.add_boundary_polygon!`

— Method`add_boundary_polygon!(vor::VoronoiTessellation, i)`

Adds the index `i`

to the set of boundary polygons of `vor`

.

`DelaunayTriangulation.add_child!`

— Method`add_child!(node::AbstractNode, child)`

Adds `child`

to `node`

, i.e. appends `child`

to the children of `node`

via `push!`

.

`DelaunayTriangulation.add_child!`

— Method`add_child!(tree::PolygonTree, child::PolygonTree)`

Adds `child`

to `tree`

.

`DelaunayTriangulation.add_edge!`

— Method`add_edge!(E, e...)`

Add the edges `e...`

to `E`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> E = Set(((1,5),(17,10),(5,3)))
Set{Tuple{Int64, Int64}} with 3 elements:
(5, 3)
(17, 10)
(1, 5)
julia> DelaunayTriangulation.add_edge!(E, (3, 2))
julia> E
Set{Tuple{Int64, Int64}} with 4 elements:
(3, 2)
(5, 3)
(17, 10)
(1, 5)
julia> DelaunayTriangulation.add_edge!(E, (1, -3), (5, 10), (1, -1))
julia> E
Set{Tuple{Int64, Int64}} with 7 elements:
(3, 2)
(5, 10)
(1, -3)
(1, -1)
(5, 3)
(17, 10)
(1, 5)
```

`DelaunayTriangulation.add_edge!`

— Method`add_edge!(events::InsertionEventHistory, e)`

Add the edge `e`

to the `added_segments`

of `events`

.

`DelaunayTriangulation.add_edge!`

— Method`add_edge!(history::PointLocationHistory{T,E}, i, j)`

Adds the edge `(i, j)`

to the `collinear_segments`

field of `history`

.

`DelaunayTriangulation.add_edge!`

— Method`add_edge!(G::Graph, u, v)`

Adds the edge `(u, v)`

to `G`

.

`DelaunayTriangulation.add_edge_to_voronoi_polygon!`

— Method`add_edge_to_voronoi_polygon!(B, vorn::VoronoiTessellation, i, k, S, m, encountered_duplicate_circumcenter) -> (Vertex, Bool, Vertex)`

Add the next edge to the Voronoi polygon for the point `i`

in the `VoronoiTessellation`

`vorn`

.

**Arguments**

`B`

: The vector of circumcenters defining the polygon.`vorn`

: The`VoronoiTessellation`

.`i`

: The polygon index.`k`

: The vertex to add.`S`

: The surrounding polygon of`i`

. See`get_surrounding_polygon`

.`m`

: The index of the next vertex in`S`

.`encountered_duplicate_circumcenter`

: Whether or not a duplicate circumcenter has been encountered.

**Outputs**

`ci`

: The index for the circumcenter of the triangle considered.`encountered_duplicate_circumcenter`

: Whether or not a duplicate circumcenter has been encountered.`k`

: The next vertex in`S`

after the input`k`

.

`DelaunayTriangulation.add_ghost_triangles!`

— Method`add_ghost_triangles!(tri::Triangulation)`

Adds all the ghost triangles to `tri`

.

`DelaunayTriangulation.add_index!`

— Method`add_index!(history::PointLocationHistory, i)`

Adds the index `i`

to the `collinear_point_indices`

field of `history`

.

`DelaunayTriangulation.add_intersection_points!`

— Method`add_intersection_points!(vorn::VoronoiTessellation, segment_intersections) -> Integer`

Adds all of the `segment_intersections`

into the polygon vertices of `vorn`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`segment_intersections`

: The intersection points from`find_all_intersections`

.

**Outputs**

`n`

: The number of polygon vertices before the intersections were added.

`DelaunayTriangulation.add_left_vertex!`

— Method`add_left_vertex!(history::PointLocationHistory, i)`

Adds the vertex `i`

to the `left_vertices`

field of `history`

.

`DelaunayTriangulation.add_neighbour!`

— Method`add_neighbour!(tri::Triangulation, u, v...)`

Adds the neighbours `v...`

to `u`

in the graph of `tri`

.

`DelaunayTriangulation.add_neighbour!`

— Method`add_neighbour!(G::Graph, u, v...)`

Adds the neighbours `v...`

to `u`

in `G`

.

`DelaunayTriangulation.add_new_triangles!`

— Method`add_new_triangles!(tri_original::Triangulation, tris)`

Adds the triangles from `tris`

to `tri_original`

.

`DelaunayTriangulation.add_point!`

— Method`add_point!(c::RepresentativeCoordinates, p)`

Treating `c`

as an arithmetic average, updates the coordinates of `c`

to include `p`

.

`DelaunayTriangulation.add_point!`

— Method`add_point!(tri::Triangulation, x, y, w; kwargs...)`

Adds the point `(x, y)`

into `tri`

with weight `w`

. This function requires that `add_weight!`

is defined on the weights stored in `tri`

. The `kwargs`

match those from `add_point!(tri::Triangulation, ::Any)`

.

`DelaunayTriangulation.add_point!`

— Method```
add_point!(tri::Triangulation, new_point; kwargs...) -> Triangle
add_point!(tri::Triangulation, x, y; kwargs...) -> Triangle
```

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`new_point`

: The point to be added to the triangulation. The second method uses`(x, y)`

to represent the new point instead. If`new_point`

is an integer, then the point added is`get_point(tri, new_point)`

.

**Keyword Arguments**

`point_indices=each_solid_vertex(tri)`

: The indices of the points to be used in the`jump_and_march`

algorithm for selecting the initial point.`m=default_num_samples(length(point_indices))`

: The number of samples (without replacement) to be used in the`jump_and_march`

algorithm for selecting the initial point.`try_points=()`

: Additional points to try for selecting the initial point, in addition to the`m`

sampled.`rng::AbstractRNG=Random.default_rng()`

: The random number generator to be used in`jump_and_march`

.`initial_search_point=integer_type(tri)(select_initial_point(tri, new_point; point_indices, m, try_points, rng))`

: The initial point to be used in`jump_and_march`

.`update_representative_point=false`

: Whether to update the representative point of the triangulation after adding the new point.`store_event_history=Val(false)`

: Whether to store the event history of the triangulation from adding the new point.`event_history=nothing`

: The event history of the triangulation from adding the new point. Only updated if`store_event_history`

is true, in which case it needs to be an`InsertionEventHistory`

object.`concavity_protection=false`

: Whether to use concavity protection for finding`V`

below. See`concavity_protection_check`

. This is only needed if your triangulation is not convex.`V=jump_and_march(tri, get_point(tri, new_point); m=nothing, point_indices=nothing, try_points=nothing, k=initial_search_point, concavity_protection, rng)`

: The positively oriented triangle containing the point being added.

In cases where your triangulation is not convex and `!concavity_protection`

, this `V`

may not be correct, and you may encounter errors - errors either during `add_point!`

or separately when you try to use the triangulation. In such cases, you should set `concavity_protection=true`

to ensure that `V`

is correct.

`peek=Val(false)`

: Whether the point should actually be added into the triangulation, or just 'peeked' at so that the events that would occur from its addition can be added into`event_history`

.

**Outputs**

The triangulation is updated in-place, but we do return

`V`

: The triangle containing the point being added.

In cases where `(x, y)`

is outside of the triangulation, it will be added successfully but note that the `convex_hull`

field of `tri`

will no longer be accurate. You can use `convex_hull!`

to fix it.

`DelaunayTriangulation.add_point_bowyer_watson!`

— Method`add_point_bowyer_watson!(tri::Triangulation, new_point, initial_search_point::I, rng::AbstractRNG=Random.default_rng(), update_representative_point=true, store_event_history=Val(false), event_history=nothing, peek::P=Val(false)) -> Triangle`

Adds `new_point`

into `tri`

.

**Arguments**

`tri`

: The triangulation.`new_point`

: The point to insert.`initial_search_point::I`

: The vertex to start the point location with`jump_and_march`

at. See`get_initial_search_point`

.`rng::AbstractRNG`

: The random number generator to use.`update_representative_point=true`

: If`true`

, then the representative point is updated. See`update_centroid_after_addition!`

.`store_event_history=Val(false)`

: If`true`

, then the event history from the insertion is stored.`event_history=nothing`

: The event history to store the event history in. Should be an`InsertionEventHistory`

if`store_event_history`

is`true`

, and`false`

otherwise.`peek=Val(false)`

: Whether to actually add`new_point`

into`tri`

, or just record into`event_history`

all the changes that would occur from its insertion.

**Output**

`V`

: The triangle in`tri`

containing`new_point`

.

**Extended help**

This function works as follows:

- First, the triangle containing the new point,
`V`

, is found using`jump_and_march`

. - Once the triangle is found, we call into
`add_point_bowyer_watson_and_process_after_found_triangle`

to properly insert the point. - Inside
`add_point_bowyer_watson_and_process_after_found_triangle`

, we first call into`add_point_bowyer_watson_after_found_triangle`

to add the point into the cavity. We then call into`add_point_bowyer_watson_onto_segment`

to make any changes necessary incase the triangulation is constrained and`new_point`

lies on a segment, since the depth-first search of the triangles containing`new_point`

in its circumcenter must be performed on each side of the segment that`new_point`

lies on.

The function `add_point_bowyer_watson_dig_cavities!`

is the main workhorse of this function from `add_point_bowyer_watson_after_found_triangle`

. See its docstring for the details.

`DelaunayTriangulation.add_point_bowyer_watson_dig_cavities!`

— Method`add_point_bowyer_watson_dig_cavities!(tri::Triangulation, new_point::N, V, q, flag, update_representative_point=true, store_event_history=Val(false), event_history=nothing, peek::F=Val(false)) where {N,F}`

Deletes all the triangles in `tri`

whose circumcircle contains `new_point`

. This leaves behind a polygonal cavity, whose boundary edges are then connected to `new_point`

, restoring the Delaunay property from `new_point`

's insertion.

**Arguments**

`tri`

: The`Triangulation`

.`new_point::N`

: The point to insert.`V`

: The triangle in`tri`

containing`new_point`

.`q`

: The point to insert.`flag`

: The position of`q`

relative to`V`

. See`point_position_relative_to_triangle`

.`update_representative_point=true`

: If`true`

, then the representative point is updated. See`update_centroid_after_addition!`

.`store_event_history=Val(false)`

: If`true`

, then the event history from the insertion is stored.`event_history=nothing`

: The event history to store the event history in. Should be an`InsertionEventHistory`

if`store_event_history`

is`true`

, and`false`

otherwise.`peek=Val(false)`

: Whether to actually add`new_point`

into`tri`

, or just record into`event_history`

all the changes that would occur from its insertion.

**Output**

There are no changes, but `tri`

is updated in-place.

**Extended help**

This function works as follows:

- To dig the cavity, we call
`dig_cavity!`

on each edge of`V`

, stepping towards the adjacent triangles to excavate the cavity recursively. - Once the cavity has been excavated, extra care is needed in case
`is_on(flag)`

, meaning`new_point`

is on one of the edges of`V`

. In particular, extra care is needed if:`is_on(flag) && (is_boundary_triangle(tri, V) || is_ghost_triangle(V) && !is_boundary_node(tri, new_point)[1])`

. The need for this check is in case`new_point`

is on a boundary edge already exists, since we need to fix the associated ghost edges. For example, a boundary edge`(i, k)`

might have been split into the edges`(i, j)`

and`(j, k)`

, which requires that the ghost triangle`(k, i, g)`

be split into`(j, i, g)`

and`(k, j, g)`

, where`g`

is the ghost vertex. This part of the function will fix this case. The need for`is_ghost_triangle(V) && !is_boundary_node(tri, new_point)[1]`

is in case the ghost edges were already correctly added. Nothing happens if the edge of`V`

that`new_point`

is on is not the boundary edge.

`DelaunayTriangulation.add_point_cavity_cdt!`

— Method`add_point_cavity_cdt!(tri::Triangulation, u, v, w, marked_vertices)`

Adds a point to the cavity `V`

left behind when deleting triangles intersected in a triangulation by an edge, updating `tri`

to do so.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

to update.`u`

: The vertex to add.`v`

: The vertex along the polygon that is next to`u`

.`w`

: The vertex along the polygon that is previous to`u`

.`marked_vertices`

: Cache for marking vertices to re-triangulate during the triangulation. This gets mutated.

**Outputs**

There is no output, but `tri`

is updated in-place, as is `marked_vertices`

if necessary.

`DelaunayTriangulation.add_point_convex_triangulation!`

— Method`add_point_convex_triangulation!(tri::Triangulation, u, v, w, S)`

Adds the point `u`

into the triangulation `tri`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`u`

: The vertex to add.`v`

: The vertex next to`u`

.`w`

: The vertex previous to`u`

.`S`

: The set of vertices of the polygon.

**Outputs**

There is no output, as `tri`

is modified in-place.

**Extended help**

This function forms part of Chew's algorithm for triangulating a convex polygon. There are some important points to make.

- Firstly, checking that
`x = get_adjacent(tri, w, v)`

is needed to prevent the algorithm from exiting the polygon.

This is important in case this algorithm is used as part of `delete_point!`

. When you are just triangulating a convex polygon by itself, this checked is the same as checking `edge_exists(tri, w, v)`

.

- For this method to be efficient, the set
`x ∈ S`

must be`O(1)`

time. This is why we use a`Set`

type for`S`

. - The algorithm is recursive, recursively digging further through the polygon to find non-Delaunay edges to adjoins with
`u`

.

`DelaunayTriangulation.add_polygon!`

— Method`add_polygon!(vor::VoronoiTessellation, B, i)`

Adds, or replaces, the polygon associated with the index `i`

with `B`

. `B`

should be a counter-clockwise sequence of vertices, with `B[begin] == B[end]`

.

`DelaunayTriangulation.add_polygon_adjacent!`

— Method`add_polygon_adjacent!(vorn::VoronoiTessellation, polygon)`

Adds the adjacent polygons of the boundary edges of the polygon `polygon`

to the adjacency list.

`DelaunayTriangulation.add_right_vertex!`

— Method`add_right_vertex!(history::PointLocationHistory, j)`

Adds the vertex `j`

to the `right_vertices`

field of `history`

.

`DelaunayTriangulation.add_segment!`

— Method```
add_segment!(tri::Triangulation, segment; rng::AbstractRNG=Random.default_rng())
add_segment!(tri::Triangulation, i, j; rng::AbstractRNG=Random.default_rng())
```

Adds `segment = (i, j)`

to `tri`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`segment`

: The segment to add. The second method uses`(i, j)`

to represent the segment instead.

**Outputs**

There is no output, but `tri`

will be updated so that it now contains `segment`

.

`DelaunayTriangulation.add_segment_intersection!`

— Method`add_segment_intersection!(segment_intersections, boundary_sites, intersection_point, incident_polygon::I) where {I} -> Integer`

Adds the `intersection_point`

into the list of `segment_intersections`

.

**Arguments**

`segment_intersections`

: The list of segment intersections.`boundary_sites`

: A mapping from boundary sites to the indices of the segment intersections that are incident to the boundary site.`intersection_point`

: The intersection point to add.`incident_polygon`

: The index of the polygon that is incident to the intersection point.

**Outputs**

`idx`

: The index of the intersection point in the list of segment intersections. iF the intersection point already exists in the list, then the index of the existing point is returned and used instead.

`DelaunayTriangulation.add_segment_to_list!`

— Method`add_segment_to_list!(tri::Triangulation, e)`

Adds `e`

to `get_interior_segments(tri)`

and `get_all_segments(tri)`

if it, or `reverse_edge(e)`

, is not already in the sets.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`e`

: The edge to add.

**Outputs**

There is no output, but `tri`

will be updated so that `e`

is in `get_interior_segments(tri)`

and `get_all_segments(tri)`

.

`DelaunayTriangulation.add_to_edges!`

— Method`add_to_edges!(E, e)`

Add the edge `e`

to `E`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> E = Set(((1, 2),(3,5)))
Set{Tuple{Int64, Int64}} with 2 elements:
(1, 2)
(3, 5)
julia> DelaunayTriangulation.add_to_edges!(E, (1, 5))
Set{Tuple{Int64, Int64}} with 3 elements:
(1, 2)
(3, 5)
(1, 5)
```

`DelaunayTriangulation.add_to_intersected_edge_cache!`

— Method`add_to_intersected_edge_cache!(intersected_edge_cache, u, v, a, b)`

Add the edge `uv`

to the list of intersected edges.

**Arguments**

`intersected_edge_cache`

: The list of intersected edges.`u`

: The first vertex of the edge of the Voronoi polygon intersecting the edge`ab`

of the boundary.`v`

: The second vertex of the edge of the Voronoi polygon intersecting the edge`ab`

of the boundary.`a`

: The first vertex of the edge of the boundary.`b`

: The second vertex of the edge of the boundary.

**Outputs**

There are no outputs, as `intersected_edge_cache`

is modified in-place.

`DelaunayTriangulation.add_to_triangles!`

— Method`add_to_triangles!(T, V)`

Add the triangle `V`

to the collection of triangles `T`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> T = Set(((1, 2, 3), (17, 8, 9)));
julia> DelaunayTriangulation.add_to_triangles!(T, (1, 5, 12))
Set{Tuple{Int64, Int64, Int64}} with 3 elements:
(1, 5, 12)
(1, 2, 3)
(17, 8, 9)
julia> DelaunayTriangulation.add_to_triangles!(T, (-1, 3, 6))
Set{Tuple{Int64, Int64, Int64}} with 4 elements:
(1, 5, 12)
(1, 2, 3)
(17, 8, 9)
(-1, 3, 6)
```

`DelaunayTriangulation.add_triangle!`

— Function```
add_triangle!(T, V...)
add_triangle!(T, i, j, k)
```

Add the triangles `V...`

or `V = (i, j, k)`

to the collection of triangles `T`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> T = Set(((1, 2, 3), (4, 5, 6)))
Set{Tuple{Int64, Int64, Int64}} with 2 elements:
(4, 5, 6)
(1, 2, 3)
julia> add_triangle!(T, (7, 8, 9));
julia> add_triangle!(T, (10, 11, 12), (13, 14, 15));
julia> add_triangle!(T, 16, 17, 18);
julia> T
Set{Tuple{Int64, Int64, Int64}} with 6 elements:
(7, 8, 9)
(10, 11, 12)
(4, 5, 6)
(13, 14, 15)
(16, 17, 18)
(1, 2, 3)
```

`DelaunayTriangulation.add_triangle!`

— Method```
add_triangle!(adj::Adjacent, u, v, w)
add_triangle!(adj::Adjacent, T)
```

Adds the adjacency relationships defined from the triangle `T = (u, v, w)`

to `adj`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj = DelaunayTriangulation.Adjacent{Int32, NTuple{2, Int32}}();
julia> add_triangle!(adj, 1, 2, 3)
Adjacent{Int32, Tuple{Int32, Int32}}, with map:
Dict{Tuple{Int32, Int32}, Int32} with 3 entries:
(1, 2) => 3
(3, 1) => 2
(2, 3) => 1
julia> add_triangle!(adj, 6, -1, 7)
Adjacent{Int32, Tuple{Int32, Int32}}, with map:
Dict{Tuple{Int32, Int32}, Int32} with 6 entries:
(1, 2) => 3
(3, 1) => 2
(6, -1) => 7
(-1, 7) => 6
(2, 3) => 1
(7, 6) => -1
```

`DelaunayTriangulation.add_triangle!`

— Method```
add_triangle!(adj2v::Adjacent2Vertex, u, v, w)
add_triangle!(adj2v::Adjacent2Vertex, T)
```

Adds the relationships defined by the triangle `T = (u, v, w)`

into `adj2v`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj2v = DelaunayTriangulation.Adjacent2Vertex{Int32, Set{NTuple{2, Int32}}}()
Adjacent2Vertex{Int32, Set{Tuple{Int32, Int32}}} with map:
Dict{Int32, Set{Tuple{Int32, Int32}}}()
julia> add_triangle!(adj2v, 17, 5, 8)
Adjacent2Vertex{Int32, Set{Tuple{Int32, Int32}}} with map:
Dict{Int32, Set{Tuple{Int32, Int32}}} with 3 entries:
5 => Set([(8, 17)])
8 => Set([(17, 5)])
17 => Set([(5, 8)])
julia> add_triangle!(adj2v, 1, 5, 13)
Adjacent2Vertex{Int32, Set{Tuple{Int32, Int32}}} with map:
Dict{Int32, Set{Tuple{Int32, Int32}}} with 5 entries:
5 => Set([(8, 17), (13, 1)])
13 => Set([(1, 5)])
8 => Set([(17, 5)])
17 => Set([(5, 8)])
1 => Set([(5, 13)])
```

`DelaunayTriangulation.add_triangle!`

— Method```
add_triangle!(G::Graph, u, v, w)
add_triangle!(G::Graph, T)
```

Adds the neighbourhood relationships defined by the triangle `T = (u, v, w)`

to the graph `G`

.

`DelaunayTriangulation.add_triangle!`

— Method`add_triangle!(events::InsertionEventHistory, T)`

Add the triangle `T`

to the `added_triangles`

of `events`

.

`DelaunayTriangulation.add_triangle!`

— Method`add_triangle!(history::PointLocationHistory, i, j, k)`

Adds the triangle `(i, j, k)`

to the `triangles`

field of `history`

.

`DelaunayTriangulation.add_triangle!`

— Method```
add_triangle!(tri::Triangulation, u, v, w; protect_boundary=false, update_ghost_edges=false)
add_triangle!(tri::Triangulation, T; protect_boundary=false, update_ghost_edges=false)
```

Adds the triangle `T = (u, v, w)`

into `tri`

. This won't add the points into `tri`

, it will just update the fields so that its existence in the triangulation is known.

**Arguments**

`tri::Triangulation`

: The triangulation to add the triangle to.`u, v, w`

: The vertices of the triangle to add.

**Keyword Arguments**

`protect_boundary=false`

: If`true`

, then the boundary edges will not be updated. Otherwise,`add_boundary_edges_single!`

,`add_boundary_edges_double!`

, or`add_boundary_edges_triple!`

will be called depending on the number of boundary edges in the triangle.`update_ghost_edges=false`

: If`true`

, then the ghost edges will be updated. Otherwise, the ghost edges will not be updated. Will only be used if`protect_boundary=false`

.

**Outputs**

There are no outputs as `tri`

is updated in-place.

`DelaunayTriangulation.add_unbounded_polygon!`

— Method`add_unbounded_polygon!(vor::VoronoiTessellation, i)`

Adds the index `i`

to the set of unbounded polygons of `vor`

.

`DelaunayTriangulation.add_vertex!`

— Method`add_vertex!(tri::Triangulation, u...)`

Adds the vertices `u...`

into the graph of `tri`

.

`DelaunayTriangulation.add_vertex!`

— Method`add_vertex!(G::Graph, u...)`

Adds the vertices `u...`

to `G`

.

`DelaunayTriangulation.add_voronoi_polygon!`

— Method`add_voronoi_polygon!(vorn::VoronoiTessellation, i) -> Vector`

Add the Voronoi polygon for the point `i`

to the `VoronoiTessellation`

`vorn`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`i`

: The polygon index.

**Outputs**

`B`

: The vector of circumcenters defining the polygon. This is a circular vector, i.e.`B[begin] == B[end]`

.

`DelaunayTriangulation.add_weight!`

— Method`add_weight!(weights, w)`

Pushes the weight `w`

into `weights`

. The default definition for this is `push!(weights, w)`

.

`DelaunayTriangulation.add_weight!`

— Method`add_weight!(tri::Triangulation, w)`

Pushes the weight `w`

into the weights of `tri`

.

`DelaunayTriangulation.adjust_θ`

— Method`adjust_θ(θ₁, θ₂, positive) -> (Number, Number)`

Given two angles `θ₁`

and `θ₂`

in radians, adjusts the angles to new angles `θ₁′`

, `θ₂′`

so that `θ₁′ ≤ θ₂′`

if `positive`

is `true`

, and `θ₁′ ≥ θ₂′`

if `positive`

is `false`

.

`DelaunayTriangulation.all_ghost_vertices`

— Method`all_ghost_vertices(tri::Triangulation) -> KeySet`

Returns the set of all ghost vertices in `tri`

.

`DelaunayTriangulation.angle_between`

— Method`angle_between(p, q) -> Float64`

Returns the angle between the vectors `p`

and `q`

in radians, treating `q`

as the base. See this article. The returned angle is in `[0, 2π)`

.

`DelaunayTriangulation.angle_between`

— Method`angle_between(c₁::AbstractParametricCurve, c₂::AbstractParametricCurve) -> Float64`

Given two curves `c₁`

and `c₂`

such that `c₁(1) == c₂(0)`

, returns the angle between the two curves, treating the interior of the curves as being left of both.

`DelaunayTriangulation.angle_between`

— Method`angle_between(enricher::BoundaryEnricher, curve_index1, curve_index2) -> Float64`

Evaluates `angle_between`

on the curves with indices `curve_index1`

and `curve_index2`

in `enricher`

.

`DelaunayTriangulation.angle_between`

— Method`angle_between(L₁::LineSegment, L₂::LineSegment) -> Float64`

Returns the angle between `L₁`

and `L₂`

, assuming that `L₁.last == L₂.first`

(this is not checked). For consistency with If the segments are part of some domain, then the line segments should be oriented so that the interior is to the left of both segments.

`DelaunayTriangulation.arc_length`

— Function```
arc_length(c::AbstractParametricCurve) -> Float64
arc_length(c::AbstractParametricCurve, t₁, t₂) -> Float64
```

Returns the arc length of the [`AbstractParametricCurve`

] `c`

. The second method returns the arc length in the interval `[t₁, t₂]`

, where `0 ≤ t₁ ≤ t₂ ≤ 1`

.

`DelaunayTriangulation.assess_added_triangles!`

— Method`assess_added_triangles!(args::RefinementArguments, tri::Triangulation)`

Assesses the quality of all triangles in `args.events.added_triangles`

according to `assess_triangle_quality`

, and enqueues any bad quality triangles into `args.queue`

.

`DelaunayTriangulation.assess_triangle_quality`

— Method`assess_triangle_quality(tri::Triangulation, args::RefinementArguments, T) -> Float64, Bool`

Assesses the quality of a triangle `T`

of `tri`

according to the `RefinementArguments`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`args::RefinementArguments`

: The`RefinementArguments`

.`T`

: The triangle.

**Output**

`ρ`

: The radius-edge ratio of the triangle.`flag`

: Whether the triangle is bad quality.

A triangle is bad quality if it does not meet the area constraints, violates the custom constraint, or if it is skinny but neither seditious or nestled.

`DelaunayTriangulation.balanced_power_of_two_quarternary_split`

— Method`balanced_power_of_two_quarternary_split(ℓ) -> Float64`

Returns the value of `s ∈ [0, ℓ]`

that gives the most balanced quarternary split of the segment `pq`

, so `s`

is a power-of-two and `s ∈ [ℓ / 4, ℓ / 2]`

.

`DelaunayTriangulation.balanced_power_of_two_ternary_split`

— Method`balanced_power_of_two_ternary_split(ℓ) -> Float64`

Returns the value of `s ∈ [0, ℓ]`

that gives the most balanced ternary split of the segment `pq`

, so `s`

is a power-of-two and `s ∈ [ℓ / 3, 2ℓ / 3]`

.

`DelaunayTriangulation.bounding_box`

— Method`bounding_box(points, i, j) -> DiametralBoundingBox`

Returns the bounding box of the diametral circle of the points `points[i]`

and `points[j]`

with generator edge `(i, j)`

, returned as an `DiametralBoundingBox`

.

`DelaunayTriangulation.bounding_box`

— Method`bounding_box(points) -> BoundingBox`

Gets the bounding box for a set of points.

`DelaunayTriangulation.bounding_box`

— Method`bounding_box(tree::BoundaryRTree, i, j) -> DiametralBoundingBox`

Returns the bounding box of the diametral circle of the edge between `i`

and `j`

in `tree`

.

`DelaunayTriangulation.bounding_box`

— Method`bounding_box(p::NTuple, q::NTuple, r::NTuple) -> BoundingBox`

Returns the bounding box of the points `p`

, `q`

and `r`

.

`DelaunayTriangulation.bounding_box`

— Method`bounding_box(center, radius) -> BoundingBox`

Returns the bounding box of the circle `(center, radius)`

.

`DelaunayTriangulation.brute_force_search`

— Method`brute_force_search(tri::Triangulation, q; itr = each_triangle(tri))`

Searches for the triangle containing the point `q`

by brute force. An exception will be raised if no triangle contains the point.

See also `jump_and_march`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`q`

: The point to be located.

**Keyword Arguments**

`itr = each_triangle(tri)`

: The iterator over the triangles of the triangulation.

**Output**

`V`

: The triangle containing the point`q`

.

`DelaunayTriangulation.brute_force_search_enclosing_circumcircle`

— Method`brute_force_search_enclosing_circumcircle(tri::Triangulation, i) -> 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, `(0, 0, 0)`

is returned.

`DelaunayTriangulation.cache_node!`

— Function`cache_node!(tree::RTree, node::AbstractNode)`

Caches `node`

in into `tree`

's node caches.

`DelaunayTriangulation.cache_node!`

— Method`cache_node!(cache::NodeCache, node)`

Caches `node`

in `cache`

if `cache`

is not full. Otherwise, does nothing.

`DelaunayTriangulation.centroidal_smooth`

— Method`centroidal_smooth(vorn::VoronoiTessellation; maxiters=1000, tol=default_displacement_tolerance(vorn), rng=Random.default_rng(), kwargs...) -> VoronoiTessellation`

Smooths `vorn`

into a centroidal tessellation so that the new tessellation is of a set of generators whose associated Voronoi polygon is that polygon's centroid.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.

**Keyword Arguments**

`maxiters=1000`

: The maximum number of iterations.`tol=default_displacement_tolerance(vorn)`

: The displacement tolerance. See`default_displacement_tolerance`

for the default.`rng=Random.default_rng()`

: The random number generator.`kwargs...`

: Extra keyword arguments passed to`retriangulate`

.

**Outputs**

`vorn`

: The updated`VoronoiTessellation`

. This is not done in-place.

**Extended help**

The algorithm is simple. We iteratively smooth the generators, moving them to the centroid of their associated Voronoi polygon for the current tessellation, continuing until the maximum distance moved of any generator is less than `tol`

. Boundary generators are not moved.

`DelaunayTriangulation.check_absolute_precision`

— Method`check_absolute_precision(x, y) -> Bool`

Returns `true`

if `abs(x - y)`

is less than or equal to `sqrt(eps(Float64))`

.

`DelaunayTriangulation.check_args`

— Method`check_args(points, boundary_nodes, hierarchy::PolygonHierarchy) -> Bool`

Check that the arguments `points`

and `boundary_nodes`

to `triangulate`

, and a constructed `PolygonHierarchy`

given by `hierarchy`

, are valid. In particular, the function checks:

- The points are all unique. If they are not, a
`DuplicatePointsError`

is thrown. - There are at least three points. If there are not, an
`InsufficientPointsError`

is thrown.

If `boundary_nodes`

are provided, meaning `has_boundary_nodes`

, then the function also checks:

- If the boundary curves all connect consistently. Here, this means that each section of a boundary curve ends at the start of the next boundary section; for contiguous boundary curves, this means that the start and end boundary nodes are the same.
- If the orientation of the boundary curves are all consistent. This means that the curves are all positively oriented relative to the domain, so that e.g. the exterior boundary curves are all counter-clockwise (relative to just themselves), the next exterior-most curves inside those exteriors are all clockwise (again, relative to just themselves), and so on.

Another requirement for `triangulate`

is that none of the boundaries intersect in their interior, which also prohibits interior self-intersections. This is NOT checked. Similarly, segments should not intersect in their interior, which is not checked.

`DelaunayTriangulation.check_delete_point_args`

— Method`check_delete_point_args(tri::Triangulation, vertex, S) -> Bool`

Checks that the vertex `vertex`

can be deleted from the triangulation `tri`

. Returns `true`

if so, and throws an `InvalidVertexDeletionError`

otherwise. This will occur if:

`vertex`

is a boundary node of`tri`

.`vertex`

is a ghost vertex of`tri`

.`vertex`

adjoins a segment of`tri`

.

`DelaunayTriangulation.check_for_intersections_with_adjacent_boundary_edges`

— Method`check_for_intersections_with_adjacent_boundary_edges(tri::Triangulation, k, q, ghost_vertex=𝒢) -> (Certificate, Certificate, Vertex, Certificate, Certificate)`

Given a boundary vertex `k`

, find a triangle adjacent to `k`

to locate a triangle or edge containing `q`

.

See also `search_down_adjacent_boundary_edges`

, which uses this function to determine an initial direction to search along a straight boundary in case `q`

is collinear with it.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`k`

: The boundary vertex to start from.`q`

: The query point.`ghost_vertex=𝒢`

: The ghost vertex corresponding to the boundary that`k`

resides on.

**Outputs**

`direction_cert`

: The direction of`q`

relative to the vertex`k`

along the boundary, given as a`Certificate`

`Left`

,`Right`

, or`Outside`

. If`is_outside(direction_cert)`

, then`q`

is not collinear with either of the adjacent boundary edges.`q_pos_cert`

: The position of`q`

relative to the vertex`k`

along the boundary, given as a`Certificate`

`Left`

,`Right`

,`On`

,`Outside`

, or`Degenerate`

. This is similar to`direction_cert`

in that it will be`Outside`

whenever`direction_cert`

is, but this certificate can also be`On`

to indicate that not only is`q`

in the direction given by`direction_cert`

, but it is directly on the edge in that direction. If`is_degnerate(q_pos_cert)`

, then`q = get_point(tri, next_vertex)`

.`next_vertex`

: The next vertex along the boundary in the direction of`q`

, or`k`

if`q`

is not collinear with either of the adjacent boundary edges.`right_cert`

: The`Certificate`

for the position of`q`

relative to the boundary edge right of`k`

.`left_cert`

: The`Certificate`

for the position of`q`

relative to the boundary edge left of`k`

.

`DelaunayTriangulation.check_for_intersections_with_interior_edges_adjacent_to_boundary_vertex`

— Method`check_for_intersections_with_interior_edges_adjacent_to_boundary_vertex(tri::Triangulation, k, q, right_cert, left_cert, store_history=Val(false), history=nothing, ghost_vertex=𝒢) -> (Bool, Vertex, Vertex, Certificate, Certificate)`

Checks for intersections between the line `pq`

, where `p = get_point(tri, k)`

, and the edges neighbouring `p`

, assuming `k`

is a boundary node. This function should only be used after using `check_for_intersections_with_adjacent_boundary_edges`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`k`

: The boundary vertex to start from.`q`

: The query point.`right_cert`

: The`Certificate`

for the position of`q`

relative to the boundary edge right of`k`

, coming from`check_for_intersections_with_adjacent_boundary_edges`

.`left_cert`

: The`Certificate`

for the position of`q`

relative to the boundary edge left of`k`

, coming from`check_for_intersections_with_adjacent_boundary_edges`

.`store_history=Val(false)`

: Whether to store the history of the algorithm.`history=nothing`

: The history of the algorithm. If`store_history`

, then this should be a`PointLocationHistory`

object.`ghost_vertex=𝒢`

: The ghost vertex corresponding to the boundary that`k`

resides on.

**Outputs**

The output takes the form `(i, j, edge_cert, triangle_cert)`

. Rather than defining each output individually, here are the possible froms of the output:

`(i, j, Single, Outside)`

: The line`pq`

intersects the edge`pᵢpⱼ`

and`(j, i, k)`

is a positively oriented triangle so that`pᵢ`

is left of`pq`

and`pⱼ`

is right of`pq`

.`(i, j, None, Inside)`

: The point`q`

is inside the positively oriented triangle`(i, j, k)`

.`(0, 0, None, Outside)`

: The point`q`

is outside of the triangulation.`(i, j, On, Inside)`

: The point`q`

is on the edge`pᵢpⱼ`

, and thus inside the positively oriented triangle`(i, j, k)`

.`(i, j, Right, Outside)`

:`The point`

q`is collinear with the edge`

pᵢpⱼ`, but is off of it and further into the triangulation.

This function assumes that the geometry is convex.

**Extended help**

This function works in two stages. Firstly, using `check_for_intersections_with_single_interior_edge_adjacent_to_boundary_vertex`

, we check for the intersection of `pq`

with the edges neighbouring the vertex `k`

, rotating counter-clockwise until we find an intersection or reach the other side of the boundary, starting from the first edge counter-clockwise away from the boundary edge right of the vertex `k`

. By keeping track of the positions of `pq`

relative to the current vertex and the previous, we can identify when an intersection is found. If no intersection is found before reaching the boundary edge left of `k`

, then `check_for_intersections_with_triangle_left_to_boundary_vertex`

is used to check the remaining triangle.

`DelaunayTriangulation.check_for_invisible_steiner_point`

— Method`check_for_invisible_steiner_point(tri::Triangulation, V, T, flag, c) -> Point, Triangle`

Determines if the Steiner point `c`

's insertion will not affect the quality of `T`

, and if so instead changes `c`

to be `T`

's centroid.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

to split a triangle of.`V`

: The triangle that the Steiner point is in.`T`

: The triangle that the Steiner point is from.`flag`

: A`Certificate`

which is`Cert.On`

if the Steiner point is on the boundary of`V`

,`Cert.Outside`

if the Steiner point is outside of`V`

, and`Cert.Inside`

if the Steiner point is inside of`V`

.`c`

: The Steiner point.

**Output**

`c′`

: The Steiner point to use instead of`c`

, which is`T`

's centroid if`c`

is not suitable.`V′`

: The triangle that the Steiner point is in, which is`T`

if`c`

is not suitable.

`DelaunayTriangulation.check_for_steiner_point_on_segment`

— Method`check_for_steiner_point_on_segment(tri::Triangulation, V, V′, new_point, flag) -> Bool`

Checks if the Steiner point with vertex `new_point`

is on a segment. If so, then its vertex is pushed into the offcenter-split list from `args`

, indicating that it should no longer be regarded as a free vertex (see `is_free`

).

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`V`

: The triangle that the Steiner point was originally in prior to`check_for_invisible_steiner_point`

.`V′`

: The triangle that the Steiner point is in.`new_point`

: The vertex associated with the Steiner point.`flag`

: A`Certificate`

which is`Cert.On`

if the Steiner point is on the boundary of`V`

,`Cert.Outside`

if the Steiner point is outside of`V`

, and`Cert.Inside`

if the Steiner point is inside of`V`

.

**Output**

`onflag`

: Whether the Steiner point is on a segment or not.

`DelaunayTriangulation.check_precision`

— Method`check_precision(x) -> Bool`

Returns `true`

if `abs(x)`

is less than or equal to `sqrt(eps(Float64))`

.

`DelaunayTriangulation.check_ratio_precision`

— Method`check_ratio_precision(x, y) -> Bool`

Returns `true`

if `abs(x/y)`

is bounded between `0.99`

and `1.01`

.

`DelaunayTriangulation.check_relative_precision`

— Method`check_relative_precision(x, y) -> Bool`

Returns `true`

if `abs(x - y)/max(abs(x), abs(y))`

is less than or equal to `sqrt(eps(Float64))`

.

`DelaunayTriangulation.check_seditious_precision`

— Method`check_seditious_precision(ℓrp, ℓrq) -> Bool`

Checks if there are precision issues related to the seditiousness of a triangle, returning `true`

if so and `false`

otherwise.

`DelaunayTriangulation.check_split_subsegment_precision`

— Method`check_split_subsegment_precision(mx, my, p, q) -> Bool`

Checks if there are precision issues related to the computed split position `(mx, my)`

of a segment `(p, q)`

, returning `true`

if so and `false`

otherwise.

`DelaunayTriangulation.check_steiner_point_precision`

— Method`check_steiner_point_precision(tri::Triangulation, T, c) -> Bool`

Checks if the Steiner point `c`

of a triangle `T`

of `tri`

can be computed without precision issues, returning `true`

if there are precision issues and `false`

otherwise.

`DelaunayTriangulation.choose_uvw`

— Method`choose_uvw(e1, e2, e3, u, v, w) -> (Vertex, Vertex, Vertex)`

Choose values for `(u, v, w)`

based on the Booleans `(e1, e2, e3)`

, assuming only one is true. The three cases are:

- If
`e1`

, returns`(u, v, w)`

. - If
`e2`

, returns`(v, w, u)`

. - If
`e3`

, returns`(w, u, v)`

.

`DelaunayTriangulation.circular_equality`

— Function`circular_equality(A, B, by=isequal) -> Bool`

Compares the two circular vectors `A`

and `B`

for equality up to circular rotation, using `by`

to compare individual elements.

`DelaunayTriangulation.classify_and_compute_segment_intersection`

— Method`classify_and_compute_segment_intersection(a, b, c, d) -> (Certificate, Certificate, Certificate, NTuple{2, Number})`

Given two line segments `(a, b)`

and `(c, d)`

, classifies the intersection of the two segments. The returned value is `(cert, cert_c, cert_d, p)`

, where:

`cert`

: A`Certificate`

indicating the intersection type.`cert_c`

: A`Certificate`

indicating the position of`c`

relative to the line through`(a, b)`

.`cert_d`

: A`Certificate`

indicating the position of`d`

relative to the line through`(a, b)`

.`p`

: The intersection point if`cert`

is`Cert.Single`

or`Cert.Touching`

, and`(NaN, NaN)`

otherwise.

`DelaunayTriangulation.classify_intersections!`

— Method`classify_intersections!(intersected_edge_cache, left_edge_intersectors, right_edge_intersectors, current_edge_intersectors, left_edge, right_edge, current_edge)`

Classify the intersections in `intersected_edge_cache`

into `left_edge_intersectors`

, `right_edge_intersectors`

, and `current_edge_intersectors`

based on whether they intersect `left_edge`

, `right_edge`

, or `current_edge`

, respectively.

**Arguments**

`intersected_edge_cache`

: The list of intersected edges currently being considered.`left_edge_intersectors`

: The set of sites that intersect the edge to the left of an edge currently being considered.`right_edge_intersectors`

: The set of sites that intersect the edge to the right of an edge currently being considered.`current_edge_intersectors`

: The set of sites that intersect the current edge being considered.`left_edge`

: The edge to the left of`e`

on the boundary.`right_edge`

: The edge to the right of`e`

on the boundary.`current_edge`

: The edge on the boundary being considered.

**Outputs**

There are no outputs, but `left_edge_intersectors`

, `right_edge_intersectors`

, or `current_edge_intersectors`

are updated all in-place depending on the type of intersection for each edge in `intersected_edge_cache`

.

`DelaunayTriangulation.clear_empty_features!`

— Method`clear_empty_features!(tri::Triangulation)`

Clears all empty features from the triangulation `tri`

.

`DelaunayTriangulation.clear_empty_keys!`

— Method`clear_empty_keys!(adj2v::Adjacent2Vertex)`

Deletes all vertices `w`

from `adj2v`

such that `get_adjacent2vertex(adj2v, w)`

is empty.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj2v = DelaunayTriangulation.Adjacent2Vertex{Int64, Set{NTuple{2, Int64}}}()
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}}()
julia> add_triangle!(adj2v, 1, 2, 3)
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 3 entries:
2 => Set([(3, 1)])
3 => Set([(1, 2)])
1 => Set([(2, 3)])
julia> delete_triangle!(adj2v, 2, 3, 1)
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 3 entries:
2 => Set()
3 => Set()
1 => Set()
julia> DelaunayTriangulation.clear_empty_keys!(adj2v)
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}}()
```

`DelaunayTriangulation.clear_empty_vertices!`

— Method`clear_empty_vertices!(G::Graph)`

Deletes all empty vertices from `G`

.

`DelaunayTriangulation.clip_all_polygons!`

— Method`clip_all_polygons!(vorn::VoronoiTessellation, n, boundary_sites, exterior_circumcenters, equal_circumcenter_mapping, is_convex)`

Clip all of the polygons in the Voronoi tessellation.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`n`

: The number of vertices in the tessellation before clipping.`boundary_sites`

: A dictionary of boundary sites.`exterior_circumcenters`

: Any exterior circumcenters to be filtered out.`equal_circumcenter_mapping`

: A mapping from the indices of the segment intersections that are equal to the circumcenter of a site to the index of the site.`is_convex`

: Whether the boundary is convex or not. Not currently used.

**Outputs**

There are no outputs, but the polygons are clipped in-place.

`DelaunayTriangulation.clip_bounded_polygon_to_bounding_box`

— Method`clip_bounded_polygon_to_bounding_box(vorn::VoronoiTessellation, i, bounding_box) -> Vector{NTuple{2,Number}}`

Clips the `i`

th polygon of `vorn`

to `bounding_box`

.

See also `clip_polygon`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`i`

: The index of the polygon.`bounding_box`

: The bounding box to clip the polygon to.

**Outputs**

`coords`

: The coordinates of the clipped polygon. This is a circular vector.

`DelaunayTriangulation.clip_polygon!`

— Method`clip_polygon!(vorn::VoronoiTessellation, n, points, polygon, new_verts, exterior_circumcenters, equal_circumcenter_mapping, is_convex)`

Clip the polygon `polygon`

by removing the vertices that are outside of the domain and adding the new vertices `new_verts`

to the polygon.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`n`

: The number of vertices in the tessellation before clipping.`points`

: The polygon points of the tessellation.`polygon`

: The index of the polygon to be clipped.`new_verts`

: The indices of the new vertices that are added to the polygon.`exterior_circumcenters`

: Any exterior circumcenters to be filtered out.`equal_circumcenter_mapping`

: A mapping from the indices of the segment intersections that are equal to the circumcenter of a site to the index of the site.`is_convex`

: Whether the boundary is convex or not. Not currently used.

**Outputs**

There are no outputs, but the polygon is clipped in-place.

`DelaunayTriangulation.clip_polygon`

— Method`clip_polygon(vertices, points, clip_vertices, clip_points) -> Vector`

Clip a polygon defined by `(vertices, points)`

to a convex clip polygon defined by `(clip_vertices, clip_points)`

with the Sutherland-Hodgman algorithm. The polygons should be defined in counter-clockwise order.

**Arguments**

`vertices`

: The vertices of the polygon to be clipped.`points`

: The underlying point set that the vertices are defined over.`clip_vertices`

: The vertices of the clipping polygon.`clip_points`

: The underlying point set that the clipping vertices are defined over.

**Output**

`clipped_polygon`

: The coordinates of the clipped polygon, given in counter-clockwise order and`clipped_polygon[begin] == clipped_polygon[end]`

.

`DelaunayTriangulation.clip_unbounded_polygon_to_bounding_box`

— Method`clip_unbounded_polygon_to_bounding_box(vorn::VoronoiTessellation, i, bounding_box) -> Vector{NTuple{2,Number}}`

Clips the `i`

th polygon of `vorn`

to `bounding_box`

. The polygon is assumed to be unbounded. See also `clip_polygon`

.

`DelaunayTriangulation.clip_voronoi_tessellation!`

— Function`clip_voronoi_tessellation!(vorn::VoronoiTessellation, is_convex=true)`

Clip the Voronoi tessellation `vorn`

to the convex hull of the generators in `vorn`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`is_convex`

: Whether the boundary is convex or not. Not currently used.

**Outputs**

There are no outputs, but the Voronoi tessellation is clipped in-place.

`DelaunayTriangulation.close_voronoi_polygon!`

— Method`close_voronoi_polygon!(vorn::VoronoiTessellation, B, i, encountered_duplicate_circumcenter, prev_ci)`

Close the Voronoi polygon for the point `i`

in the `VoronoiTessellation`

`vorn`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`B`

: The vector of circumcenters defining the polygon.`i`

: The polygon index.`encountered_duplicate_circumcenter`

: Whether or not a duplicate circumcenter has been encountered.`prev_ci`

: The previous circumcenter index.

**Outputs**

There are no outputs, as `vorn`

and `B`

are modified in-place.

`DelaunayTriangulation.coarse_discretisation!`

— Method`coarse_discretisation!(points, boundary_nodes, boundary_curve; n=0)`

Constructs an initial coarse discretisation of a curve-bounded domain with bonudary defines by `(points, boundary_nodes, boundary_curves)`

, where `boundary_nodes`

and `boundary_curves`

should come from `convert_boundary_curves!`

. The argument `n`

is the amount of times to split an edge. If non-zero, this should be a power of two (otherwise it will be rounded up to the next power of two). If it is zero, then the splitting will continue until the maximum total variation over any subcurve is less than π/2.

`DelaunayTriangulation.collapse_after_deletion!`

— Method`collapse_after_deletion!(node::AbstractNode, tree::RTree, detached)`

Condenses `tree`

after a deletion of one of `node`

's children. The `detached`

argument will contain the nodes that were detached from `tree`

during the condensing process.

`DelaunayTriangulation.compare_distance`

— Method`compare_distance(current_dist, current_idx, pts, i, qx, qy) -> (Number, Vertex)`

Computes the minimum of the distance between the `i`

th point of `pts`

and `(qx, qy)`

and `current_dist`

.

**Arguments**

`current_dist`

: The current value for the distance to the point`(qx, qy)`

.`current_idx`

: The point of`pts`

corresponding to the distance`current_dist`

.`pts`

: The point set.`i`

: The vertex to compare with`current_idx`

.`qx`

: The x-coordinate of the query point.`qy`

: The y-coordinate of the query point.

**Outputs**

`current_dist`

: The minimum of the distance between the`i`

th point of`pts`

and`(qx, qy)`

and`current_dist`

.`current_idx`

: The point of`pts`

corresponding to the distance`current_dist`

, which will be either`i`

or`current_idx`

.

`DelaunayTriangulation.compare_triangle_collections`

— Method`compare_triangle_collections(T, V) -> Bool`

Compare the collections of triangles `T`

and `V`

by comparing their triangles according to `compare_triangles`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> T = Set(((1, 2, 3), (4, 5, 6), (7, 8, 9)));
julia> V = [[2, 3, 1], [4, 5, 6], [9, 7, 8]];
julia> DelaunayTriangulation.compare_triangle_collections(T, V)
true
julia> V[1] = [17, 19, 20];
julia> DelaunayTriangulation.compare_triangle_collections(T, V)
false
julia> V = [[1, 2, 3], [8, 9, 7]];
julia> DelaunayTriangulation.compare_triangle_collections(T, V)
false
```

`DelaunayTriangulation.compare_triangles`

— Method`compare_triangles(T, V) -> Bool`

Compare the triangles `T`

and `V`

by comparing their vertices up to rotation.

**Examples**

```
julia> using DelaunayTriangulation
julia> T1 = (1, 5, 10);
julia> T2 = (17, 23, 20);
julia> DelaunayTriangulation.compare_triangles(T1, T2)
false
julia> T2 = (5, 10, 1);
julia> DelaunayTriangulation.compare_triangles(T1, T2)
true
julia> T2 = (10, 1, 5);
julia> DelaunayTriangulation.compare_triangles(T1, T2)
true
julia> T2 = (10, 5, 1);
julia> DelaunayTriangulation.compare_triangles(T1, T2)
false
```

`DelaunayTriangulation.compare_unoriented_edge_collections`

— Methodcompare*unoriented*edge_collections(E, F) -> Bool

Tests if the edge collections `E`

and `F`

are equal, ignoring edge orientation.

`DelaunayTriangulation.compare_unoriented_edges`

— Method`compare_unoriented_edges(u, v) -> Bool`

Compare the unoriented edges `u`

and `v`

, i.e. compare the vertices of `u`

and `v`

in any order.

**Examples**

```
julia> using DelaunayTriangulation
julia> u = (1, 3);
julia> v = (5, 3);
julia> DelaunayTriangulation.compare_unoriented_edges(u, v)
false
julia> v = (1, 3);
julia> DelaunayTriangulation.compare_unoriented_edges(u, v)
true
julia> v = (3, 1);
julia> DelaunayTriangulation.compare_unoriented_edges(u, v)
true
```

`DelaunayTriangulation.complete_split_edge_and_legalise!`

— Function`complete_split_edge_and_legalise!(tri::Triangulation, i, j, r, store_event_history=Val(false), event_history=nothing)`

Given a triangulation `tri`

, an edge `(i, j)`

, and a point `r`

, splits both `(i, j)`

and `(j, i)`

at `r`

using `split_edge!`

and then subsequently legalises the new edges with `legalise_split_edge!`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`i`

: The first vertex of the edge to split.`j`

: The second vertex of the edge to split.`r`

: The vertex to split the edge at.`store_event_history=Val(false)`

: Whether to store the event history of the flip.`event_history=nothing`

: The event history. Only updated if`store_event_history`

is true, in which case it needs to be an`InsertionEventHistory`

object.

**Outputs**

There is no output, as `tri`

is updated in-place.

`DelaunayTriangulation.complete_split_triangle_and_legalise!`

— Method`complete_split_triangle_and_legalise!(tri::Triangulation, i, j, k, r)`

Splits the triangle `(i, j, k)`

at the vertex `r`

, assumed to be inside the triangle, and legalises the newly added edges in `tri`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`i`

: The first vertex of the triangle.`j`

: The second vertex of the triangle.`k`

: The third vertex of the triangle.`r`

: The vertex to split the triangle at.

**Outputs**

There is no output, as `tri`

is updated in-place.

`DelaunayTriangulation.compute_balance`

— Method`compute_balance(node::Union{Nothing,BalancedBSTNode{K}}) -> Int8`

Computes the balance of the subtree rooted at `node`

. This is the difference between the left and right heights.

`DelaunayTriangulation.compute_centroid!`

— Method`compute_centroid!(c::RepresentativeCoordinates, points)`

Computes the centroid of `points`

and stores the result in `c`

.

`DelaunayTriangulation.compute_concentric_shell_quarternary_split_position`

— Method`compute_concentric_shell_quarternary_split_position(p, q) -> Float64`

Returns the value of `t ∈ [0, 1]`

that gives the most balanced quarternary split of the segment `pq`

, so that one of the segments has a power-of-two length between 1/4 and 1/2 of the length of `pq`

.

`DelaunayTriangulation.compute_concentric_shell_ternary_split_position`

— Method`compute_concentric_shell_ternary_split_position(p, q) -> Float64`

Returns the value of `t ∈ [0, 1]`

that gives the most balanced ternary split of the segment `pq`

, so that one of the segments has a power-of-two length and both segments have lengths between 1/3 and 2/3 of the length of `pq`

.

`DelaunayTriangulation.compute_count`

— Method`compute_count(node::Union{Nothing,BalancedBSTNode{K}}) -> Int32`

Computes the count of the subtree rooted at `node`

, i.e. the number of nodes in the subtree rooted at `node`

, including `node`

.

`DelaunayTriangulation.compute_height`

— Method`compute_height(node::Union{Nothing,BalancedBSTNode{K}}) -> Int8`

Computes the height of the subtree rooted at `node`

.

`DelaunayTriangulation.compute_representative_points!`

— Method`compute_representative_points!(tri::Triangulation; use_convex_hull=!has_boundary_nodes(tri), precision=one(number_type(tri)))`

Computes a new set of representative points for `tri`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

for which to compute the representative points.

**Keyword Arguments**

`use_convex_hull=!has_boundary_nodes(tri)`

: If`true`

, then the representative points are computed using the convex hull of the triangulation. Otherwise, the representative points are computed using the boundary nodes of the triangulation.`precision=one(number_type(tri))`

: The precision to use when computing the representative points via`pole_of_inaccessibility`

.

**Output**

There are no outputs as `tri`

is updated in-place, but for each curve the representative point is computed using `pole_of_inaccessibility`

.

While `get_exterior_curve_indices(tri)`

does store the curves corresponding to exterior curves, this function still treats the first curve as the most important exterior curve, computing the representative point so that it is in no holes. In particular, other exterior curves might have representative points that are in a hole of one of their interior holes. This isn't much of a problem, indeed it wouldn't be a significant problem even if we had the representative point in a hole of the first curve, but it is something to be aware of.

`DelaunayTriangulation.compute_split_position`

— Method`compute_split_position(enricher::BoundaryEnricher, i, j) -> (Float64, Float64, NTuple{2,Float64})`

Gets the point to split the edge `(i, j)`

at.

**Arguments**

`enricher::BoundaryEnricher`

: The enricher.`i`

: The first point of the edge.`j`

: The second point of the edge.

**Outputs**

`t`

: The parameter value of the split point.`Δθ`

: The total variation of the subcurve`(i, t)`

. If a split was created due to a small angle, this will be set to zero.`ct`

: The point to split the edge at.

`DelaunayTriangulation.compute_split_position`

— Method`compute_split_position(tri::Triangulation, args::RefinementArguments, e) -> NTuple{2, Float64}`

Computes the position to split a segment `e`

of `tri`

at in `split_subsegment!`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

to split a segment of.`args::RefinementArguments`

: The`RefinementArguments`

for the refinement.`e`

: The segment to split.

**Output**

`mx, my`

: The position to split the segment at.

This point is computed according to a set of rules:

- If
`e`

is not a subsegment, meaning it is an input segment, then its midpoint is returned. - If
`e`

is a subsegment and the segment adjoins two other distinct segments (one for each vertex) at an acute angle, as determined by`segment_vertices_adjoin_other_segments_at_acute_angle`

, then the point is returned so that`e`

can be split such that one of the new subsegments has a power-of-two length between 1/4 and 1/2 of the length of`e`

, computed using`compute_concentric_shell_quarternary_split_position`

. - If
`e`

is a subsegment and the segment adjoins one other segment at an acute angle, as determined by`segment_vertices_adjoin_other_segments_at_acute_angle`

, then the point is returned so that`e`

can be split such that one of the new subsegments has a power-of-two length between 1/3 and 2/3 of the length of`e`

, computed using`compute_concentric_shell_ternary_split_position`

. - Otherwise, the midpoint is returned.

`DelaunayTriangulation.concavity_protection_check`

— Method`concavity_protection_check(tri::Triangulation, concavity_protection, V, q) -> Bool`

Check whether the `jump_and_march`

algorithm needs to restart. This is only needed if `tri`

is not convex.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`concavity_protection`

: Whether this check is needed.`V`

: The triangle that the algorithm has found.`q`

: The query point.

**Outputs**

`need_to_restart`

: Whether the algorithm needs to restart. Will also be`false`

if`concavity_protection`

.

**Extended help**

This function uses `dist`

to determine whether the query point `q`

is inside or outside of the polygon defined by the triangulation, and also checks the position of `q`

relative to `V`

via `point_position_relative_to_triangle`

. If `q`

is outside of this triangle, then `need_to_restart = true`

. If `q`

is inside this triangle, then issues can still arise due to overlapping ghost triangles from the non-convexity. Thus, depending on the result from `dist`

and whether `V`

is a ghost triangle, `need_to_restart`

will be set accordingly.

`DelaunayTriangulation.connect_circumcenters!`

— Method`connect_circumcenters!(B, ci)`

Add the circumcenter index `ci`

to the array `B`

.

`DelaunayTriangulation.connect_segments!`

— Method`connect_segments!(segments)`

Connects the ordered vector of `segments`

so that the endpoints all connect, preserving order.

**Example**

```
julia> using DelaunayTriangulation
julia> segments = [(7, 12), (12, 17), (17, 22), (32, 37), (37, 42), (42, 47)];
julia> DelaunayTriangulation.connect_segments!(segments)
7-element Vector{Tuple{Int64, Int64}}:
(7, 12)
(12, 17)
(17, 22)
(22, 32)
(32, 37)
(37, 42)
(42, 47)
```

`DelaunayTriangulation.constrained_triangulation!`

— Method`constrained_triangulation!(tri::Triangulation, segments, boundary_nodes, full_polygon_hierarchy; rng=Random.default_rng(), delete_holes=true) -> Triangulation`

Creates a constrained triangulation from `tri`

by adding `segments`

and `boundary_nodes`

to it. This will be in-place, but a new triangulation is returned to accommodate the changed types.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`segments`

: The interior segments to add to the triangulation.`boundary_nodes`

: The boundary nodes to add to the triangulation.`full_polygon_hierarchy`

: The`PolygonHierarchy`

defining the boundary. This will get copied into the existing polygon hierarchy.

**Keyword Arguments**

`rng=Random.default_rng()`

: The random number generator to use.`delete_holes=true`

: Whether to delete holes in the triangulation. See`delete_holes!`

.

**Outputs**

`new_tri`

: The new triangulation, now containing`segments`

in the`interior_segments`

field and`boundary_nodes`

in the`boundary_nodes`

field, and with the updated`PolygonHierarchy`

. See also`remake_triangulation_with_constraints`

and`replace_ghost_vertex_information`

.

`DelaunayTriangulation.construct_boundary_edge_map`

— Method`construct_boundary_edge_map(boundary_nodes::A, IntegerType::Type{I}=number_type(boundary_nodes), EdgeType::Type{E}=NTuple{2,IntegerType}) where {A,I,E} -> Dict`

Constructs a map that takes boundary edges in `boundary_nodes`

to a `Tuple`

giving the edge's position in `boundary_nodes`

. In particular, if `dict = construct_boundary_edge_map(boundary_nodes)`

, then `dict[e] = (pos, ℓ)`

so that `bn = get_boundary_nodes(boundary_nodes, pos)`

gives the boundary nodes associated with the section that `e`

lives on, and `get_boundary_nodes(bn, ℓ)`

is the first vertex of `e`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.construct_boundary_edge_map([17, 18, 15, 4, 3, 17])
Dict{Tuple{Int64, Int64}, Tuple{Vector{Int64}, Int64}} with 5 entries:
(18, 15) => ([17, 18, 15, 4, 3, 17], 2)
(3, 17) => ([17, 18, 15, 4, 3, 17], 5)
(17, 18) => ([17, 18, 15, 4, 3, 17], 1)
(4, 3) => ([17, 18, 15, 4, 3, 17], 4)
(15, 4) => ([17, 18, 15, 4, 3, 17], 3)
julia> DelaunayTriangulation.construct_boundary_edge_map([[5, 17, 3, 9], [9, 18, 13, 1], [1, 93, 57, 5]])
Dict{Tuple{Int64, Int64}, Tuple{Int64, Int64}} with 9 entries:
(18, 13) => (2, 2)
(17, 3) => (1, 2)
(9, 18) => (2, 1)
(13, 1) => (2, 3)
(3, 9) => (1, 3)
(93, 57) => (3, 2)
(5, 17) => (1, 1)
(57, 5) => (3, 3)
(1, 93) => (3, 1)
julia> DelaunayTriangulation.construct_boundary_edge_map([[[2, 5, 10], [10, 11, 2]], [[27, 28, 29, 30], [30, 31, 85, 91], [91, 92, 27]]])
Dict{Tuple{Int64, Int64}, Tuple{Tuple{Int64, Int64}, Int64}} with 12 entries:
(92, 27) => ((2, 3), 2)
(2, 5) => ((1, 1), 1)
(11, 2) => ((1, 2), 2)
(10, 11) => ((1, 2), 1)
(30, 31) => ((2, 2), 1)
(91, 92) => ((2, 3), 1)
(29, 30) => ((2, 1), 3)
(31, 85) => ((2, 2), 2)
(27, 28) => ((2, 1), 1)
(5, 10) => ((1, 1), 2)
(28, 29) => ((2, 1), 2)
(85, 91) => ((2, 2), 3)
```

`DelaunayTriangulation.construct_curve_index_map!`

— Method`construct_curve_index_map!(enricher::BoundaryEnricher)`

Constructs the curve index map for `enricher`

, modifying the curve index map field in-place.

`DelaunayTriangulation.construct_edge`

— Function`construct_edge(::Type{E}, i, j) where {E} -> E`

Construct an edge of type `E`

from vertices `i`

and `j`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.construct_edge(NTuple{2,Int}, 2, 5)
(2, 5)
julia> DelaunayTriangulation.construct_edge(Vector{Int32}, 5, 15)
2-element Vector{Int32}:
5
15
```

`DelaunayTriangulation.construct_ghost_vertex_map`

— Method`construct_ghost_vertex_map(boundary_nodes::A, IntegerType::Type{I}=number_type(boundary_nodes)) where {A,I} -> Dict`

Given a set of `boundary_nodes`

, returns a `Dict`

that maps ghost vertices to their associated section in `boundary_nodes`

. There are three cases:

`has_multiple_curves(boundary_nodes)`

Returns `dict::Dict{I, NTuple{2, I}}`

, mapping ghost vertices `i`

to `Tuple`

s `(m, n)`

so that `get_boundary_nodes(boundary_nodes, m, n)`

are the boundary nodes associated with `i`

, i.e. the `n`

th section of the `m`

th curve is associated with the ghost vertex `i`

.

`has_multiple_sections(boundary_nodes)`

Returns `dict::Dict{I, I}`

, mapping ghost vertices `i`

to `n`

so that `get_boundary_nodes(boundary_nodes, n)`

are the boundary nodes associated with `i`

, i.e. the `n`

th section of the boundary is associated with the ghost vertex `i`

.

`otherwise`

Returns `dict::Dict{I, A}`

, mapping the ghost vertex `i`

to `boundary_nodes`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> gv_map = DelaunayTriangulation.construct_ghost_vertex_map([1, 2, 3, 4, 5, 1])
Dict{Int64, Vector{Int64}} with 1 entry:
-1 => [1, 2, 3, 4, 5, 1]
julia> gv_map = DelaunayTriangulation.construct_ghost_vertex_map([[17, 29, 23, 5, 2, 1], [1, 50, 51, 52], [52, 1]])
Dict{Int64, Int64} with 3 entries:
-1 => 1
-3 => 3
-2 => 2
julia> gv_map = DelaunayTriangulation.construct_ghost_vertex_map([[[1, 5, 17, 18, 1]], [[23, 29, 31, 33], [33, 107, 101], [101, 99, 85, 23]]])
Dict{Int64, Tuple{Int64, Int64}} with 4 entries:
-1 => (1, 1)
-3 => (2, 2)
-2 => (2, 1)
-4 => (2, 3)
```

**Extended help**

This map can be useful for iterating over all boundary nodes. For example, you can iterate over all sections of a boundary using:

```
gv_map = construct_ghost_vertex_map(boundary_nodes)
for (ghost_vertex, section) in gv_map
nodes = get_boundary_nodes(boundary_nodes, section)
# do something with nodes
end
```

This works for any form of `boundary_nodes`

.

`DelaunayTriangulation.construct_ghost_vertex_ranges`

— Method`construct_ghost_vertex_ranges(boundary_nodes::A, IntegerType::Type{I}=number_type(boundary_nodes)) where {A,I} -> Dict`

Given a set of `boundary_nodes`

, returns a `Dict`

that maps ghost vertices to the range of all ghost vertices that the corresponding boundary curve could correspond to.

**Examples**

```
julia> using DelaunayTriangulation
julia> boundary_nodes = [
[
[1, 2, 3, 4], [4, 5, 6, 1]
],
[
[18, 19, 20, 25, 26, 30]
],
[
[50, 51, 52, 53, 54, 55], [55, 56, 57, 58], [58, 101, 103, 105, 107, 120], [120, 121, 122, 50]
]
]
3-element Vector{Vector{Vector{Int64}}}:
[[1, 2, 3, 4], [4, 5, 6, 1]]
[[18, 19, 20, 25, 26, 30]]
[[50, 51, 52, 53, 54, 55], [55, 56, 57, 58], [58, 101, 103, 105, 107, 120], [120, 121, 122, 50]]
julia> DelaunayTriangulation.construct_ghost_vertex_ranges(boundary_nodes)
Dict{Int64, UnitRange{Int64}} with 7 entries:
-5 => -7:-4
-1 => -2:-1
-7 => -7:-4
-3 => -3:-3
-2 => -2:-1
-4 => -7:-4
-6 => -7:-4
```

`DelaunayTriangulation.construct_parent_map!`

— Method`construct_parent_map!(enricher::BoundaryEnricher)`

Constructs the parent map for `enricher`

, modifying the parent map field in-place.

`DelaunayTriangulation.construct_polygon_hierarchy`

— Method`construct_polygon_hierarchy(points, boundary_nodes, boundary_curves; IntegerType=Int, n=4096) -> PolygonHierarchy{IntegerType}`

Returns a `PolygonHierarchy`

defining the polygon hierarchy for a given set of `boundary_nodes`

that define a curve-bounded domain from the curves in `boundary_curves`

. Uses `polygonise`

to fill in the boundary curves.

**Arguments**

`points`

: The point set.`boundary_nodes`

: The boundary nodes. These should be the output from`convert_boundary_curves!`

.`boundary_curves`

: The boundary curves. These should be the output from`convert_boundary_curves!`

.

**Keyword Arguments**

`IntegerType=Int`

: The integer type to use for indexing the polygons.`n=4096`

: The number of points to use for filling in the boundary curves in`polygonise`

.

`DelaunayTriangulation.construct_polygon_hierarchy`

— Method`construct_polygon_hierarchy(points, boundary_nodes; IntegerType=Int) -> PolygonHierarchy{IntegerType}`

Returns a `PolygonHierarchy`

defining the polygon hierarchy for a given set of `boundary_nodes`

that define a set of piecewise linear curves.

`DelaunayTriangulation.construct_polygon_hierarchy`

— Method`construct_polygon_hierarchy(points; IntegerType=Int) -> PolygonHierarchy{IntegerType}`

Returns a `PolygonHierarchy`

defining the polygon hierarchy for a given set of `points`

. This defines a hierarchy with a single polygon.

`DelaunayTriangulation.construct_positively_oriented_triangle`

— Method`construct_triangle(tri::Triangulation, i, j, k) -> Triangle`

Returns a triangle in `tri`

from the vertices `i`

, `j`

, and `k`

such that the triangle is positively oriented.

`DelaunayTriangulation.construct_positively_oriented_triangle`

— Method`construct_positively_oriented_triangle(::Type{V}, i, j, k, points) where {V} -> V`

Construct a triangle of type `V`

from vertices `i`

, `j`

, and `k`

such that the triangle is positively oriented, using `points`

for the coordinates.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0)];
julia> DelaunayTriangulation.construct_positively_oriented_triangle(NTuple{3, Int}, 1, 2, 3, points)
(2, 1, 3)
julia> DelaunayTriangulation.construct_positively_oriented_triangle(NTuple{3, Int}, 2, 3, 1, points)
(3, 2, 1)
julia> DelaunayTriangulation.construct_positively_oriented_triangle(NTuple{3, Int}, 2, 1, 3, points)
(2, 1, 3)
julia> DelaunayTriangulation.construct_positively_oriented_triangle(NTuple{3, Int}, 3, 2, 1, points)
(3, 2, 1)
julia> points = [(1.0, 1.0), (2.5, 2.3), (17.5, 23.0), (50.3, 0.0), (-1.0, 2.0), (0.0, 0.0), (5.0, 13.33)];
julia> DelaunayTriangulation.construct_positively_oriented_triangle(Vector{Int}, 5, 3, 2, points)
3-element Vector{Int64}:
3
5
2
julia> DelaunayTriangulation.construct_positively_oriented_triangle(Vector{Int}, 7, 1, 2, points)
3-element Vector{Int64}:
7
1
2
julia> DelaunayTriangulation.construct_positively_oriented_triangle(Vector{Int}, 7, 2, 1, points)
3-element Vector{Int64}:
2
7
1
julia> DelaunayTriangulation.construct_positively_oriented_triangle(Vector{Int}, 5, 4, 3, points)
3-element Vector{Int64}:
5
4
3
```

`DelaunayTriangulation.construct_segment_map`

— Method`construct_segment_map(segments, points, IntegerType) -> Dict{IntegerType, Vector{IntegerType}}`

Returns the segment map of `segments`

. This is a map that maps a vertex to all vertices that share a segment with that vertex. Segments are stored twice. The vertices associated with a vertex are sorted counter-clockwise, using the `points`

argument to define the coordinates.

`DelaunayTriangulation.construct_tree!`

— Method`construct_tree!(enricher::BoundaryEnricher)`

Constructs the spatial tree for `enricher`

, modifying the spatial tree field in-place. The parent map must be correctly configured in order for this to be valid.

`DelaunayTriangulation.construct_triangle`

— Function`construct_triangle(::Type{T}, i, j, k) where {T} -> Triangle`

Construct a triangle of type `T`

from vertices `i`

, `j`

, and `k`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.construct_triangle(NTuple{3,Int}, 1, 2, 3)
(1, 2, 3)
julia> DelaunayTriangulation.construct_triangle(Vector{Int32}, 1, 2, 3)
3-element Vector{Int32}:
1
2
3
```

`DelaunayTriangulation.contains_boundary_edge`

— Method```
contains_boundary_edge(tri::Triangulation, ij) -> Bool
contains_boundary_edge(tri::Triangulation, i, j) -> Bool
```

Returns `true`

if the boundary edge `(i, j)`

is in `tri`

, and `false`

otherwise. Orientation matters here.

`DelaunayTriangulation.contains_edge`

— Function```
contains_edge(i, j, E) -> Bool
contains_edge(e, E) -> Bool
```

Check if `E`

contains the edge `e = (i, j)`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> E = Set(((1,3),(17,3),(1,-1)))
Set{Tuple{Int64, Int64}} with 3 elements:
(1, -1)
(17, 3)
(1, 3)
julia> DelaunayTriangulation.contains_edge((1, 2), E)
false
julia> DelaunayTriangulation.contains_edge((17, 3), E)
true
julia> DelaunayTriangulation.contains_edge(3, 17, E) # order
false
julia> E = [[1,2],[5,13],[-1,1]]
3-element Vector{Vector{Int64}}:
[1, 2]
[5, 13]
[-1, 1]
julia> DelaunayTriangulation.contains_edge(1, 2, E)
true
```

`DelaunayTriangulation.contains_segment`

— Method```
contains_segment(tri::Triangulation, ij) -> Bool
contains_segment(tri::Triangulation, i, j) -> Bool
```

Returns `true`

if `(i, j)`

is a segment in `tri`

, and `false`

otherwise. Both `(i, j)`

and `(j, i)`

are checked.

`DelaunayTriangulation.contains_triangle`

— Function`contains_triangle(T, V) -> (Triangle, Bool)`

Check if the collection of triangles `V`

contains the triangle `T`

up to rotation. The `Triangle`

returned is the triangle in `V`

that is equal to `T`

up to rotation, or `T`

if no such triangle exists. The `Bool`

is `true`

if `V`

contains `T`

, and `false`

otherwise.

**Examples**

```
julia> using DelaunayTriangulation
julia> V = Set(((1, 2, 3), (4, 5, 6), (7, 8, 9)))
Set{Tuple{Int64, Int64, Int64}} with 3 elements:
(7, 8, 9)
(4, 5, 6)
(1, 2, 3)
julia> DelaunayTriangulation.contains_triangle((1, 2, 3), V)
((1, 2, 3), true)
julia> DelaunayTriangulation.contains_triangle((2, 3, 1), V)
((1, 2, 3), true)
julia> DelaunayTriangulation.contains_triangle((10, 18, 9), V)
((10, 18, 9), false)
julia> DelaunayTriangulation.contains_triangle(9, 7, 8, V)
((7, 8, 9), true)
```

`DelaunayTriangulation.contains_triangle`

— Method```
contains_triangle(tri::Triangulation, T) -> (Triangle, Bool)
contains_triangle(tri::Triangulation, i, j, k) -> (Triangle, Bool)
```

Tests whether `tri`

contains `T = (i, j, k)`

up to rotation, returning

`V`

: The rotated form of`T`

that is in`tri`

, or simply`T`

if`T`

is not in`tri`

.`flag`

:`true`

if`T`

is in`tri`

, and`false`

otherwise.

`DelaunayTriangulation.contains_unoriented_edge`

— Method`contains_unoriented_edge(e, E) -> Bool`

Check if `E`

contains the unoriented edge `e`

, i.e. check if `E`

contains the edge `e`

or `reverse_edge(e)`

.

`DelaunayTriangulation.convert_boundary_curves!`

— Method`convert_boundary_curves!(points, boundary_nodes, IntegerType) -> (NTuple{N, AbstractParametricCurve} where N, Vector)`

Converts the provided `points`

and `boundary_nodes`

into a set of boundary curves and modified boundary nodes suitable for triangulation. In particular:

- The function gets
`boundary_curves`

from`to_boundary_curves`

. `boundary_nodes`

is replaced with a set of initial boundary nodes (from`get_skeleton`

). These nodes come from evaluating each boundary curve at`t = 0`

and`t = 1`

. In the case of a piecewise linear boundary, the vertices are copied directly. Note that not all control points of a`CatmullRomSpline`

(which`is_interpolating`

) will be added - only those at`t = 0`

and`t = 1`

.- The
`points`

are modified to include the new boundary nodes. If a point is already in`points`

, it is not added again.

**Arguments**

`points`

: The point set. This is modified in place with the new boundary points.`boundary_nodes`

: The boundary nodes to be converted. This is not modified in place.`IntegerType`

: The type of integer to use for the boundary nodes.

**Output**

`boundary_curves`

: The boundary curves associated with`boundary_nodes`

.`boundary_nodes`

: The modified boundary nodes.

`DelaunayTriangulation.convert_boundary_points_to_indices`

— Function```
convert_boundary_points_to_indices(x, y; existing_points = NTuple{2, Float64}[], check_args=true) -> (Vector, Vector)
convert_boundary_points_to_indices(xy; existing_points = NTuple{2, Float64}[], check_args=true) -> (Vector, Vector)
```

Converts a boundary represented by `(x, y)`

or `xy`

, where the points are combined rather than as separate sets of coordinates, into a set of boundary nodes for use in `triangulate`

.

**Arguments**

`x`

,`y`

: The`x`

and`y`

-coordinates for the boundary points. The individual vectors must match the specification required for boundaries outlined in the documentation.`xy`

: As above, except the coordinates are combined rather than given as separate vectors.

**Keyword Arguments**

`existing_points`

: The existing points to append the boundary points to. This is useful if you have a pre-existing set of points.`check_args`

: Whether to check that the arguments match the specification in the documentation.

**Outputs**

`boundary_nodes`

: The boundary nodes.`points`

: The point set, which is the same as`existing_points`

but with the boundary points appended to it.

`DelaunayTriangulation.convert_certificate`

— Method`convert_certificate(cert::I, Cert1, Cert2, Cert3) -> Certificate`

Given `cert ∈ (-1, 0, 1)`

, return `Cert1`

, `Cert2`

or `Cert3`

depending on if `cert == -1`

, `cert == 0`

or `cert == 1`

, respectively.

`DelaunayTriangulation.convert_lookup_idx`

— Method`convert_lookup_idx(b::AbstractParametricCurve, i) -> Float64`

Converts the index `i`

of the lookup table of the curve `b`

to the corresponding `t`

-value.

`DelaunayTriangulation.convert_to_edge_adjoining_ghost_vertex`

— Method`convert_to_edge_adjoining_ghost_vertex(tri::Triangulation, e) -> Edge`

Returns the edge `e`

if it is not a boundary edge, and the edge `reverse(e)`

if it is a boundary edge.

See also `is_boundary_edge`

.

`DelaunayTriangulation.convert_to_edge_adjoining_ghost_vertex`

— Method`convert_to_edge_adjoining_ghost_vertex(vorn::VoronoiTessellation, e) -> Edge`

Returns the edge `e`

if it is not a boundary edge, and the edge `reverse(e)`

if it is a boundary edge.

See also `is_boundary_edge`

.

`DelaunayTriangulation.convex_hull!`

— Method`convex_hull!(tri::Triangulation; reconstruct=has_boundary_nodes(tri))`

Updates the `convex_hull`

field of `tri`

to match the current triangulation.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.

**Keyword Arguments**

`reconstruct=has_boundary_nodes(tri)`

: If`true`

, then the convex hull is reconstructed from scratch, using`convex_hull`

on the points. Otherwise, computes the convex hull using the ghost triangles of`tri`

. If there are no ghost triangles but`reconstruct=true`

, then the convex hull is reconstructed from scratch.

`DelaunayTriangulation.convex_hull!`

— Method`convex_hull!(ch::ConvexHull{P,I}) where {P,I}`

Using the points in `ch`

, computes the convex hull in-place.

See also `convex_hull`

.

`DelaunayTriangulation.convex_hull`

— Method`convex_hull(points; IntegerType::Type{I}=Int) where {I} -> ConvexHull`

Computes the convex hull of `points`

. The monotone chain algorithm is used.

**Arguments**

`points`

: The set of points.

**Output**

`ch`

: The`ConvexHull`

.

`DelaunayTriangulation.curvature`

— Method`curvature(c::AbstractParametricCurve, t) -> Float64`

Returns the curvature of the [`AbstractParametricCurve`

] `c`

at `t`

.

`DelaunayTriangulation.decrement_num_elements!`

— Method`decrement_num_elements!(tree::RTree)`

Decrements the number of elements in `tree`

by 1.

`DelaunayTriangulation.default_displacement_tolerance`

— Method`default_displacement_tolerance(vorn::VoronoiTessellation) -> Number`

Returns the default displacement tolerance for the centroidal smoothing algorithm. The default is given by `max_extent / 1e4`

, where `max_extent = max(width, height)`

, where `width`

and `height`

are the width and height of the bounding box of the underlying point set.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.

**Outputs**

`tol`

: The default displacement tolerance.

`DelaunayTriangulation.default_num_samples`

— Method`default_num_samples(n) -> Integer`

Given a number of points `n`

, returns `∛n`

rounded up to the nearest integer. This is the default number of samples used in the jump-and-march algorithm.

`DelaunayTriangulation.delete_adjacent!`

— Method```
delete_adjacent!(adj::Adjacent, uv)
delete_adjacent!(adj::Adjacent, u, v)
```

Deletes the edge `uv`

from `adj`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj = DelaunayTriangulation.Adjacent(Dict((2, 7) => 6, (7, 6) => 2, (6, 2) => 2, (17, 3) => -1, (-1, 5) => 17, (5, 17) => -1));
julia> DelaunayTriangulation.delete_adjacent!(adj, 2, 7)
Adjacent{Int64, Tuple{Int64, Int64}}, with map:
Dict{Tuple{Int64, Int64}, Int64} with 5 entries:
(-1, 5) => 17
(17, 3) => -1
(6, 2) => 2
(5, 17) => -1
(7, 6) => 2
julia> DelaunayTriangulation.delete_adjacent!(adj, (6, 2))
Adjacent{Int64, Tuple{Int64, Int64}}, with map:
Dict{Tuple{Int64, Int64}, Int64} with 4 entries:
(-1, 5) => 17
(17, 3) => -1
(5, 17) => -1
(7, 6) => 2
julia> DelaunayTriangulation.delete_adjacent!(adj, 5, 17)
Adjacent{Int64, Tuple{Int64, Int64}}, with map:
Dict{Tuple{Int64, Int64}, Int64} with 3 entries:
(-1, 5) => 17
(17, 3) => -1
(7, 6) => 2
```

`DelaunayTriangulation.delete_adjacent!`

— Method```
delete_adjacent!(tri::Triangulation, uv)
delete_adjacent!(tri::Triangulation, u, v)
```

Deletes the key `(u, v)`

from the adjacency map of `tri`

.

`DelaunayTriangulation.delete_adjacent!`

— Method```
delete_adjacent!(vor::VoronoiTessellation, ij)
delete_adjacent!(vor::VoronoiTessellation, i, j)
```

Deletes the edge `(i, j)`

from the adjacency map of `vor`

.

`DelaunayTriangulation.delete_adjacent2vertex!`

— Method```
delete_adjacent2vertex!(adj2v::Adjacent2Vertex, w, uv)
delete_adjacent2vertex!(adj2v::Adjacent2Vertex, w, u, v)
```

Deletes the edge `uv`

from the set of edges `E`

such that `(u, v, w)`

is a positively oriented triangle in the underlying triangulation for each `(u, v) ∈ E`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj2v = DelaunayTriangulation.Adjacent2Vertex(Dict(1 => Set(((2, 3), (5, 7), (8, 9))), 5 => Set(((1, 2), (7, 9), (8, 3)))))
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 2 entries:
5 => Set([(1, 2), (8, 3), (7, 9)])
1 => Set([(8, 9), (5, 7), (2, 3)])
julia> DelaunayTriangulation.delete_adjacent2vertex!(adj2v, 5, 8, 3)
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 2 entries:
5 => Set([(1, 2), (7, 9)])
1 => Set([(8, 9), (5, 7), (2, 3)])
julia> DelaunayTriangulation.delete_adjacent2vertex!(adj2v, 1, (2, 3))
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 2 entries:
5 => Set([(1, 2), (7, 9)])
1 => Set([(8, 9), (5, 7)])
```

`DelaunayTriangulation.delete_adjacent2vertex!`

— Method`delete_adjacent2vertex!(adj2v::Adjacent2Vertex, w)`

Deletes the vertex `w`

from `adj2v`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj2v = DelaunayTriangulation.Adjacent2Vertex(Dict(1 => Set(((2, 3), (5, 7))), 5 => Set(((-1, 2), (2, 3)))))
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 2 entries:
5 => Set([(-1, 2), (2, 3)])
1 => Set([(5, 7), (2, 3)])
julia> DelaunayTriangulation.delete_adjacent2vertex!(adj2v, 1)
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 1 entry:
5 => Set([(-1, 2), (2, 3)])
julia> DelaunayTriangulation.delete_adjacent2vertex!(adj2v, 5)
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}}()
```

`DelaunayTriangulation.delete_adjacent2vertex!`

— Method```
delete_adjacent2vertex!(tri::Triangulation, w, uv)
delete_adjacent2vertex!(tri::Triangulation, w, u, v)
```

Deletes the edge `(u, v)`

from the set of edges returned by `get_adjacent2vertex(tri, w)`

.

`DelaunayTriangulation.delete_adjacent2vertex!`

— Method`delete_adjacent2vertex!(tri::Triangulation, w)`

Deletes the key `w`

from the `Adjacent2Vertex`

map of `tri`

.

`DelaunayTriangulation.delete_all_exterior_triangles!`

— Method`delete_all_exterior_triangles!(tri::Triangulation, triangles)`

Deletes all the triangles in the set `triangles`

from the triangulation `tri`

.

`DelaunayTriangulation.delete_boundary_node!`

— Method`delete_boundary_node!(boundary_nodes, pos)`

Deletes the boundary node at the position `pos`

from `boundary_nodes`

. Here, `pos[1]`

is such that `get_boundary_nodes(boundary_nodes, pos[1])`

is the section that the node will be deleted from, and `pos[2]`

gives the position of the array to delete from. In particular,

`delete_boundary_node!(boundary_nodes, pos)`

is the same as

`deleteat!(get_boundary_nodes(boundary_nodes, pos[1]), pos[2])`

**Examples**

```
julia> using DelaunayTriangulation
julia> boundary_nodes = [71, 25, 33, 44, 55, 10];
julia> DelaunayTriangulation.delete_boundary_node!(boundary_nodes, (boundary_nodes, 4))
5-element Vector{Int64}:
71
25
33
55
10
julia> boundary_nodes = [[7, 13, 9, 25], [25, 26, 29, 7]];
julia> DelaunayTriangulation.delete_boundary_node!(boundary_nodes, (2, 3))
2-element Vector{Vector{Int64}}:
[7, 13, 9, 25]
[25, 26, 7]
julia> boundary_nodes = [[[17, 23, 18, 25], [25, 26, 81, 91], [91, 101, 17]], [[1, 5, 9, 13], [13, 15, 1]]];
julia> DelaunayTriangulation.delete_boundary_node!(boundary_nodes, ((2, 2), 2))
2-element Vector{Vector{Vector{Int64}}}:
[[17, 23, 18, 25], [25, 26, 81, 91], [91, 101, 17]]
[[1, 5, 9, 13], [13, 1]]
```

`DelaunayTriangulation.delete_boundary_node!`

— Method`delete_boundary_node!(tri::Triangulation, pos)`

Deletes the boundary node at the specified position `pos`

in `tri`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`pos`

: The position to delete the node at, given as a`Tuple`

so that`delete_boundary_node!(tri, pos)`

is the same as`deleteat!(get_boundary_nodes(tri, pos[1]), pos[2])`

.

**Outputs**

There are no outputs, but the boundary nodes of `tri`

are updated in-place.

`DelaunayTriangulation.delete_child!`

— Method`delete_child!(tree::PolygonTree, child::PolygonTree)`

Deletes `child`

from `tree`

.

`DelaunayTriangulation.delete_edge!`

— Method`delete_edge!(E, e...)`

Delete the edges `e...`

from `E`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> E = Set(([1,2],[10,15],[1,-1],[13,23],[1,5]))
Set{Vector{Int64}} with 5 elements:
[10, 15]
[1, 5]
[1, 2]
[1, -1]
[13, 23]
julia> DelaunayTriangulation.delete_edge!(E, [10,15])
julia> E
Set{Vector{Int64}} with 4 elements:
[1, 5]
[1, 2]
[1, -1]
[13, 23]
julia> DelaunayTriangulation.delete_edge!(E, [1,5], [1, -1])
julia> E
Set{Vector{Int64}} with 2 elements:
[1, 2]
[13, 23]
```

`DelaunayTriangulation.delete_edge!`

— Method`delete_edge!(boundary_enricher::BoundaryEnricher, i, j)`

Deletes the edge `(i, j)`

in `boundary_enricher`

.

`DelaunayTriangulation.delete_edge!`

— Method`delete_edge!(events::InsertionEventHistory, e)`

Add the edge `e`

to the `deleted_segments`

of `events`

.

`DelaunayTriangulation.delete_edge!`

— Method`delete_edge!(G::Graph, u, v)`

Deletes the edge `(u, v)`

from `G`

.

`DelaunayTriangulation.delete_free_vertices_around_subsegment!`

— Method`delete_free_vertices_around_subsegment!(tri::Triangulation, args::RefinementArguments, e)`

Deletes all free vertices (i.e., Steiner points) contained in the diametral circle of `e`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`args::RefinementArguments`

: The`RefinementArguments`

.`e`

: The segment.

**Output**

The free vertices are deleted from `tri`

in-place.

`DelaunayTriangulation.delete_from_edges!`

— Method`delete_from_edges!(E, e)`

Delete the edge `e`

from `E`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> E = Set(([1,2],[5,15],[17,10],[5,-1]))
Set{Vector{Int64}} with 4 elements:
[17, 10]
[5, 15]
[5, -1]
[1, 2]
julia> DelaunayTriangulation.delete_from_edges!(E, [5, 15])
Set{Vector{Int64}} with 3 elements:
[17, 10]
[5, -1]
[1, 2]
```

`DelaunayTriangulation.delete_from_triangles!`

— Method`delete_from_triangles!(T, V)`

Delete the triangle `V`

from the collection of triangles `T`

. Only deletes `V`

if `V`

is in `T`

up to rotation.

**Examples**

```
julia> using DelaunayTriangulation
julia> V = Set(((1, 2, 3), (4, 5, 6), (7, 8, 9)))
Set{Tuple{Int64, Int64, Int64}} with 3 elements:
(7, 8, 9)
(4, 5, 6)
(1, 2, 3)
julia> DelaunayTriangulation.delete_from_triangles!(V, (4, 5, 6))
Set{Tuple{Int64, Int64, Int64}} with 2 elements:
(7, 8, 9)
(1, 2, 3)
julia> DelaunayTriangulation.delete_from_triangles!(V, (9, 7, 8))
Set{Tuple{Int64, Int64, Int64}} with 1 element:
(1, 2, 3)
```

`DelaunayTriangulation.delete_ghost_triangles!`

— Method`delete_ghost_triangles!(tri::Triangulation)`

Deletes all the ghost triangles from `tri`

.

Ghost vertices are still used in the `keys`

of the `Adjacent2Vertex`

of `tri`

, and are still present in the `Graph`

. If you want to delete the ghost vertex `keys`

from the `Adjacent2Vertex`

, you need to use `delete_adjacent2vertex!`

. For deleting the ghost vertices from the `Graph`

, you need `delete_ghost_vertices_from_graph!`

. Additionally, edges in `Adjacent`

can still map to ghost vertices. If you also want to delete those, you need to filter through the `values`

of the `Adjacent`

map that are ghost vertices, and use `delete_adjacent!`

.

`DelaunayTriangulation.delete_ghost_vertices_from_graph!`

— Method`delete_ghost_vertices_from_graph!(tri::Triangulation)`

Deletes all ghost vertices from the graph of `tri`

.

`DelaunayTriangulation.delete_ghost_vertices_from_graph!`

— Method`delete_ghost_vertices!(G::Graph)`

Deletes all ghost vertices from `G`

.

`DelaunayTriangulation.delete_holes!`

— Method`delete_holes!(tri::Triangulation)`

Deletes all the exterior faces to the boundary nodes specified in the triangulation `tri`

.

**Extended help**

This function works in several stages:

- First,
`find_all_points_to_delete`

is used to identify all points in the exterior faces. - Once all the points to delete have been found, all the associated triangles are found using
`find_all_triangles_to_delete`

, taking care for any incorrectly identified triangles and points. - Once the correct set of triangles to delete has been found, they are deleted using
`delete_all_exterior_triangles!`

.

`DelaunayTriangulation.delete_intersected_triangles!`

— Method`delete_intersected_triangles!(tri, triangles)`

Deletes the triangles in `triangles`

from `tri`

.

`DelaunayTriangulation.delete_neighbour!`

— Method`delete_neighbour!(tri::Triangulation, u, v...)`

Deletes the neighbours `v...`

from `u`

in the graph of `tri`

.

`DelaunayTriangulation.delete_neighbour!`

— Method`delete_neighbour!(G::Graph, u, v...)`

Deletes the neighbours `v...`

from `u`

in `G`

.

`DelaunayTriangulation.delete_node!`

— Method`delete_node!(node::Union{Nothing,BalancedBSTNode{K}}, key::K) -> Union{Nothing,BalancedBSTNode{K}}`

Deletes the node with key `key`

from the subtree rooted at `node`

if it exists. Returns the new root of the subtree.

`DelaunayTriangulation.delete_point!`

— Method`delete_point!(c::RepresentativeCoordinates, p)`

Treating `c`

as an arithmetic average, updates the coordinates of `c`

to exclude `p`

.

`DelaunayTriangulation.delete_point!`

— Method`delete_point!(tri::Triangulation, vertex; kwargs...)`

Deletes the `vertex`

of `tri`

, retriangulating the cavity formed by the surrounding polygon of `vertex`

using `triangulate_convex`

.

It is not possible to delete vertices that are on the boundary, are ghost vertices, or adjoin a segment of `tri`

. See also `check_delete_point_args`

.

This function will not actually delete the corresponding coordinates from `get_points(tri)`

, nor will it remove the associated weight from `get_weights(tri)`

.

**Arguments**

`tri::Triangulation`

:`Triangulation`

.`vertex`

: The vertex to delete.

**Keyword Arguments**

`store_event_history=Val(false)`

: Whether to store the event history of the triangulation from deleting the point.`event_history=nothing`

: The event history of the triangulation from deleting the point. Only updated if`store_event_history`

is true, in which case it needs to be an`InsertionEventHistory`

object.`rng::AbstractRNG=Random.default_rng()`

: The random number generator to use for the triangulation.

`DelaunayTriangulation.delete_polygon_adjacent!`

— Method`delete_polygon!(vor::VoronoiTessellation, polygon)`

Deletes the adjacent polygons of the boundary edges of the polygon `polygon`

from the adjacency list.

`DelaunayTriangulation.delete_polygon_vertices_in_random_order!`

— Method`delete_polygon_vertices_in_random_order!(list::ShuffledPolygonLinkedList, tri::Triangulation, u, v, rng::AbstractRNG)`

Deletes vertices from the polygon defined by `list`

in a random order.

**Arguments**

`list::ShuffledPolygonLinkedList`

: The linked list of polygon vertices.`tri::Triangulation`

: The`Triangulation`

.`u`

,`v`

: The vertices of the segment`(u, v)`

that was inserted in order to define the polygon`V = list.S`

.`rng::AbstractRNG`

: The random number generator to use.

**Outputs**

There is no output, but `list`

is updated in-place.

`DelaunayTriangulation.delete_tree!`

— Method`delete_tree!(hierarchy::PolygonHierarchy, index)`

Deletes the `PolygonTree`

of the `index`

th polygon in `hierarchy`

. The `index`

must be associated with an exterior polygon.

`DelaunayTriangulation.delete_triangle!`

— Function```
delete_triangle!(V, T...)
delete_triangle!(V, i, j, k)
```

Delete the triangles `T...`

from the collection of triangles `V`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> V = Set(((1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, 15)))
Set{Tuple{Int64, Int64, Int64}} with 5 elements:
(7, 8, 9)
(10, 11, 12)
(4, 5, 6)
(13, 14, 15)
(1, 2, 3)
julia> delete_triangle!(V, (6, 4, 5))
Set{Tuple{Int64, Int64, Int64}} with 4 elements:
(7, 8, 9)
(10, 11, 12)
(13, 14, 15)
(1, 2, 3)
julia> delete_triangle!(V, (10, 11, 12), (1, 2, 3))
Set{Tuple{Int64, Int64, Int64}} with 2 elements:
(7, 8, 9)
(13, 14, 15)
julia> delete_triangle!(V, 8, 9, 7)
Set{Tuple{Int64, Int64, Int64}} with 1 element:
(13, 14, 15)
```

`DelaunayTriangulation.delete_triangle!`

— Method```
delete_triangle!(adj::Adjacent, u, v, w)
delete_triangle!(adj::Adjacent, T)
```

Deletes the adjacency relationships defined from the triangle `T = (u, v, w)`

from `adj`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj = DelaunayTriangulation.Adjacent{Int32, NTuple{2, Int32}}();
julia> add_triangle!(adj, 1, 6, 7);
julia> add_triangle!(adj, 17, 3, 5);
julia> adj
Adjacent{Int32, Tuple{Int32, Int32}}, with map:
Dict{Tuple{Int32, Int32}, Int32} with 6 entries:
(17, 3) => 5
(1, 6) => 7
(6, 7) => 1
(7, 1) => 6
(5, 17) => 3
(3, 5) => 17
julia> delete_triangle!(adj, 3, 5, 17)
Adjacent{Int32, Tuple{Int32, Int32}}, with map:
Dict{Tuple{Int32, Int32}, Int32} with 3 entries:
(1, 6) => 7
(6, 7) => 1
(7, 1) => 6
julia> delete_triangle!(adj, 7, 1, 6)
Adjacent{Int32, Tuple{Int32, Int32}}, with map:
Dict{Tuple{Int32, Int32}, Int32}()
```

`DelaunayTriangulation.delete_triangle!`

— Method```
delete_triangle!(adj2v::Adjacent2Vertex, u, v, w)
delete_triangle!(adj2v::Adjacent2Vertex, T)
```

Deletes the relationships defined by the triangle `T =(u, v, w)`

from `adj2v`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj2v = DelaunayTriangulation.Adjacent2Vertex{Int32, Set{NTuple{2, Int32}}}()
Adjacent2Vertex{Int32, Set{Tuple{Int32, Int32}}} with map:
Dict{Int32, Set{Tuple{Int32, Int32}}}()
julia> add_triangle!(adj2v, 1, 2, 3)
Adjacent2Vertex{Int32, Set{Tuple{Int32, Int32}}} with map:
Dict{Int32, Set{Tuple{Int32, Int32}}} with 3 entries:
2 => Set([(3, 1)])
3 => Set([(1, 2)])
1 => Set([(2, 3)])
julia> add_triangle!(adj2v, 17, 5, 2)
Adjacent2Vertex{Int32, Set{Tuple{Int32, Int32}}} with map:
Dict{Int32, Set{Tuple{Int32, Int32}}} with 5 entries:
5 => Set([(2, 17)])
2 => Set([(3, 1), (17, 5)])
17 => Set([(5, 2)])
3 => Set([(1, 2)])
1 => Set([(2, 3)])
julia> delete_triangle!(adj2v, 5, 2, 17)
Adjacent2Vertex{Int32, Set{Tuple{Int32, Int32}}} with map:
Dict{Int32, Set{Tuple{Int32, Int32}}} with 5 entries:
5 => Set()
2 => Set([(3, 1)])
17 => Set()
3 => Set([(1, 2)])
1 => Set([(2, 3)])
julia> delete_triangle!(adj2v, 2, 3, 1)
Adjacent2Vertex{Int32, Set{Tuple{Int32, Int32}}} with map:
Dict{Int32, Set{Tuple{Int32, Int32}}} with 5 entries:
5 => Set()
2 => Set()
17 => Set()
3 => Set()
1 => Set()
```

`DelaunayTriangulation.delete_triangle!`

— Method```
delete_triangle!(G::Graph, u, v, w)
delete_triangle!(G::Graph, T)
```

Deletes the neighbourhood relationships defined by the triangle `T = (u, v, w)`

from the graph `G`

.

`DelaunayTriangulation.delete_triangle!`

— Method`delete_triangle!(events::InsertionEventHistory, T)`

Add the triangle `T`

to the `deleted_triangles`

of `events`

.

`DelaunayTriangulation.delete_triangle!`

— Method```
delete_triangle!(tri::Triangulation, u, v, w; protect_boundary=false, update_ghost_edges=false)
delete_triangle!(tri::Triangulation, T; protect_boundary=false, update_ghost_edges=false)
```

Deletes the triangle `T = (u, v, w)`

from `tri`

. This won't delete the points from `tri`

, it will just update the fields so that its non-existence in the triangulation is known.

**Arguments**

`tri::Triangulation`

: The triangulation to delete the triangle from.`u, v, w`

: The vertices of the triangle to delete.

**Keyword Arguments**

`protect_boundary=false`

: If`true`

, then the boundary edges will not be updated. Otherwise,`delete_boundary_edges_single!`

,`delete_boundary_edges_double!`

, or`delete_boundary_edges_triple!`

will be called depending on the number of boundary edges in the triangle.`update_ghost_edges=false`

: If`true`

, then the ghost edges will be updated. Otherwise, the ghost edges will not be updated. Will only be used if`protect_boundary=false`

.

**Outputs**

There are no outputs as `tri`

is updated in-place.

`DelaunayTriangulation.delete_unbounded_polygon!`

— Method`delete_unbounded_polygon!(vor::VoronoiTessellation, i)`

Deletes the index `i`

from the set of unbounded polygons of `vor`

.

`DelaunayTriangulation.delete_unoriented_edge!`

— Method`delete_unoriented_edge!(E, e)`

Delete the unoriented edge `e`

from `E`

, i.e. delete both the edge `e`

and `reverse_edge(e)`

.

`DelaunayTriangulation.delete_vertex!`

— Method`delete_vertex!(list::ShuffledPolygonLinkedList, i)`

Deletes the vertex `S[πᵢ]`

from the linked `list`

, where `πᵢ = list.shuffled_indices[i]`

. This deletion is done symbolically rather than by mutating the vectors in `list`

. In particular, we perform

`next[prev[πᵢ]] = next[πᵢ]`

`prev[next[πᵢ]] = prev[πᵢ]`

which is the same as removing `S[πᵢ]`

from the linked `list`

.

`DelaunayTriangulation.delete_vertex!`

— Method`delete_vertex!(tri::Triangulation, u...)`

Deletes the vertices `u...`

from the graph of `tri`

.

`DelaunayTriangulation.delete_vertex!`

— Method`delete_vertex!(G::Graph, u...)`

Deletes the vertices `u...`

from `G`

.

`DelaunayTriangulation.delete_vertices_in_random_order!`

— Method`delete_vertices_in_random_order!(list::Triangulation, tri::ShuffledPolygonLinkedList, rng)`

Deletes the vertices of the polygon represented by `list`

in random order, done by switching the pointers of the linked list. Only three vertices will survive. If these these three vertices are collinear, then the deletion is attempted again after reshuffling the vertices.

**Arguments**

`list::ShuffledPolygonLinkedList`

: The linked list representing the polygon to be deleted.`tri::Triangulation`

: The`Triangulation`

.`rng::AbstractRNG`

: The random number generator used to shuffle the vertices of`S`

.

**Outputs**

There is no output, as `list`

is modified in-place.

`DelaunayTriangulation.dequeue_and_process!`

— Method```
dequeue_and_process!(vorn, polygon_edge_queue, edges_to_process,
intersected_edge_cache, left_edge_intersectors, right_edge_intersectors, current_edge_intersectors,
processed_pairs, boundary_sites, segment_intersections, exterior_circumcenters, equal_circumcenter_mapping)
```

Dequeue an edge from `polygon_edge_queue`

and process it. If `polygon_edge_queue`

is empty, then we process the first edge in `edges_to_process`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`polygon_edge_queue`

: The queue of edges that need to be processed.`edges_to_process`

: The edges that need to be processed.`intersected_edge_cache`

: A cache of intersected edges.`left_edge_intersectors`

: The intersection points of`left_edge`

with other edges.`right_edge_intersectors`

: The intersection points of`right_edge`

with other edges.`current_edge_intersectors`

: The intersection points of`current_edge`

with other edges.`processed_pairs`

: A set of pairs of edges and polygons that have already been processed.`boundary_sites`

: A dictionary of boundary sites.`segment_intersections`

: A dictionary of segment intersections.`exterior_circumcenters`

: A dictionary of exterior circumcenters.`equal_circumcenter_mapping`

: A mapping from the indices of the segment intersections that are equal to the circumcenter of a site to the index of the site.

**Outputs**

There are no outputs. Instead, the caches and queues are updated in-place.

**Extended help**

This function works as follows:

- Firstly, if there are no edges queued in
`polygon_edge_queue`

, then we enqueue the first in edge in`edges_to_process`

using`enqueue_new_edge!`

. - We then dequeue the next edge to be processed. If the edge has already been processed, then we return early.
- If we're still here, then we process the
`(edge, polygon)`

pair enqueued from`polygon_edge_queue`

using`process_polygon!`

. This function checks for intersections of the`edge`

with the`polygon`

. - Once the polygon has been processed, we then needed to classify all of the intersections using
`classify_intersections!`

, which determines, for each intersection, if the intersection is with`edge`

, or with the edge left of`edge`

, or to the edge right of`edge`

. - Then,
`process_intersection_points!`

is used to process the intersection points, enqueueing new edges when needed. - We then delete the edge from
`edges_to_process`

if it is in there and return.

`DelaunayTriangulation.detach!`

— Method`detach!(node::AbstractNode, idx) -> Bool`

Detaches the `idx`

th child of `node`

. Returns `true`

if the `node`

's bounding box had to be adjusted and `false`

otherwise.

`DelaunayTriangulation.diametral_circle`

— Method`diametral_circle(p, q) -> (NTuple{2,Float64}, Float64)`

Returns the circle with diameter `pq`

.

`DelaunayTriangulation.differentiate`

— Function`differentiate(c::AbstractParametricCurve, t) -> NTuple{2, Float64}`

Evaluates the derivative of `c`

at `t`

.

`DelaunayTriangulation.dig_cavity!`

— Method`dig_cavity!(tri::Triangulation, r, i, j, ℓ, flag, V, store_event_history=Val(false), event_history=nothing, peek::F=Val(false)) where {F}`

Excavates the cavity in `tri`

through the edge `(i, j)`

, stepping towards the adjacent triangles to excavate the cavity recursively, eliminating all triangles containing `r`

in their circumcircle.

**Arguments**

`tri`

: The`Triangulation`

.`r`

: The new point being inserted.`i`

: The first vertex of the edge`(i, j)`

.`j`

: The second vertex of the edge`(i, j)`

.`ℓ`

: The vertex adjacent to`(j, i)`

, so that the triangle being stepped into is`(j, i, ℓ)`

.`flag`

: The position of`r`

relative to`V`

. See`point_position_relative_to_triangle`

.`V`

: The triangle in`tri`

containing`r`

.`store_event_history=Val(false)`

: If`true`

, then the event history from the insertion is stored.`event_history=nothing`

: The event history to store the event history in. Should be an`InsertionEventHistory`

if`store_event_history`

is`true`

, and`false`

otherwise.`peek=Val(false)`

: Whether to actually add`new_point`

into`tri`

, or just record into`event_history`

all the changes that would occur from its insertion.

**Output**

There are no changes, but `tri`

is updated in-place.

**Extended help**

This function works as follows:

- First, we check if
`ℓ`

is 0, which would imply that the triangle`(j, i, ℓ)`

doesn't exist as it has already been deleted. If this is the check, we return and stop digging. - If the edge
`(i, j)`

is not a segment,`r`

is inside of the circumcenter of`(j, i, ℓ)`

, and`ℓ`

is not a ghost vertex, then we can step forward into the next triangles. In particular, we delete the triangle`(j, i, ℓ)`

from`tri`

and then call`dig_cavity!`

again on two edges of`(j, i, ℓ)`

other than`(j, i)`

. - If we did not do step 2, then this means that we are on the edge of the polygonal cavity; this also covers the case that
`ℓ`

is a ghost vertex, i.e. we are at the boundary of the triangulation. There are two cases to consider here. Firstly, if`(i, j)`

is not a segment, we just need to add the triangle`(r, i, j)`

into`tri`

to connect`r`

to this edge of the polygonal cavity. If`(i, j)`

is a segment, then the situation is more complicated. In particular,`r`

being on an edge of`V`

might imply that we are going to add a degenerate triangle`(r, i, j)`

into`tri`

, and so this needs to be avoided. So, we check if`is_on(flag) && contains_segment(tri, i, j)`

and, if the edge that`r`

is on is`(i, j)`

, we add the triangle`(r, i, j)`

. Otherwise, we do nothing.

`DelaunayTriangulation.dist`

— Method`dist(p, q) -> Number`

Assuming `p`

and `q`

are two-dimensional, computes the Euclidean distance between `p`

and `q`

.

`DelaunayTriangulation.dist`

— Method`dist(tri::Triangulation, p) -> Number`

Given a point `p`

, returns the distance from `p`

to the triangulation, using the conventions from `distance_to_polygon`

:

`δ > 0`

: If the returned distance is positive, then`p`

is inside the triangulation.`δ < 0`

: If the returned distance is negative, then`p`

is outside the triangulation.`δ = 0`

: If the returned distance is zero, then`p`

is on the boundary of the triangulation.

Where we say distance, we are referring to the distance from `p`

to the boundary of the triangulation.

`DelaunayTriangulation.dist_sqr`

— Method`dist_sqr(p, q) -> Number`

Assuming `p`

and `q`

are two-dimensional, computes the square of the Euclidean distance between `p`

and `q`

.

`DelaunayTriangulation.distance_to_offcenter`

— Method`distance_to_offcenter(β, ℓ) -> Number`

Given a triangle with shortest edge length `ℓ`

, computes the distance from the edge to the offcenter of the triangle with radius-edge ratio cutoff `β`

.

`DelaunayTriangulation.distance_to_polygon`

— Method`distance_to_polygon(q, points, boundary_nodes) -> Number`

Given a query point `q`

and a polygon defined by `(points, boundary_nodes)`

, returns the signed distance from `q`

to the polygon. The `boundary_nodes`

must match the specification in the documentation and in `check_args`

.

See also `dist`

.

`DelaunayTriangulation.each_added_boundary_segment`

— Method`each_added_boundary_segment(events::InsertionEventHistory) -> Iterator`

Returns an iterator over the boundary segments that were added to the triangulation during the insertion of a point.

`DelaunayTriangulation.each_added_segment`

— Method`each_deleted_triangle(events::InsertionEventHistory) -> Iterator`

Returns an iterator over the triangles that were deleted from the triangulation during the insertion of a point.

`DelaunayTriangulation.each_added_triangle`

— Method`each_added_triangle(events::InsertionEventHistory) -> Iterator`

Returns an iterator over the triangles that were added to the triangulation during the insertion of a point.

`DelaunayTriangulation.each_boundary_edge`

— Method`each_boundary_edge(enricher::BoundaryEnricher) -> KeySet`

Returns the set of keys in the parent map of `enricher`

, i.e. each boundary edge in `enricher`

.

`DelaunayTriangulation.each_boundary_edge`

— Method`each_boundary_edge(tri::Triangulation) -> KeySet`

Returns an iterator over the boundary edges of `tri`

, in no specific order.

`DelaunayTriangulation.each_boundary_node`

— Method`each_boundary_node(boundary_nodes) -> Iterator`

Returns an iterator that goves over each node in `boundary_nodes`

. It is assumed that `boundary_nodes`

represents a single section or a single contiguous boundary; if you do want to loop over every boundary nodes for a boundary with multiple sections, you should to see the result from `construct_ghost_vertex_map`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.each_boundary_node([7, 8, 19, 2, 17])
5-element Vector{Int64}:
7
8
19
2
17
julia> DelaunayTriangulation.each_boundary_node([7, 8, 19, 2, 17, 7])
6-element Vector{Int64}:
7
8
19
2
17
7
```

`DelaunayTriangulation.each_edge`

— Function`each_edge(E) -> Iterator`

Get an iterator over the edges in `E`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> E = Set(((1,2),(1,3),(2,-1)))
Set{Tuple{Int64, Int64}} with 3 elements:
(1, 2)
(1, 3)
(2, -1)
julia> each_edge(E)
Set{Tuple{Int64, Int64}} with 3 elements:
(1, 2)
(1, 3)
(2, -1)
```

`DelaunayTriangulation.each_edge`

— Method`each_edge(tri::Triangulation) -> Edges`

Returns an iterator over all edges in `tri`

. Note that, if `has_ghost_triangles(tri)`

, then some of these edges will be ghost edges.

See also `each_solid_edge`

and `each_ghost_edge`

.

`DelaunayTriangulation.each_generator`

— Method`each_boundary_polygon(vorn::VoronoiTessellation) -> KeySet`

Returns an iterator over the boundary polygon indices of `vorn`

.

`DelaunayTriangulation.each_ghost_edge`

— Method`each_ghost_edge(tri::Triangulation) -> Edges`

Returns an iterator over all ghost edges in `tri`

.

See also `each_edge`

and `each_solid_edge`

.

`DelaunayTriangulation.each_ghost_triangle`

— Method`each_ghost_triangle(tri::Triangulation) -> Triangles`

Returns an iterator over all ghost triangles in `tri`

.

See also `each_triangle`

and `each_solid_triangle`

.

`DelaunayTriangulation.each_ghost_vertex`

— Method`each_ghost_vertex(tri::Triangulation) -> Set{Vertex}`

Returns an iterator over all ghost vertices in `tri`

.

See also `each_vertex`

and `each_solid_vertex`

.

`DelaunayTriangulation.each_point`

— Function`each_point(points) -> Iterator`

Returns an iterator over each point in `points`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [(1.0, 2.0), (5.0, 13.0)];
julia> DelaunayTriangulation.each_point(points)
2-element Vector{Tuple{Float64, Float64}}:
(1.0, 2.0)
(5.0, 13.0)
julia> points = [1.0 5.0 17.7; 5.5 17.7 0.0];
julia> DelaunayTriangulation.each_point(points)
3-element ColumnSlices{Matrix{Float64}, Tuple{Base.OneTo{Int64}}, SubArray{Float64, 1, Matrix{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}}:
[1.0, 5.5]
[5.0, 17.7]
[17.7, 0.0]
```

`DelaunayTriangulation.each_point`

— Method`each_point(tri::Triangulation) -> Points`

Returns an iterator over all points in `tri`

.

If `tri`

has vertices that are not yet present in the triangulation, e.g. if you have deleted vertices or have some submerged vertices in a weighted triangulation, then the corresponding points will still be present in this iterator. It is recommended that you instead consider `each_vertex`

, `each_solid_vertex`

, or `each_ghost_vertex`

together with `get_point`

to get the coordinates.

`DelaunayTriangulation.each_point_index`

— Function`each_point_index(points) -> Iterator`

Returns an iterator over each point index in `points`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [(1.0, 2.0), (-5.0, 2.0), (2.3, 2.3)];
julia> DelaunayTriangulation.each_point_index(points)
Base.OneTo(3)
julia> points = [1.0 -5.0 2.3; 2.0 2.0 2.3];
julia> DelaunayTriangulation.each_point_index(points)
Base.OneTo(3)
```

`DelaunayTriangulation.each_point_index`

— Method`each_point_index(tri::Triangulation) -> Indices`

Returns an iterator over all point indices in `tri`

.

If `tri`

has vertices that are not yet present in the triangulation, e.g. if you have deleted vertices or have some submerged vertices in a weighted triangulation, then the corresponding point indices will still be present in this iterator. It is recommended that you instead consider `each_vertex`

, `each_solid_vertex`

, or `each_ghost_vertex`

.

`DelaunayTriangulation.each_polygon`

— Method`each_polygon(vor::VoronoiTessellation) -> ValueIterator`

Returns an iterator over each set of polygon vertices of `vor`

.

`DelaunayTriangulation.each_polygon_index`

— Method`each_polygon_index(vor::VoronoiTessellation) -> KeySet`

Returns an iterator over the polygon indices of `vor`

.

`DelaunayTriangulation.each_polygon_vertex`

— Method`each_polygon_vertex(vor::VoronoiTessellation) -> UnitRange`

Returns an iterator over each polygon point index of `vor`

.

`DelaunayTriangulation.each_segment`

— Method`each_segment(tri::Triangulation) -> Edges`

Returns an iterator over all segments in `tri`

. This includes both interior and boundary segments. If you only want interior segments, then see `get_interior_segments`

,

`DelaunayTriangulation.each_solid_edge`

— Method`each_solid_edge(tri::Triangulation) -> Edges`

Returns an iterator over all solid edges in `tri`

.

See also `each_edge`

and `each_ghost_edge`

.

`DelaunayTriangulation.each_solid_triangle`

— Method`each_solid_triangle(tri::Triangulation) -> Triangles`

Returns an iterator over all solid triangles in `tri`

.

See also `each_triangle`

and `each_ghost_triangle`

.

`DelaunayTriangulation.each_solid_vertex`

— Method`each_solid_vertex(tri::Triangulation) -> Set{Vertex}`

Returns an iterator over all solid vertices in `tri`

.

See also `each_vertex`

and `each_ghost_vertex`

.

`DelaunayTriangulation.each_triangle`

— Function`each_triangle(T) -> Iterator`

Return an iterator over the triangles in `T`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> T = Set(((1, 2, 3), (-1, 5, 10), (17, 13, 18)));
julia> each_triangle(T)
Set{Tuple{Int64, Int64, Int64}} with 3 elements:
(-1, 5, 10)
(1, 2, 3)
(17, 13, 18)
julia> T = [[1, 2, 3], [10, 15, 18], [1, 5, 6]];
julia> each_triangle(T)
3-element Vector{Vector{Int64}}:
[1, 2, 3]
[10, 15, 18]
[1, 5, 6]
```

`DelaunayTriangulation.each_triangle`

— Method`each_triangle(tri::Triangulation) -> Triangles`

Returns an iterator over all triangles in `tri`

. Note that, if `has_ghost_triangles(tri)`

, then some of these triangles will be ghost triangles.

See also `each_solid_triangle`

and `each_ghost_triangle`

.

`DelaunayTriangulation.each_unbounded_polygon`

— Method`each_polygon(vor::VoronoiTessellation) -> Set`

Returns an iterator over the polygon indices of `vor`

.

`DelaunayTriangulation.each_vertex`

— Method" each_vertex(tri::Triangulation) -> Set{Vertex}

Returns an iterator over all vertices in `tri`

. Note that, if `has_ghost_triangles(tri)`

, then some of these vertices will be ghost vertices.

See also `each_solid_vertex`

and `each_ghost_vertex`

.

`DelaunayTriangulation.edge_exists`

— Method```
edge_exists(tri::Triangulation, ij) -> Bool
edge_exists(tri::Triangulation, i, j) -> Bool
```

Tests if the edge `(i, j)`

is in `tri`

, returning `true`

if so and `false`

otherwise.

See also `unoriented_edge_exists`

.

`DelaunayTriangulation.edge_length`

— Function```
edge_length(tri::Triangulation, u, v) -> Number
edge_length(tri::Triangulation, e) -> Number
```

Computes the length of the edge `e = (u, v)`

.

`DelaunayTriangulation.edge_length_sqr`

— Method```
edge_length_sqr(tri::Triangulation, u, v) -> Number
edge_length_sqr(tri::Triangulation, e) -> Number
```

Computes the square of the length of the edge `e = (u, v)`

.

`DelaunayTriangulation.edge_type`

— Method`edge_type(E) -> DataType`

Get the type of edges in `E`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> e = Set(((1,2),(2,3),(17,5)))
Set{Tuple{Int64, Int64}} with 3 elements:
(1, 2)
(17, 5)
(2, 3)
julia> DelaunayTriangulation.edge_type(e)
Tuple{Int64, Int64}
julia> e = [[1,2],[3,4],[17,3]]
3-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]
[17, 3]
julia> DelaunayTriangulation.edge_type(e)
Vector{Int64} (alias for Array{Int64, 1})
```

`DelaunayTriangulation.edge_type`

— Method`edge_type(tri::Triangulation) -> DataType`

Returns the type used for representing individual edges in `tri`

.

`DelaunayTriangulation.edge_type`

— Method`edge_type(vorn::VoronoiTessellation) -> DataType`

Type used for representing individual edges in the Voronoi tessellation.

`DelaunayTriangulation.edge_vertices`

— Method`edge_vertices(e) -> NTuple{2, Vertex}`

Get the vertices of `e`

**Examples**

```
julia> using DelaunayTriangulation
julia> e = (1, 5);
julia> edge_vertices(e)
(1, 5)
julia> e = [23, 50];
julia> edge_vertices(e)
(23, 50)
```

`DelaunayTriangulation.edges_are_disjoint`

— Method`edges_are_disjoint(e, e′) -> Bool`

Returns `true`

if `e`

and `e′`

have any shared vertex, and `false`

otherwise.

`DelaunayTriangulation.edges_type`

— Method`edges_type(tri::Triangulation) -> DataType`

Returns the type used for representing collections of edges in `tri`

.

`DelaunayTriangulation.empty_representative_points!`

— Method`empty_representative_points!(tri::Triangulation)`

Empties the `Dict`

of representative points of `tri`

.

`DelaunayTriangulation.empty_unconstrained_triangulation!`

— Method`empty_unconstrained_triangulation!(tri::Triangulation)`

Empties the triangulation `tri`

by emptying its fields. Only works for unconstrained triangulaions.

`DelaunayTriangulation.encroaches_upon`

— Method`encroaches_upon(p, q, r, args::RefinementArguments) -> Bool`

Determines if a point `r`

encroaches upon a segment `pq`

according to the `RefinementArguments`

.

See also `point_position_relative_to_diametral_circle`

and `point_position_relative_to_diametral_lens`

.

`DelaunayTriangulation.enqueue_all!`

— Method`enqueue_all!(queue::Queue, data)`

Adds all `data`

to the end of the `queue`

.

`DelaunayTriangulation.enqueue_all_bad_triangles!`

— Method`enqueue_all_bad_triangles!(args::RefinementArguments, tri::Triangulation)`

Enqueues all bad triangles in the triangulation into `args.queue`

.

`DelaunayTriangulation.enqueue_all_encroached_segments!`

— Method`enqueue_all_encroached_segments!(args::RefinementArguments, tri::Triangulation)`

Enqueues all encroached segments in the triangulation into `args.queue`

.

`DelaunayTriangulation.enqueue_new_edge!`

— Method`enqueue_new_edge!(polygon_edge_queue, vorn::VoronoiTessellation, e)`

Enqueue the edge `e`

of the boundary to be processed.

**Arguments**

`polygon_edge_queue`

: The queue of edges that are to be processed.`vorn`

: The`VoronoiTessellation`

.`e`

: The edge to be processed.

**Outputs**

There are no outputs, as `polygon_edge_queue`

is modified in-place.

`DelaunayTriangulation.enqueue_newly_encroached_segments!`

— Method`enqueue_newly_encroached_segments!(args::RefinementArguments, tri::Triangulation) -> Bool`

Enqueues all segments that are newly encroached upon after a point insertion into the triangulation into `args.queue`

.

**Arguments**

`args::RefinementArguments`

: The`RefinementArguments`

for the refinement.`tri::Triangulation`

: The`Triangulation`

to enqueue newly encroached segments of.

**Output**

`any_encroached`

: Whether any segments were newly encroached upon.

`DelaunayTriangulation.enrich_boundary!`

— Method`enrich_boundary!(enricher::BoundaryEnricher)`

Enriches the initial boundary defined inside `enricher`

, implementing the algorithm of Gosselin and Ollivier-Gooch (2007). At the termination of the algorithm, all edges will contain no other points inside their diametral circles.

`DelaunayTriangulation.eval_boundary_curve`

— Method`eval_boundary_curve(enricher::BoundaryEnricher, curve_index, t) -> NTuple{2,Float64}`

Returns the `curve_index`

th boundary curve at `t`

.

`DelaunayTriangulation.eval_fnc_at_het_tuple_element`

— Method`eval_fnc_at_het_tuple_element(f, tup, idx)`

Evaluates `f(tup[idx])`

in a type-stable way. If `idx > length(tup)`

, then `f`

is evaluated on the last element of `tup`

.

`DelaunayTriangulation.eval_fnc_at_het_tuple_element_with_arg`

— Method`eval_fnc_at_het_tuple_element_with_arg(f, tup, arg, idx)`

Evaluates `f(tup[idx], arg...)`

in a type-stable way. If `idx > length(tup)`

, then `f`

is evaluated on the last element of `tup`

.

`DelaunayTriangulation.eval_fnc_at_het_tuple_two_elements`

— Method`eval_fnc_at_het_tuple_two_elements(f, tup, idx1, idx2)`

Evaluates `f(tup[idx1], tup[idx2])`

in a type-stable way.

`DelaunayTriangulation.eval_fnc_in_het_tuple`

— Method`eval_fnc_in_het_tuple(tup, arg, idx)`

Evaluates `tup[idx](arg...)`

in a type-stable way. If `idx > length(tup)`

, then `tup[end](arg...)`

is evaluated.

`DelaunayTriangulation.expand`

— Function`expand(box::BoundingBox, perc=0.10) -> BoundingBox`

Expands the bounding box `box`

by a factor `perc`

in each direction.

`DelaunayTriangulation.expand_bounds!`

— Function`expand_bounds!(hierarchy::PolygonHierarchy, perc=0.10) -> PolygonHierarchy`

Expands the bounding boxes of `hierarchy`

by a factor of `perc`

in each direction.

`DelaunayTriangulation.extend_segments!`

— Method`extend_segments!(segments, segment)`

Given an ordered vector of `segments`

, ensures that they also represent the replacement of `segment`

. In particular, suppose `segments`

represents the sequence of edges

` ---(i₁, i₂)---(i₂, i₃)---(⋯, ⋯)---(iₙ₋₁, iₙ)---`

and `segment`

is `(i₀, iₙ₊₁)`

. Then the extended sequence becomes

` ---(i₀, i₁)---(i₁, i₂)---(i₂, i₃)---(⋯, ⋯)---(iₙ₋₁, iₙ)---(iₙ, iₙ₊₁)---`

**Example**

```
julia> using DelaunayTriangulation
julia> segments = [(2, 7), (7, 12), (12, 49)];
julia> segment = (1, 68);
julia> DelaunayTriangulation.extend_segments!(segments, segment)
5-element Vector{Tuple{Int64, Int64}}:
(1, 2)
(2, 7)
(7, 12)
(12, 49)
(49, 68)
```

`DelaunayTriangulation.exterior_jump_and_march`

— Function`exterior_jump_and_march(tri::Triangulation, k, q, ghost_vertex=𝒢) -> (Vertex, Vertex)`

Given a query point `q`

outside of the triangulation, find the ghost triangle containing `q`

.

**Arguments**

`tri`

: The`Triangulation`

.`k`

: The exterior boundary vertex to start from.`q`

: The query point.`ghost_vertex=𝒢`

: The ghost vertex corresponding to the boundary that`k`

resides on.

**Outputs**

`i`

: The first vertex of the edge on the boundary adjoining the positively oriented ghost triangle.`j`

: The second vertex of the edge on the boundary adjoining the positively oriented ghost triangle.

This function assumes that the geometry is convex. If the geometry is not convex, the returned value may not be correct and should be checked separately. Additionally, if `q`

is actually inside the triangulation, then the result is meaningless.

**Extended help**

This function works by first finding the position of `q`

relative to `pₘp`

, where `pₘ`

is the representative point for the `ghost_vertex`

and `p = get_point(tri, k)`

. Depending on this position, we rotate counter-clockwise if `q`

is left of the line using `exterior_jump_and_march_rotate_left`

and clockwise otherwise using `exterior_jump_and_march_rotate_right`

. By keeping track of the current position of `q`

and its position relative to the next ghost edge, we can identify when `q`

resides inside a ghost triangle.

`DelaunayTriangulation.finalise!`

— Method`finalise!(tri::Triangulation, args::RefinementArguments)`

Finalises the triangulation after refinement, e.g. by deleting ghost triangles and unlocking the convex hull if needed.

`DelaunayTriangulation.find_all_intersections`

— Method`find_all_intersections(vorn::VoronoiTessellation) -> (Dict, Vector, Set, Dict)`

Find all intersections between the edges of the Voronoi tessellation and the boundary of the polygon.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.

**Outputs**

`boundary_sites`

: A dictionary of boundary sites.`segment_intersections`

: The intersection points.`exterior_circumcenters`

: The circumcenters that are outside of the domain.`equal_circumcenter_mapping`

: A mapping from the indices of the segment intersections that are equal to the circumcenter of a site to the index of the site.

**Extended help**

This algorithm works as follows:

- First, using
`initialise_clipping_arrays`

, we initialise the arrays that we will use to store the intersections, and queue up all boundary edges for processing. - Then, starting with the first edge in
`edges_to_process`

, we dequeue an edge from`polygon_edge_queue`

and process it via`dequeue_and_process!`

. - We repeat step 2 until
`polygon_edge_queue`

and`edges_to_process`

are both empty. - In the special case that there is just a single triangle in the underlying triangulation, we process the intersections using
`add_segment_intersection!`

directly. - We then return.

`DelaunayTriangulation.find_all_points_to_delete!`

— Method`find_all_points_to_delete!(points_to_process, tri::Triangulation, seed, all_bn)`

Starting at `seed`

, finds more points to spread to and mark for deletion.

**Arguments**

`points_to_process`

: The current list of points marked for deletion.`tri::Triangulation`

: The`Triangulation`

.`seed`

: The seed vertex to start spreading from.`all_bn`

: All the boundary nodes in the triangulation, obtained from`get_all_boundary_nodes`

.

**Outputs**

There are no outputs, as `points_to_process`

is updated in-place.

**Extended help**

This function works by considering the neighbours around the vertex `seed`

. For each neighbouring vertex, we designate that as a new seed, and consider if it needs to be added into `points_to_process`

according to its distance from the triangulation computed from `distance_to_polygon`

. We then call `find_all_points_to_delete!`

recursively again on the new seed.

`DelaunayTriangulation.find_all_points_to_delete`

— Method`find_all_points_to_delete(tri::Triangulation) -> Set{Int}`

Returns a set of all the points that are in the exterior faces of the triangulation `tri`

.

**Extended help**

This function works by 'spreading' from some initial vertex. In particular, starting at each boundary node, we spread outwards towards adjacent vertices, recursively spreading so that all exterior points are identified with the help of `find_all_points_to_delete!`

.

`DelaunayTriangulation.find_all_triangles_to_delete`

— Method`find_all_triangles_to_delete(tri::Triangulation, points_to_process) -> Set{Triangle}`

Returns a set of all the triangles that are in the exterior faces of the triangulation `tri`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`points_to_process`

: The set of points that are in the exterior faces of the triangulation`tri`

, obtained from`find_all_points_to_delete`

.

**Outputs**

`triangles_to_delete`

: The set of triangles that are in the exterior faces of the triangulation`tri`

.

**Extended help**

This function works in two stages.

- Firstly, all the non-boundary vertices, i.e. those from
`points_to_process`

, are processed. For each vertex`v`

, the triangles adjoining it, given by`get_adjacent2vertex(tri, v)`

, aremarked for deletion. - Next, all the boundary vertices need to be processed and carefully analysed to determine if any other triangles need to be deleted since, for example, a triangle may be adjoining three vertices that are all boundary vertices, and it might not be obvious if it is inside or outside of the triangulation. By applying
`dist`

to compute the distance between the triangle's centroid and the triangulation, the triangle can be accurately marked for deletion if it is outside of the triangulation.

`DelaunayTriangulation.find_bounding_box`

— Method`find_bounding_box(tree::RTree, id_bounding_box::DiametralBoundingBox) -> Tuple{Leaf{Branch}, Int}`

Returns the leaf node and the index in the leaf node's children that `id_bounding_box`

is associated with.

`DelaunayTriangulation.find_duplicate_points`

— Method`find_duplicate_points(points) -> Dict{Point, Vector{Int}}`

Returns a `Dict`

of `points`

that maps each duplicate point to a `Vector`

of the indices of the duplicate points.

`DelaunayTriangulation.find_edge`

— Method`find_edge(tri::Triangulation, T, ℓ) -> Edge`

Given a triangle `T = (i, j, k)`

of `tri`

and a vertex `ℓ`

of `tri`

, returns the edge of `T`

that contains `ℓ`

. If no such edge exists, the edge `(k, i)`

is returned.

`DelaunayTriangulation.find_point_index`

— Method```
find_point_index(points, x, y) -> Integer
find_point_index(points, p) -> Integer
```

Returns an index of a point in `points`

that is equal to `p = (x, y)`

. If no such point exists, then `0`

is returned.

`DelaunayTriangulation.find_polygon`

— Method`find_polygon(tri::Triangulation, q) -> Integer`

Given a point `q`

, finds the index of the polygon in the triangulation `tri`

that contains `q`

. If `q`

is on the boundary of the triangulation or outside the triangulation, the function returns `0`

.

See also `dist`

and `distance_to_polygon`

.

`DelaunayTriangulation.find_position_in_parent`

— Method`find_position_in_parent(node::AbstractNode) -> Int`

Returns the position of `node`

in its parent's children. If `node`

has no parent, returns `0`

.

`DelaunayTriangulation.find_subtree`

— Method`find_subtree(tree, bounding_box, level) -> Union{Branch,Leaf{Branch}}`

Returns the subtree of `tree`

at `level`

that `bounding_box`

should be inserted into.

`DelaunayTriangulation.find_tree`

— Method`find_tree(hierarchy::PolygonHierarchy, points, boundary_nodes, p) -> Union{Nothing,PolygonTree}`

Finds a tree in `hierarchy`

containing `p`

.

**Arguments**

`hierarchy::PolygonHierarchy`

: The`PolygonHierarchy`

to search.`points`

: The point set.`boundary_nodes`

: The boundary nodes.`p`

: The point to test the trees of`hierarchy`

against.

**Output**

`nothing`

if`p`

is not inside any tree in`hierarchy`

, and the`PolygonTree`

containing`p`

otherwise.

`DelaunayTriangulation.find_tree`

— Method`find_tree(hierarchy::PolygonHierarchy, points, boundary_nodes, tree::PolygonTree, p) -> PolygonTree`

Finds a tree in `hierarchy`

containing `p`

that is a child of `tree`

, assuming `p`

is inside `tree`

.

**Arguments**

`hierarchy::PolygonHierarchy`

: The`PolygonHierarchy`

to search.`points`

: The point set.`boundary_nodes`

: The boundary nodes.`tree::PolygonTree`

: The`PolygonTree`

to search, assuming`p`

is inside`tree`

.`p`

: The point to test the children of`tree`

against.

**Output**

`tree`

if`p`

is inside`tree`

but none of its children, and a child containing`p`

otherwise.

`DelaunayTriangulation.fix_down!`

— Method`fix_down!(queue::MaxPriorityQueue, k)`

Fixes the `queue`

after decreasing the value of one of its elements by percolating downwards.

`DelaunayTriangulation.fix_edge_order_after_rotation!`

— Method`fix_edge_order_after_rotation!(tri::Triangulation, segment, e)`

Fixes the edge order in `get_interior_segments(tri)`

after `segment`

was rotated by `optimise_edge_order`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`segment`

: The segment that was arranged.`e`

: The arranged segment from`optimise_edge_order`

.

**Outputs**

There is no output, but `tri`

will be updated so that `e`

is in `get_interior_segments(tri)`

instead of `segment`

.

`DelaunayTriangulation.fix_edges_after_deletion!`

— Method`fix_edges_after_deletion!(tri::Triangulation, S)`

Ensures that the edges in `S`

surrounding a deleted vertex of `tri`

are correctly updated.

`DelaunayTriangulation.fix_segments!`

— Method`fix_segments!(segments, bad_indices)`

Fixes the overlapping segments in `segments`

, referred to via `bad_indices`

, by connecting consecutive edges where needed.

**Arguments**

`segments`

: The segments to fix.`bad_indices`

: The indices of the segments to fix.

**Outputs**

There are no outputs as `segments`

is updated in-place.

**Example**

```
julia> using DelaunayTriangulation
julia> segments = [(2, 15), (2, 28), (2, 41)]; # the edges all start with 2, so they are not actual segments in the triangulation, and so must be fixed
julia> bad_indices = [1, 2, 3];
julia> DelaunayTriangulation.fix_segments!(segments, bad_indices)
3-element Vector{Tuple{Int64, Int64}}:
(2, 15)
(15, 28)
(28, 41)
julia> segments = [(2, 7), (2, 12), (12, 17), (2, 22), (2, 27), (2, 32), (32, 37), (2, 42), (42, 47)];
julia> bad_indices = [2, 4, 5, 6, 8]
5-element Vector{Int64}:
2
4
5
6
8
julia> DelaunayTriangulation.fix_segments!(segments, bad_indices)
9-element Vector{Tuple{Int64, Int64}}:
(2, 7)
(7, 12)
(12, 17)
(17, 22)
(22, 27)
(27, 32)
(32, 37)
(37, 42)
(42, 47)
```

`DelaunayTriangulation.fix_up!`

— Method`fix_up!(queue::MaxPriorityQueue, k)`

Fixes the `queue`

after increasing the value of one of its elements by percolating upwards.

`DelaunayTriangulation.flip_edge!`

— Method```
flip_edge!(tri::Triangulation, i, j, store_event_history=Val(false), event_history=nothing)
flip_edge!(tri::Triangulation, i, j, k, ℓ, store_event_history=Val(false), event_history=nothing)
```

Flips the edge between vertices `i`

and `j`

in `tri`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`i`

: The first vertex of the edge to flip.`j`

: The second vertex of the edge to flip.`k`

: The vertex`k = get_adjacent(tri, j, i)`

. This is only used in the second method.`ℓ`

: The vertex`ℓ = get_adjacent(tri, i, j)`

. This is only used in the second method.`store_event_history=Val(false)`

: Whether to store the event history of the flip.`event_history=nothing`

: The event history. Only updated if`store_event_history`

is true, in which case it needs to be an`InsertionEventHistory`

object. This storage is done using`store_flip_edge_history!`

.

**Outputs**

There is no output, as `tri`

is updated in-place.

If `(i, j, k, ℓ)`

, where `ℓ = get_adjacent(tri, i, j)`

and `k = get_adjacent(tri, j, i)`

, is not a convex quadrilateral, then this edge flip will make the triangulation non-planar.

`DelaunayTriangulation.get_adjacent`

— Method`get_adjacent(adj::Adjacent) -> Dict`

Returns the `adjacent`

map of `adj`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> d = Dict((1, 2) => 3, (2, 3) => 1, (3, 1) => 2);
julia> adj = DelaunayTriangulation.Adjacent(d)
Adjacent{Int64, Tuple{Int64, Int64}}, with map:
Dict{Tuple{Int64, Int64}, Int64} with 3 entries:
(1, 2) => 3
(3, 1) => 2
(2, 3) => 1
julia> get_adjacent(adj)
Dict{Tuple{Int64, Int64}, Int64} with 3 entries:
(1, 2) => 3
(3, 1) => 2
(2, 3) => 1
julia> get_adjacent(adj) == d
true
```

`DelaunayTriangulation.get_adjacent`

— Method```
get_adjacent(tri::Triangulation, uv) -> Vertex
get_adjacent(tri::Triangulation, u, v) -> Vertex
```

Returns the vertex `w`

such that `(u, v, w)`

is a positively oriented triangle in the underlying triangulation, or `∅`

if no such triangle exists.

`DelaunayTriangulation.get_adjacent`

— Method`get_adjacent(tri::Triangulation) -> Adjacent`

Returns the adjacency map of the triangulation. This is a map from each edge `(u, v)`

to a vertex `w`

such that `(u, v, w)`

is a positively oriented triangle in `tri`

.

See also `Adjacent`

.

`DelaunayTriangulation.get_adjacent`

— Method```
get_adjacent(vor::VoronoiTessellation, ij) -> Index
get_adjacent(vor::VoronoiTessellation, i, j) -> Index
```

Gets the polygon index associated with the oriented edge `ij`

in the Voronoi tessellation `vor`

.

`DelaunayTriangulation.get_adjacent`

— Method`get_adjacent(vorn::VoronoiTessellation) -> Adjacent{Index,Edge}`

Gets the adjacency information of the Voronoi tessellation `vorn`

as an `Adjacent`

object. This object maps oriented edges to the polygons that they belong to.

`DelaunayTriangulation.get_adjacent`

— Method```
get_adjacent(adj::Adjacent{I, E}, uv::E) -> Vertex
get_adjacent(adj::Adjacent{I, E}, u, v) -> Vertex
```

Returns the vertex `w`

such that `(u, v, w)`

is a positively oriented triangle in the underlying triangulation, or `∅`

if no such triangle exists.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj = DelaunayTriangulation.Adjacent(Dict((1, 2) => 3, (2, 3) => 1, (3, 1) => 2, (4, 5) => -1))
Adjacent{Int64, Tuple{Int64, Int64}}, with map:
Dict{Tuple{Int64, Int64}, Int64} with 4 entries:
(4, 5) => -1
(1, 2) => 3
(3, 1) => 2
(2, 3) => 1
julia> get_adjacent(adj, 4, 5)
-1
julia> get_adjacent(adj, (3, 1))
2
julia> get_adjacent(adj, (1, 2))
3
julia> get_adjacent(adj, 17, 5)
0
julia> get_adjacent(adj, (1, 6))
0
```

`DelaunayTriangulation.get_adjacent2vertex`

— Method`get_adjacent2vertex(adj2v::Adjacent2Vertex, w) -> Edges`

Returns the set of edges `E`

such that `(u, v, w)`

is a positively oriented triangle in the underlying triangulation for each `(u, v) ∈ E`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> adj2v = DelaunayTriangulation.Adjacent2Vertex(Dict(1 => Set(((2, 3), (5, 7), (8, 9))), 5 => Set(((1, 2), (7, 9), (8, 3)))))
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 2 entries:
5 => Set([(1, 2), (8, 3), (7, 9)])
1 => Set([(8, 9), (5, 7), (2, 3)])
julia> get_adjacent2vertex(adj2v, 1)
Set{Tuple{Int64, Int64}} with 3 elements:
(8, 9)
(5, 7)
(2, 3)
julia> get_adjacent2vertex(adj2v, 5)
Set{Tuple{Int64, Int64}} with 3 elements:
(1, 2)
(8, 3)
(7, 9)
```

`DelaunayTriangulation.get_adjacent2vertex`

— Method`get_adjacent2vertex(adj2v::Adjacent2Vertex) -> Dict`

Returns the `adjacent2vertex`

map of `adj2v`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> e1 = Set(((1, 2), (5, 3), (7, 8)));
julia> e2 = Set(((2, 3), (13, 5), (-1, 7)));
julia> d = Dict(9 => e1, 6 => e2);
julia> adj2v = DelaunayTriangulation.Adjacent2Vertex(d)
Adjacent2Vertex{Int64, Set{Tuple{Int64, Int64}}} with map:
Dict{Int64, Set{Tuple{Int64, Int64}}} with 2 entries:
6 => Set([(13, 5), (-1, 7), (2, 3)])
9 => Set([(1, 2), (7, 8), (5, 3)])
julia> get_adjacent2vertex(adj2v)
Dict{Int64, Set{Tuple{Int64, Int64}}} with 2 entries:
6 => Set([(13, 5), (-1, 7), (2, 3)])
9 => Set([(1, 2), (7, 8), (5, 3)])
julia> get_adjacent2vertex(adj2v) == d
true
```

`DelaunayTriangulation.get_adjacent2vertex`

— Method`get_adjacent2vertex(tri::Triangulation, w) -> Edges`

Returns the set of all edges `(u, v)`

in `tri`

such that `(u, v, w)`

is a positively oriented triangle in `tri`

.

`DelaunayTriangulation.get_adjacent2vertex`

— Method`get_adjacent2vertex(tri::Triangulation) -> Adjacent2Vertex`

Returns the `Adjacent2Vertex`

map of the triangulation `tri`

. This is a map from a vertex `w`

to a set of all edges `(u, v)`

such that `(u, v, w)`

is a positively oriented triangle in `tri`

.

`DelaunayTriangulation.get_all_boundary_nodes`

— Method`get_all_boundary_nodes(tri::Triangulation) -> Set{Vertex}`

Returns the set of all boundary vertices in `tri`

, in no specific order.

`DelaunayTriangulation.get_all_segments`

— Method`get_all_segments(tri::Triangulation) -> Edges`

Return all segments of the triangulation. This includes interior segments and boundary segments. Segments are edges that are forced to be in the triangulation.

`DelaunayTriangulation.get_all_stat`

— Method`get_all_stat(stats::TriangulationStatistics, stat::Symbol) -> Vector`

Returns a vector of the statistic `stat`

for each triangle in `stats`

.

`DelaunayTriangulation.get_angles`

— Method`get_angles(stats::TriangulationStatistics, T)`

Returns the angles field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_apex`

— Method`get_apex(complex::SmallAngleComplex{I}) where {I} -> I`

Returns the apex of `complex`

.

`DelaunayTriangulation.get_area`

— Method`get_area(r::BoundingBox) -> Float64`

Returns the area of `r`

, i.e. `hspan(r) * vspan(r)`

.

`DelaunayTriangulation.get_area`

— Method`get_area(stats::TriangulationStatistics, T)`

Returns the area field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_area`

— Method`get_area(stats::TriangulationStatistics)`

Returns the area field from the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_area`

— Method`get_area(tri::Triangulation) -> Number`

Returns the area of `tri`

.

`DelaunayTriangulation.get_area`

— Method`get_area(vor::VoronoiTessellation, i) -> Number`

Gets the area of the `i`

th Voronoi polygon.

`DelaunayTriangulation.get_aspect_ratio`

— Method`get_aspect_ratio(stats::TriangulationStatistics, T)`

Returns the aspect_ratio field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_bl_corner`

— Method`get_bl_corner(r::BoundingBox) -> NTuple{2,Float64}`

Returns the bottom-left corner of `r`

.

`DelaunayTriangulation.get_boundary_chain`

— Method`get_boundary_chain(tri::Triangulation, i, j) -> Edges`

Given two boundary vertices `i`

and `j`

on a boundary with ghost vertex `ghost_vertex`

, walks counter-clockwise from `i`

to `j`

along the boundary and returns the collection of all vertices encountered in counter-clockwise order.

`DelaunayTriangulation.get_boundary_curve`

— Method`get_boundary_curve(boundary_enricher::BoundaryEnricher, curve_index) -> AbstractParametricCurve`

Returns the `curve_index`

th curve from the boundary curves in `boundary_enricher`

.

`DelaunayTriangulation.get_boundary_curves`

— Method`get_boundary_curves(boundary_enricher::BoundaryEnricher{P,B,C}) -> C`

Returns the boundary curves associated with `boundary_enricher`

.

`DelaunayTriangulation.get_boundary_curves`

— Method`get_boundary_curves(tri::Triangulation) -> NTuple{N, Function}`

Returns the functions defining the boundaries of `tri`

. If `!is_curve_bounded(tri)`

, then this returns an empty `Tuple`

. Otherwise, this returns a `Tuple`

of functions, one for each section of the boundary, where the `i`

th element of the `Tuple`

corresponds to the `i`

th section of the boundary, which corresponds to the ghost vertex `-i`

. For curves that are defined by boundary nodes rather than by a function, the function is `PiecewiseLinear`

. For the other functions, these are all defined by `t -> NTuple{2, Number}`

, where `t ∈ [0, 1]`

and the `NTuple{2, Number}`

is the coordinate on the curve at that `t`

.

`DelaunayTriangulation.get_boundary_edge_map`

— Method`get_boundary_edge_map(boundary_enricher::BoundaryEnricher, i, j)`

Returns the value from the key `(i, j)`

in the boundary edge map of `boundary_enricher`

. The returned value is a `Tuple`

`(position, index)`

so that `boundary_nodes = get_boundary_nodes(get_boundary_nodes(boundary_enricher), position)`

are the boundary nodes associated with the section that `(i, j)`

resides on, and `i = get_boundary_nodes(boundary_nodes, index)`

and `j = get_boundary_nodes(boundary_nodes, index + 1)`

.

`DelaunayTriangulation.get_boundary_edge_map`

— Method`get_boundary_edge_map(boundary_enricher::BoundaryEnricher{P,B,C,I,BM}) -> BM`

Returns the boundary edge map associated with `boundary_enricher`

.

`DelaunayTriangulation.get_boundary_edge_map`

— Method```
get_boundary_edge_map(tri::Triangulation, ij)
get_boundary_edge_map(tri::Triangulation, i, j)
```

Returns the value from the key `(i, j)`

in the boundary edge map of `tri`

. The returned value is a `Tuple`

`(position, index)`

so that `boundary_nodes = get_boundary_nodes(tri, position)`

are the boundary nodes associated with the section that `(i, j)`

resides on, and `i = get_boundary_nodes(boundary_nodes, index)`

and `j = get_boundary_nodes(boundary_nodes, index + 1)`

.

`DelaunayTriangulation.get_boundary_edge_map`

— Method`get_boundary_edge_map(tri::Triangulation) -> Dict`

Returns the boundary edge map of the triangulation `tri`

. This is a `Dict`

that maps a boundary edge `(u, v)`

to its position in `get_boundary_nodes(tri)`

. In particular, the returned value is a `Tuple`

`(position, index)`

so that `boundary_nodes = get_boundary_nodes(tri, position)`

are the boundary nodes associated with the section that `(u, v)`

resides on, and `u = get_boundary_nodes(boundary_nodes, index)`

and `v = get_boundary_nodes(boundary_nodes, index + 1)`

.

See also `construct_boundary_edge_map`

.

`DelaunayTriangulation.get_boundary_enricher`

— Method`get_boundary_enricher(tri::Triangulation) -> BoundaryEnricher`

Returns the `BoundaryEnricher`

of `tri`

. If the domain is not curve-bounded, this is `nothing`

.

`DelaunayTriangulation.get_boundary_nodes`

— Function`get_boundary_nodes(boundary_nodes, mnℓ...)`

Given a collection of `boundary_nodes`

, returns the specified component of the collection. There are several forms for the methods:

`get_boundary_nodes(boundary_nodes, m)`

: If`boundary_nodes`

has multiple curves, this returns the`m`

th curve. If`boundary_nodes`

has multiple sections, this returns the`m`

th section. Otherwise, this returns the`m`

th boundary node.`get_boundary_nodes(boundary_nodes, m, n)`

: If`boundary_nodes`

has multiple curves, this returns the`n`

th section of the`m`

th curve. Otherwise, if`boundary_nodes`

has multiple sections, this returns the`n`

th boundary node of the`m`

th section.`get_boundary_nodes(boundary_nodes, (m, n))`

: This is equivalent to`get_boundary_nodes(boundary_nodes, m, n)`

.`get_boundary_nodes(boundary_nodes::A, ::A)`

: This just returns`boundary_nodes`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> get_boundary_nodes([[[1, 2, 3, 4], [4, 5, 1]], [[6, 7, 8, 9], [9, 10, 6]]], 2)
2-element Vector{Vector{Int64}}:
[6, 7, 8, 9]
[9, 10, 6]
julia> get_boundary_nodes([[1, 2, 3, 4], [4, 5, 1]], 1)
4-element Vector{Int64}:
1
2
3
4
julia> get_boundary_nodes([1, 2, 3, 4, 5, 6, 1], 4)
4
julia> get_boundary_nodes([[[1, 2, 3, 4], [4, 5, 1]], [[6, 7, 8, 9], [9, 10, 6]]], 1, 2)
3-element Vector{Int64}:
4
5
1
julia> get_boundary_nodes([[1, 2, 3, 4], [4, 5, 6, 1]], 2, 3)
6
julia> get_boundary_nodes([1, 2, 3, 4, 5, 1], [1, 2, 3, 4, 5, 1])
6-element Vector{Int64}:
1
2
3
4
5
1
```

`DelaunayTriangulation.get_boundary_nodes`

— Method`get_boundary_nodes(boundary_enricher::BoundaryEnricher{P,B}) -> B`

Returns the boundary nodes associated with `boundary_enricher`

.

`DelaunayTriangulation.get_boundary_nodes`

— Method`get_boundary_nodes(tri, mnℓ...)`

Given a triangulation `tri`

, returns the specified component of the boundary nodes. There are several forms for the methods:

`get_boundary_nodes(tri, m)`

: If`tri`

has multiple curves, this returns the`m`

th curve. If`tri`

has multiple sections, this returns the`m`

th section. Otherwise, this returns the`m`

th boundary node.`get_boundary_nodes(tri, m, n)`

: If`tri`

has multiple curves, this returns the`n`

th section of the`m`

th curve. Otherwise, if`tri`

has multiple sections, this returns the`n`

th boundary node of the`m`

th section.`get_boundary_nodes(tri, (m, n))`

: This is equivalent to`get_boundary_nodes(tri, m, n)`

.`get_boundary_nodes(tri::A, ::A)`

: This just returns`boundary_nodes`

.

`DelaunayTriangulation.get_boundary_nodes`

— Method`get_boundary_nodes(tri::Triangulation) -> BoundaryNodes`

Return the boundary nodes of the triangulation. This is only for triangulations with a constrained boundary. If the triangulation has no constrained boundary, then the boundary is instead given by its convex hull and this function returns an empty vector. See `get_convex_hull`

.

`DelaunayTriangulation.get_boundary_polygons`

— Method`get_boundary_polygons(vorn::VoronoiTessellation) -> Set{Index}`

Gets the boundary polygons of the Voronoi tessellation `vorn`

as a `Set`

of polygon indices.

`DelaunayTriangulation.get_bounded_polygon_coordinates`

— Method`get_bounded_polygon_coordinates(vorn::VoronoiTessellation, i, bounding_box) -> Vector{NTuple{2,Number}}`

Returns the coordinates of the `i`

th polygon of `vorn`

, clipped to `bounding_box`

.

`DelaunayTriangulation.get_bounding_box`

— Method`get_bounding_box(node::AbstractNode) -> BoundingBox`

Returns the bounding box of `node`

.

`DelaunayTriangulation.get_bounding_box`

— Method`get_bounding_box(id_bounding_box::DiametralBoundingBox) -> BoundingBox`

Returns the bounding box of `id_bounding_box`

.

`DelaunayTriangulation.get_bounding_box`

— Method`get_bounding_box(hierarchy::PolygonHierarchy, index) -> BoundingBox`

Returns the bounding box of the `index`

th polygon in `hierarchy`

.

`DelaunayTriangulation.get_bounding_box`

— Method`get_bounding_box(tree::RTree) -> BoundingBox`

Returns the bounding box of `tree`

.

`DelaunayTriangulation.get_bounding_boxes`

— Method`get_bounding_boxes(hierarchy::PolygonHierarchy) -> Vector{BoundingBox}`

Returns the bounding boxes of `hierarchy`

.

`DelaunayTriangulation.get_branch_cache`

— Method`get_branch_cache(tree::RTree) -> BranchCache`

Returns the branch cache of `tree`

.

`DelaunayTriangulation.get_cache`

— Method`get_cache(tri::Triangulation) -> TriangulationCache`

Returns the cache of `tri`

. This is a `TriangulationCache`

used as a cache for `add_segment!`

which requires a separate `Triangulation`

structure for use.

`DelaunayTriangulation.get_centroid`

— Method`get_centroid(stats::TriangulationStatistics, T)`

Returns the centroid field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_centroid`

— Method`get_centroid(vor::VoronoiTessellation, i) -> NTuple{2, Number}`

Gets the centroid of the `i`

th Voronoi polygon, given as a `Tuple`

of the form `(x, y)`

.

`DelaunayTriangulation.get_child`

— Method`get_child(node::AbstractNode, i::Integer) -> AbstractNode`

Returns the `i`

th child of `node`

.

`DelaunayTriangulation.get_child_type`

— Method`get_child_type(node::AbstractNode) -> Union{Type{Leaf}, Type{Branch}}`

Returns the type of the children of `node`

.

`DelaunayTriangulation.get_children`

— Method`get_children(node::AbstractNode) -> Vector`

Returns the children of `node`

.

`DelaunayTriangulation.get_children`

— Method`get_children(tree::PolygonTree) -> Set{PolygonTree}`

Returns the children of `tree`

.

`DelaunayTriangulation.get_circle_intersection`

— Method`get_circle_intersection(c::AbstractParametricCurve, t₁, t₂, r) -> (Float64, NTuple{2,Float64})`

Given a circle centered at `c(t₁)`

with radius `r`

, finds the first intersection of the circle with the curve after `t₁`

and less than `t₂`

. It is assumed that such an intersection exists. The returned value is `(t, q)`

, where `t`

is the parameter value of the intersection and `q`

is the point of intersection.

`DelaunayTriangulation.get_circle_intersection`

— Method`get_circle_intersection(enricher::BoundaryEnricher, curve_index, t₁, t₂, r) -> (Float64, NTuple{2,Float64})`

Finds the intersection of the `curve_index`

th curve with the circle centered at the curve evaluated at `t₁`

with radius `r`

. The argument `t₂`

defines the end of the subcurve to consider. The returned tuple is `(t, p)`

where `t`

is the parameter value of the intersection and `p`

is the point of intersection.

`DelaunayTriangulation.get_circumcenter`

— Method`get_circumcenter(stats::TriangulationStatistics, T)`

Returns the circumcenter field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_circumcenter_to_triangle`

— Method`get_circumcenter_to_triangle(vor::VoronoiTessellation, i) -> Triangle`

Gets the triangle associated with the `i`

th circumcenter. The triangle is sorted so that the minimum vertex is last.

`DelaunayTriangulation.get_circumcenter_to_triangle`

— Method`get_circumcenter_to_triangle(vorn::VoronoiTessellation) -> Dict{Index,Triangle}`

Gets the circumcenters of the Voronoi tessellation `vorn`

as a `Dict`

, mapping circumcenter indices to their corresponding triangles. The triangles are sorted so that the minimum vertex is last.

`DelaunayTriangulation.get_circumradius`

— Method`get_circumradius(stats::TriangulationStatistics, T)`

Returns the circumradius field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_clipping_poly_structs`

— Method`get_clipping_poly_structs(vorn::VoronoiTessellation, i, bounding_box) -> (Polygon, Polygon)`

Returns the polygons used for clipping the `i`

th polygon of `vorn`

to `bounding_box`

.

See also `clip_polygon`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`i`

: The index of the polygon.`bounding_box`

: The bounding box to clip the polygon to.

**Outputs**

`poly`

: The polygon to clip.`clip_poly`

: The polygon to clip to.

`DelaunayTriangulation.get_closest_point`

— Method`get_closest_point(b::AbstractParametricCurve p) -> (Float64, NTuple{2,Float64})`

Returns the `t`

-value and the associated point `q`

on the curve `b`

that is nearest to `p`

using a binary search. The search is done until the binary search interval is smaller than `1e-12`

. This function will only work if the curve `b`

has a lookup table.

This function is only tested on loop-free curves. It is not guaranteed to work on curves with loops. Moreover, for this function to be accurate, you want the lookup table in `b`

to be sufficiently dense.

`DelaunayTriangulation.get_cocircular_circumcenters`

— Method`get_cocircular_circumcenters(vorn::VoronoiTessellation) -> Set`

Gets the cocircular circumcenters of the Voronoi tessellation `vorn`

as a `Set`

of circumcenter indices. These are circumcenters that come from triangles that are cocircular with another adjoining triangle.

`DelaunayTriangulation.get_convex_hull`

— Method`get_convex_hull(tri::Triangulation) -> ConvexHull`

Returns the convex hull of the points in `tri`

. This is given as a `ConvexHull`

object, where the vertices are sorted counter-clockwise and defined so that the first and last vertices are equal.

`DelaunayTriangulation.get_convex_hull_vertices`

— Method`get_convex_hull_vertices(tri::Triangulation) -> Vector{Vertex}`

Returns the vertices on the convex hull of `tri`

, in counter-clockwise order.

See also `ConvexHull`

.

`DelaunayTriangulation.get_count`

— Method`get_count(node::Union{Nothing, BalancedBSTNode}) -> Int32`

Returns the count of `node`

. If the `node`

is `nothing`

, returns `0`

.

`DelaunayTriangulation.get_count`

— Method`get_count(tree::BalancedBST{K}) -> Int32`

`DelaunayTriangulation.get_curve_index`

— Function```
get_curve_index(dict, ghost_vertex) -> Int
get_curve_index(ghost_vertex) -> Int
```

Given a `Dict`

from `construct_ghost_vertex_map`

and a `ghost_vertex`

, returns the index of the curve corresponding to that ghost vertex. The second method maps `ghost_vertex`

to `1`

if it is an `Integer`

or a `Vector`

, and `ghost_vertex[1]`

if it is a `Tuple`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.get_curve_index(-1)
1
julia> DelaunayTriangulation.get_curve_index((5, 3))
5
julia> gv_map = DelaunayTriangulation.construct_ghost_vertex_map([[[1, 5, 17, 18, 1]], [[23, 29, 31, 33], [33, 107, 101], [101, 99, 85, 23]]])
Dict{Int64, Tuple{Int64, Int64}} with 4 entries:
-1 => (1, 1)
-3 => (2, 2)
-2 => (2, 1)
-4 => (2, 3)
julia> DelaunayTriangulation.get_curve_index(gv_map, -1)
1
julia> DelaunayTriangulation.get_curve_index(gv_map, -2)
2
julia> DelaunayTriangulation.get_curve_index(gv_map, -3)
2
julia> DelaunayTriangulation.get_curve_index(gv_map, -4)
2
```

`DelaunayTriangulation.get_curve_index`

— Method`get_curve_index(tri::Triangulation, ℓ) -> Integer`

Returns the curve index corresponding to the ghost vertex `ℓ`

in `tri`

.

`DelaunayTriangulation.get_curve_index_map`

— Method`get_curve_index_map(boundary_enricher::BoundaryEnricher{P,B,C,I}) -> Dict{I,I}`

Returns the curve index map associated with `boundary_enricher`

.

`DelaunayTriangulation.get_detached_cache`

— Method`get_detached_cache(tree::RTree) -> Vector{Union{Branch,Leaf{Branch}}}`

Returns the detached cache of `tree`

.

`DelaunayTriangulation.get_distance_to_plane`

— Method`get_distance_to_plane(a, b, c, p) -> Number`

Returns the distance from the point `p`

to the plane defined by the points `(a, b, c)`

. The distance is positive if `p`

is above the plane.

`DelaunayTriangulation.get_distance_to_witness_plane`

— Method" get*distance*to*witness*plane(tri::Triangulation, i, V) -> Float64

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.

See also `point_position_relative_to_witness_plane`

and `get_distance_to_plane`

.

`DelaunayTriangulation.get_edge`

— Method`get_edge(id_bounding_box::DiametralBoundingBox) -> NTuple{2,Int}`

Returns the generator edge of `id_bounding_box`

.

`DelaunayTriangulation.get_edge_midpoints`

— Method`get_edge_midpoints(stats::TriangulationStatistics, T)`

Returns the edge_midpoints field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_edges`

— Method`get_edges(graph::Graph) -> Set{NTuple{2, Vertex}}`

Returns the set of edges in `graph`

.

`DelaunayTriangulation.get_edges`

— Method`get_edges(tri::Triangulation) -> Set{NTuple{2,Vertex}}`

Returns the set of all edges in `tri`

. Orientation is ignored, so that only one of `(i, j)`

and `(j, i)`

will appear in the result. Note that, if `has_ghost_triangles(tri)`

, then some of these edges will be ghost edges.

See also `each_edge`

, `each_solid_edge`

, and `each_ghost_edge`

.

`DelaunayTriangulation.get_edges_for_split_edge`

— Method`get_edges_for_split_edge(tri::Triangulation, i, j, r)`

Returns the edges `(i, j)`

, `(j, i)`

, `(i, r)`

, `(r, i)`

, `(r, j)`

, and `(j, r)`

.

`DelaunayTriangulation.get_equidistant_split`

— Method`get_equidistant_split(c::AbstractParametricCurve, t₁, t₂) -> Float64`

Returns a value of `t`

such that the arc length along `c`

from `t₁`

to `t`

is equal to the arc length along `c`

from `t`

to `t₂`

. Uses the bisection method to compute the `t`

-value.

`DelaunayTriangulation.get_equidistant_split`

— Method`get_equidistant_split(enricher::BoundaryEnricher, curve_index, t₁, t₂) -> Float64`

Returns the equidistant split of the `curve_index`

th curve between `t₁`

and `t₂`

.

`DelaunayTriangulation.get_equivariation_split`

— Method`get_equivariation_split(c::AbstractParametricCurve, t₁, t₂) -> Float64, Float64`

Returns a value of `t`

such that the total variation of `c`

from `t₁`

to `t`

is equal to the total variation of `c`

from `t`

to `t₂`

. Uses the bisection method to compute the `t`

-value. Also returns the new total variation of the two pieces.

`DelaunayTriangulation.get_equivariation_split`

— Method`get_equivariation_split(enricher::BoundaryEnricher, curve_index, t₁, t₂) -> Float64, Float64`

Returns the equivariation split of the `curve_index`

th curve between `t₁`

and `t₂`

. Also returns the total variation of the two pieces.

`DelaunayTriangulation.get_exterior_curve_indices`

— Method`get_exterior_curve_indices(hierarchy::PolygonHierarchy) -> KeySet`

Returns the indices of the exterior curves of `hierarchy`

.

`DelaunayTriangulation.get_exterior_curve_indices`

— Method`get_exterior_curve_indices(tri::Triangulation) -> KeySet{Integer}`

Returns the set of all curve indices that correspond to exterior curves of `tri`

.

`DelaunayTriangulation.get_fan_triangles`

— Method`get_fan_triangles(cache::TriangulationCache) -> Triangles`

Returns the triangles in a fan stored in `cache`

.

`DelaunayTriangulation.get_fill_factor`

— Method`get_fill_factor(tree::RTree) -> Float64`

Returns the fill factor of `tree`

.

`DelaunayTriangulation.get_free_cache`

— Method`get_free_cache(tree::RTree) -> BitVector`

Returns the free cache of `tree`

.

`DelaunayTriangulation.get_generator`

— Method```
get_generator(vor::VoronoiTessellation, i) -> NTuple{2, Number}
get_generator(vor::VoronoiTessellation, i...) -> NTuple{length(i), NTuple{2, Number}}
```

Gets the coordinates for the generators `i...`

, returned as `Tuple`

s of the form `(x, y)`

for each generator.

`DelaunayTriangulation.get_generators`

— Method`get_generators(vorn::VoronoiTessellation) -> Dict{Vertex,Point}`

Gets the generators of the Voronoi tessellation `vorn`

as a `Dict`

, mapping vertices to their coordinates. These coordinates are given as `Tuple`

s of the form `(x, y)`

.

`DelaunayTriangulation.get_ghost_vertex`

— Function```
get_ghost_vertex(i, j, k) -> Vertex
get_ghost_vertex(i, j) -> Vertex
```

Given three vertices `i`

, `j`

, and `k`

, returns the ghost vertex among them. If none of them are ghost vertices, returns `k`

. The two-argument version is equivalent to `get_ghost_vertex(i, j, j)`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.get_ghost_vertex(1, 7, -2)
-2
julia> DelaunayTriangulation.get_ghost_vertex(-1, 2, 3)
-1
julia> DelaunayTriangulation.get_ghost_vertex(1, 5, 10)
10
julia> DelaunayTriangulation.get_ghost_vertex(1, -1)
-1
julia> DelaunayTriangulation.get_ghost_vertex(-5, 2)
-5
```

`DelaunayTriangulation.get_ghost_vertex_map`

— Method`get_ghost_vertex_map(tri::Triangulation) -> Dict`

Returns the ghost vertex map of the triangulation `tri`

. This is a `Dict`

that maps ghost vertices to their associated section in `boundary_nodes`

. There are three cases; below, `I`

is `integer_type(tri)`

:

`has_multiple_curves(tri)`

Returns `dict::Dict{I, NTuple{2, I}}`

, mapping ghost vertices `i`

to `Tuple`

s `(m, n)`

so that `get_boundary_nodes(tri, m, n)`

are the boundary nodes associated with `i`

, i.e. the `n`

th section of the `m`

th curve is associated with the ghost vertex `i`

.

`has_multiple_sections(tri)`

Returns `dict::Dict{I, I}`

, mapping ghost vertices `i`

to `n`

so that `get_boundary_nodes(tri, n)`

are the boundary nodes associated with `i`

, i.e. the `n`

th section of the boundary is associated with the ghost vertex `i`

.

`otherwise`

Returns `dict::Dict{I, A}`

, mapping the ghost vertex `i`

to `get_boundary_nodes(tri)`

, where `A = typeof(get_boundary_nodes(tri))`

.

See also `construct_ghost_vertex_map`

.

`DelaunayTriangulation.get_ghost_vertex_range`

— Method`get_ghost_vertex_range(tri::Triangulation, ℓ) -> UnitRange`

Given a ghost vertex `ℓ`

of `tri`

, returns the range of all ghost vertices corresponding to the same curve or section as `ℓ`

does.

`DelaunayTriangulation.get_ghost_vertex_ranges`

— Method`get_ghost_vertex_ranges(tri::Triangulation) -> Dict`

Returns the ghost vertex ranges map of the triangulation `tri`

. This is a `Dict`

that maps ghost vertices `i`

to the range of all other ghost vertices associated with the curve that `i`

is associated with.

See also `construct_ghost_vertex_ranges`

.

`DelaunayTriangulation.get_graph`

— Method`get_graph(tri::Triangulation) -> Graph`

Returns the `Graph`

of the triangulation `tri`

. This is an undirected graph.

`DelaunayTriangulation.get_height`

— Method`get_height(node::Union{Nothing, BalancedBSTNode}) -> Int8`

Returns the height of `node`

. If the `node`

is `nothing`

, returns `0`

.

`DelaunayTriangulation.get_height`

— Method`get_height(tree::PolygonTree) -> Int`

Returns the height of `tree`

.

`DelaunayTriangulation.get_height`

— Method`get_height(tree::RTree) -> Int`

Returns the height of `tree`

.

`DelaunayTriangulation.get_index`

— Method`get_index(tree::PolygonTree{I}) -> I`

Returns the index of `tree`

.

`DelaunayTriangulation.get_individual_statistics`

— Method`get_individual_statistics(stats::TriangulationStatistics)`

Returns the individual_statistics field from the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_init_for_steiner_point`

— Method`get_init_for_steiner_point(tri::Triangulation, T) -> Vertex`

Gets the initial vertex to start the search for the Steiner point of a triangle `T`

of `tri`

in `get_steiner_point`

. The initial vertex is chosen so that it is opposite the longest edge.

`DelaunayTriangulation.get_initial_search_point`

— Method`get_initial_search_point(tri::Triangulation, num_points, new_point, insertion_order, num_sample_rule::F, rng, try_last_inserted_point) where {F} -> Vertex`

For a given iteration of the Bowyer-Watson algorithm, finds the point to start the point location with `jump_and_march`

at.

**Arguments**

`tri`

: The triangulation.`num_points`

: The number of points currently in the triangulation.`new_point`

: The point to insert.`insertion_order`

: The insertion order of the points. See`get_insertion_order`

.`num_sample_rule::F`

: The rule to use to determine the number of points to sample. See`default_num_samples`

for the default.`rng::AbstractRNG`

: The random number generator to use.`try_last_inserted_point`

: If`true`

, then the last inserted point is also considered as the start point.

**Output**

`initial_search_point`

: The vertex to start the point location with`jump_and_march`

at.

`DelaunayTriangulation.get_initial_triangle`

— Function`get_initial_triangle(tri::Triangulation, insertion_order, itr=0) -> Triangle`

Gets the initial triangle for the Bowyer-Watson algorithm.

**Arguments**

`tri`

: The triangulation.`insertion_order`

: The insertion order of the points. See`get_insertion_order`

.`itr=0`

: To avoid issues with degenerate triangles and infinite loops, this counts the number of times`insertion_order`

had to be shifted using`circshift!`

to find an initial non-degenerate triangle.

**Output**

`initial_triangle`

: The initial triangle.

`DelaunayTriangulation.get_inradius`

— Method`get_inradius(stats::TriangulationStatistics, T)`

Returns the inradius field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_insertion_order`

— Method```
get_insertion_order(points, randomise, skip_points, ::Type{I}, rng) where {I} -> Vector{I}
get_insertion_order(tri::Triangulation, randomise, skip_points, rng) -> Vector{I}
```

Gets the insertion order for points into a triangulation.

**Arguments**

`points`

: The points to insert.`randomise`

: If`true`

, then the insertion order is randomised. Otherwise, the insertion order is the same as the order of the points.`skip_points`

: The points to skip.`I::Type{I}`

: The type of the vertices.`rng::AbstractRNG`

: The random number generator to use.

**Output**

`order`

: The order to insert the points in.

This `order`

might be mutated (by `circshift!`

) in `get_initial_triangle`

.

`DelaunayTriangulation.get_interior_segments`

— Method`get_interior_segments(tri::Triangulation) -> Edges`

Return the interior segments of the triangulation. These are segments that are forced to be in the triangulation - they are not the same as edges.

`DelaunayTriangulation.get_interior_segments_on_hull`

— Method`get_interior_segments_on_hull(cache::TriangulationCache) -> Set{Edge}`

Returns the interior segments on the convex hull of the triangulation stored in `cache`

.

`DelaunayTriangulation.get_intersection_cache`

— Method`get_intersection_cache(tree::RTree) -> NTuple{2,RTreeIntersectionCache}`

Returns the intersection cache of `tree`

.

`DelaunayTriangulation.get_intersections`

— Method`get_intersections(tree::BoundaryRTree, i, j, k; cache_id=1) -> RTreeIntersectionIterator`

Returns an `RTreeIntersectionIterator`

over the elements in `tree`

that intersect with the bounding box of the triangle `(i, j, k)`

. `cache_id`

must be `1`

or `2`

, and determines what cache to use for the intersection query.

`DelaunayTriangulation.get_intersections`

— Method`get_intersections(tree::BoundaryRTree, i, j; cache_id=1) -> RTreeIntersectionIterator`

Returns an `RTreeIntersectionIterator`

over the elements in `tree`

that intersect with the diametral circle of the edge between `i`

and `j`

. `cache_id`

must be `1`

or `2`

, and determines what cache to use for the intersection query.

`DelaunayTriangulation.get_intersections`

— Method`get_intersections(tree::BoundaryRTree, i; cache_id=1) -> RTreeIntersectionIterator`

Returns an `RTreeIntersectionIterator`

over the elements in `tree`

that intersect with the `i`

th vertex. `cache_id`

must be `1`

or `2`

, and determines what cache to use for the intersection query.

`DelaunayTriangulation.get_intersections`

— Method`get_intersections(tree::BoundaryRTree, bbox::BoundingBox; cache_id=1) -> RTreeIntersectionIterator`

Returns an `RTreeIntersectionIterator`

over the elements in `tree`

that intersect with `bbox`

. `cache_id`

must be `1`

or `2`

, and determines what cache to use for the intersection query.

`DelaunayTriangulation.get_intersections`

— Method`get_intersections(tree::RTree, bounding_box::BoundingBox; cache_id=1) -> RTreeIntersectionIterator`

Returns an `RTreeIntersectionIterator`

over the elements in `tree`

that intersect with `bounding_box`

. `cache_id`

must be `1`

or `2`

, and determines what cache to use for the intersection query.

`DelaunayTriangulation.get_intersections`

— Method`get_intersections(tree::RTree, point::NTuple{2,<:Number}; cache_id=1) -> RTreeIntersectionIterator`

Returns an `RTreeIntersectionIterator`

over the elements in `tree`

that intersect with `point`

, representing `point`

as a `BoundingBox`

with zero width and height centered at `point`

. `cache_id`

must be `1`

or `2`

, and determines what cache to use for the intersection query.

`DelaunayTriangulation.get_inverse`

— Method`get_inverse(c::AbstractParametricCurve, p) -> Float64`

Given a point `p`

on `c`

, returns the `t`

-value such that `c(t) ≈ p`

.

`DelaunayTriangulation.get_inverse`

— Method`get_inverse(enricher::BoundaryEnricher, curve_index, q) -> Float64`

Returns the inverse of the `curve_index`

th curve at `q`

.

`DelaunayTriangulation.get_key`

— Method`get_key(node::BalancedBSTNode{K}) -> K`

Returns the key associated with `node`

.

`DelaunayTriangulation.get_largest_angle`

— Method`get_largest_angle(stats::TriangulationStatistics)`

Returns the largest_angle field from the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_largest_area`

— Method`get_largest_area(stats::TriangulationStatistics)`

Returns the largest_area field from the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_largest_radius_edge_ratio`

— Method`get_largest_radius_edge_ratio(stats::TriangulationStatistics)`

Returns the largest*radius*edge_ratio field from the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_leaf_cache`

— Method`get_leaf_cache(tree::RTree) -> LeafCache`

Returns the leaf cache of `tree`

.

`DelaunayTriangulation.get_left`

— Method`get_left(node::BalancedBSTNode) -> Union{Nothing, BalancedBSTNode}`

Returns the left child of `node`

. If the `node`

is `nothing`

, returns `nothing`

.

`DelaunayTriangulation.get_left_boundary_node`

— Method`get_left_boundary_node(tri::Triangulation, k, ghost_vertex) -> Vertex`

Returns the boundary node to the left of the vertex `k`

in `tri`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`k`

: The boundary vertex.`ghost_vertex`

: The ghost vertex associated with the boundary section that`k`

is on.

**Outputs**

`ℓ`

: The vertex left of`k`

on the boundary.

`DelaunayTriangulation.get_lengths`

— Method`get_lengths(stats::TriangulationStatistics, T)`

Returns the lengths field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_level`

— Function`get_level(node::AbstractNode) -> Int`

Returns the level of `node`

. If `node`

is a leaf, returns `1`

.

`DelaunayTriangulation.get_lifted_point`

— Method`get_lifted_point(p, w) -> Tuple{Float64, Float64, Float64}`

Returns the lifted companion of the point `p`

, in particular `(x, y, x^2 + y^2 - w)`

, where `(x, y)`

is `p`

.

`DelaunayTriangulation.get_lifted_point`

— Method`get_lifted_point(tri::Triangulation, i) -> Tuple{Float64, Float64, Float64}`

Returns the lifted companion of the `i`

th vertex of `tri`

, in particular `(x, y, x^2 + y^2 - w)`

, where `w`

is the `i`

th weight of `tri`

and `(x, y)`

is the `i`

th point of `tri`

.

`DelaunayTriangulation.get_marked_vertices`

— Method`get_marked_vertices(cache::TriangulationCache) -> Vector{Vertex}`

Returns the marked vertices stored in `cache`

.

`DelaunayTriangulation.get_maximum_angle`

— Method`get_maximum_angle(stats::TriangulationStatistics, T) -> Float64`

Returns the maximum angle of `T`

from `stats`

.

`DelaunayTriangulation.get_median_angle`

— Method`get_median_angle(stats::TriangulationStatistics, T) -> Float64`

Returns the median angle of `T`

from `stats`

.

`DelaunayTriangulation.get_members`

— Method`get_members(complex::SmallAngleComplex{I}) where {I} -> Vector{SmallAngleComplexMember{I}}`

Returns the members of `complex`

.

`DelaunayTriangulation.get_min_nodes`

— Method`get_min_nodes(tree::RTree) -> Int`

Returns the minimum number of nodes that a node in `tree`

can have.

`DelaunayTriangulation.get_minimum_angle`

— Method`get_minimum_angle(stats::TriangulationStatistics, T) -> Float64`

Returns the minimum angle of `T`

from `stats`

.

`DelaunayTriangulation.get_minimum_edge_length`

— Method`get_minimum_edge_length(complex::SmallAngleComplex, points) -> Float64`

Returns the minimum edge length in `complex`

with respect to `points`

.

`DelaunayTriangulation.get_nearest_neighbour`

— Function`get_nearest_neighbour(tri_or_vor, q; kwargs...)`

Get the index of the nearest neighbour of `q`

in `tri_or_vor`

.

**Arguments**

`tri_or_vor`

: A`Triangulation`

or`VoronoiTessellation`

.`q`

: The point to be located.

**Keyword Arguments**

`kwargs...`

: Keyword arguments passed to`jump_and_march`

.

**Output**

`i`

: The index of the nearest neighbour. This is a point of the triangulation if`tri_or_vor`

is a`Triangulation`

or of a generator if`tri_or_vor`

is a`VoronoiTessellation`

.

`DelaunayTriangulation.get_need_tests`

— Method`get_need_tests(cache::RTreeIntersectionCache) -> BitVector`

Returns the `need_tests`

cache of `tree`

.

`DelaunayTriangulation.get_neighbouring_boundary_edges`

— Method`get_neighbouring_boundary_edges(tri::Triangulation, e) -> (Edge, Edge)`

Returns the two boundary edges adjacent to the boundary edge `e`

in the triangulation `tri`

.

**Arguments**

`tri::Triangulation`

: a triangulation`e`

: The boundary edge.

**Outputs**

`left_e`

: The left edge.`right_e`

: The right edge.

`DelaunayTriangulation.get_neighbouring_boundary_edges`

— Method`get_neighbouring_boundary_edges(vorn::VoronoiTessellation, e) -> (Edge, Edge)`

Given a boundary edge `e`

, returns the edges left and right of `e`

.

`DelaunayTriangulation.get_neighbours`

— Method`get_neighbours(G::Graph, u) -> Set{Vertex}`

Returns the set of neighbours of `u`

in `G`

.

`DelaunayTriangulation.get_neighbours`

— Method`get_neighbours(graph::Graph) -> Dict{Vertex, Set{Vertex}}`

Returns the `neighbours`

map of `graph`

.

`DelaunayTriangulation.get_neighbours`

— Method`get_neighbours(tri::Triangulation, u) -> Set{Vertex}`

Returns the set of neighbours of `u`

in `tri`

. Note that, if `has_ghost_triangles(tri)`

, then some of the neighbours and vertices will be ghost vertices.

`DelaunayTriangulation.get_neighbours`

— Method`get_neighbours(tri::Triangulation) -> Dict{Vertex, Set{Vertex}}`

Returns the `neighbours`

map of `tri`

. Note that, if `has_ghost_triangles(tri)`

, then some of the neighbours and vertices will be ghost vertices.

`DelaunayTriangulation.get_new_polygon_indices`

— Method`get_new_polygon_indices(vorn, vertices) -> (Vector{Int}, Vector{NTuple{2,Float64}}, Tuple{Int, Int})`

Returns the new vertices and points of the polygon, as well as the indices of the ghost vertices in the polygon.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`vertices`

: The vertices of the polygon.

**Outputs**

`new_vertices`

: The new vertices of the polygon. This is not a circular vector. The vertices corresponding to a ghost vertex will be given by the ghost vertex itself.`new_points`

: The new points of the polygon. This is not a circular vector. The points corresponding to a ghost vertex will be given by by`(NaN, NaN)`

.`ghost_vertices`

: The indices of the ghost vertices in`new_vertices`

.

`DelaunayTriangulation.get_next_cell!`

— Method`get_next_cell!(queue::CellQueue)`

Returns the next cell in the queue.

`DelaunayTriangulation.get_next_child`

— Method`get_next_child(node::AbstractNode, start_idx, need_tests, itr::RTreeIntersectionIterator) -> Int, QueryResult`

Returns the index of the next child of `node`

that intersects with the bounding box in `itr`

and the `QueryResult`

of the intersection.

`DelaunayTriangulation.get_next_edge`

— Method`get_next_edge(member::SmallAngleComplexMember{I}) where {I} -> I`

Returns the next edge of `member`

.

`DelaunayTriangulation.get_next_triangle_for_voronoi_polygon`

— Method`get_next_triangle_for_voronoi_polygon(vorn::VoronoiTessellation, i, k, S, m) -> (Vertex, Vertex)`

Get the next triangle for the Voronoi polygon for the point `i`

in the `VoronoiTessellation`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`i`

: The polygon index.`k`

: The vertex to add.`S`

: The surrounding polygon of`i`

. See`get_surrounding_polygon`

.`m`

: The index of the next vertex in`S`

.

**Outputs**

`ci`

: The index for the circumcenter of the next triangle.`k`

: The next vertex in`S`

after the input`k`

.

`DelaunayTriangulation.get_node_indices`

— Method`get_node_indices(cache::RTreeIntersectionCache) -> Vector{Int}`

Returns the node indices of `cache`

.

`DelaunayTriangulation.get_offcenter`

— Method`get_offcenter(stats::TriangulationStatistics, T)`

Returns the offcenter field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_ordinal_suffix`

— Method`get_ordinal_suffix(i) -> String`

Returns the ordinal suffix for the integer `i`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.get_ordinal_suffix(1)
"st"
julia> DelaunayTriangulation.get_ordinal_suffix(2)
"nd"
julia> DelaunayTriangulation.get_ordinal_suffix(3)
"rd"
julia> DelaunayTriangulation.get_ordinal_suffix(4)
"th"
julia> DelaunayTriangulation.get_ordinal_suffix(5)
"th"
julia> DelaunayTriangulation.get_ordinal_suffix(6)
"th"
julia> DelaunayTriangulation.get_ordinal_suffix(11)
"th"
julia> DelaunayTriangulation.get_ordinal_suffix(15)
"th"
julia> DelaunayTriangulation.get_ordinal_suffix(100)
"th"
```

`DelaunayTriangulation.get_parent`

— Method`get_parent(node::AbstractNode) -> Union{Branch, Nothing}`

Returns the parent of `node`

.

`DelaunayTriangulation.get_parent`

— Method`get_parent(node::BalancedBSTNode) -> Union{Nothing, BalancedBSTNode}`

Returns the parent of `node`

. If the `node`

is `nothing`

, returns `nothing`

.

`DelaunayTriangulation.get_parent`

— Method`get_parent(tree::PolygonTree) -> Union{Nothing,PolygonTree}`

Returns the parent of `tree`

.

`DelaunayTriangulation.get_parent`

— Method`get_parent(boundary_enricher::BoundaryEnricher{P,B,C,I}, i::I, j::I) -> I`

Returns the parent of the edge `(i, j)`

in `boundary_enricher`

. If the edge is not in the parent map, then `0`

is returned.

`DelaunayTriangulation.get_parent_curve`

— Method`get_parent_curve(member::SmallAngleComplexMember{I}) where {I} -> I`

Returns the parent curve of `member`

.

`DelaunayTriangulation.get_parent_map`

— Method`get_parent_map(boundary_enricher::BoundaryEnricher{P,B,C,I}) -> Dict{NTuple{2,I},I}`

Returns the parent map associated with `boundary_enricher`

.

`DelaunayTriangulation.get_perimeter`

— Method`get_perimeter(stats::TriangulationStatistics, T)`

Returns the perimeter field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_plane_through_three_points`

— Method`get_plane_through_three_points(a, b, c) -> NTuple{4, Number}`

Given three points `(a, b, c)`

in `ℝ³`

represented as `Tuple`

s, computes the equation of the plane through the points. The result is given in the form `(α, β, γ, δ)`

, so that the plane is given by

`αx + βy + γz + δ = 0.`

**Extended help**

The equation of the plane is computed by expanding the equation

\[\det \begin{bmatrix} x & y & z & 1 \\ a_x & a_y & a_z & 1 \\ b_x & b_y & b_z & 1 \\ c_x & c_y & c_z & 1 \end{bmatrix} = 0.\]

From this, we find:

\[\begin{align*} \alpha &= a_y b_z - a_z b_y - a_y c_z + a_z c_y + b_y c_z - b_z c_y, \\ \beta &= a_z b_x - a_x b_z + a_x c_z - a_z c_x - b_x c_z + b_z c_x, \\ \gamma &= a_x b_y - a_y b_x - a_x c_y + a_y c_x + b_x c_y - b_y c_x, \\ \delta &= a_x b_z c_y - a_x b_y c_z + a_y b_x c_z - a_y b_z c_x - a_z b_x c_y + a_z b_y c_x. \end{align*}\]

`DelaunayTriangulation.get_point`

— Function`get_point(points, vertices...) -> NTuple{length(vertices), NTuple{2, Number}}`

Get the points associated with `vertices`

in `points`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [(1.0, 2.0), (3.0, 5.5), (1.7, 10.3), (-5.0, 0.0)];
julia> get_point(points, 1)
(1.0, 2.0)
julia> get_point(points, 1, 2, 3, 4)
((1.0, 2.0), (3.0, 5.5), (1.7, 10.3), (-5.0, 0.0))
julia> points = [1.0 3.0 1.7 -5.0; 2.0 5.5 10.3 0.0];
julia> get_point(points, 1)
(1.0, 2.0)
julia> get_point(points, 1, 2, 3, 4)
((1.0, 2.0), (3.0, 5.5), (1.7, 10.3), (-5.0, 0.0))
julia> typeof(ans)
NTuple{4, Tuple{Float64, Float64}}
```

`DelaunayTriangulation.get_point`

— Method```
get_point(tri::Triangulation, i) -> NTuple{2, Number}
get_point(tri::Triangulation, i...) -> NTuple{length(i), NTuple{2, Number}}
```

Returns the coordinates corresponding to the vertices `i...`

of `tri`

, given as a `Tuple`

of the form `(x, y)`

for each point. If `i`

is a ghost vertex, then the coordinates of the representative point of the curve associated with `i`

are returned instead.

`DelaunayTriangulation.get_points`

— Method`get_points(convex_hull::ConvexHull) -> Points`

Returns the underlying point set of `convex_hull`

.

`DelaunayTriangulation.get_points`

— Method`get_points(boundary_enricher::BoundaryEnricher{P}) -> P`

Returns the point set associated with `boundary_enricher`

.

`DelaunayTriangulation.get_points`

— Method`get_points(tri::Triangulation) -> Points`

Return the points of the triangulation. Note that this may include points not yet in `tri`

.

`DelaunayTriangulation.get_polygon`

— Method`get_polygon(vor::VoronoiTessellation, i) -> Vector{Vertex}`

Gets the vector of vertices corresponding to the `i`

th polygon, given in counter-clockwise order and with the first and last vertices equal. To obtain the coordinates, see `get_polygon_point`

.

`DelaunayTriangulation.get_polygon_coordinates`

— Function`get_polygon_coordinates(vorn::VoronoiTessellation, i, bounding_box=nothing) -> Vector{NTuple{2,Number}}`

Returns the coordinates of the polygon with index `i`

in `vorn`

. If `bounding_box`

is provided, then the polygon is clipped to the bounding box. If the polygon is unbounded, then `bounding_box`

must be provided.

See also `get_unbounded_polygon_coordinates`

and `get_bounded_polygon_coordinates`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`i`

: The index of the polygon.`bounding_box=nothing`

: The bounding box to clip the polygon to. If`nothing`

, then the polygon is not clipped. If the polygon is unbounded, then`bounding_box`

must be provided.

**Outputs**

`coords`

: The coordinates of the polygon. This is a circular vector.

`DelaunayTriangulation.get_polygon_hierarchy`

— Method`get_polygon_hierarchy(boundary_enricher::BoundaryEnricher{P,B,C,I}) -> PolygonHierarchy{I}`

Returns the polygon hierarchy associated with `boundary_enricher`

.

`DelaunayTriangulation.get_polygon_hierarchy`

— Method`get_polygon_hierarchy(tri::Triangulation) -> PolygonHierarchy`

Returns the `PolygonHierarchy`

of the boundary of `tri`

. This defines the hierarchy of the boundary curves, giving information about which curves are contained in which other curves.

`DelaunayTriangulation.get_polygon_orientation`

— Method`get_polygon_orientation(hierarchy::PolygonHierarchy, index) -> Bool`

Returns the polygon orientation of the `index`

th polygon in `hierarchy`

.

`DelaunayTriangulation.get_polygon_orientations`

— Method`get_polygon_orientations(hierarchy::PolygonHierarchy) -> BitVector`

Returns the polygon orientations of `hierarchy`

.

`DelaunayTriangulation.get_polygon_point`

— Method```
get_polygon_point(vor::VoronoiTessellation, i) -> NTuple{2, Number}
get_polygon_point(vor::VoronoiTessellation, i...) -> NTuple{length(i), NTuple{2, Number}}
```

Gets the coordinates corresponding to the vertices `i...`

of the polygons, returned as `Tuple`

s of the form `(x, y)`

for each vertex.

`DelaunayTriangulation.get_polygon_points`

— Method`get_polygon_points(vorn::VoronoiTessellation) -> Vector{Point}`

Gets the polygon points of the Voronoi tessellation `vorn`

. These are the vertices of the Voronoi polygons, and are given as `Tuple`

s of the form `(x, y)`

.

`DelaunayTriangulation.get_polygons`

— Method`get_polygons(vorn::VoronoiTessellation) -> Dict{Index,Vector{Vertex}}`

Gets the polygons of the Voronoi tessellation `vorn`

as a `Dict`

, mapping polygon indices to their vertices, where the vertices refer to points in `get_polygon_points(vorn)`

. The vertices are given in counter-clockwise order and the first and last vertices are equal.

`DelaunayTriangulation.get_power_distance`

— Method`get_power_distance(tri::Triangulation, i, j) -> Float64`

Returns the power distance between vertices `i`

and `j`

, defined by `||pᵢ - pⱼ||^2 - wᵢ - wⱼ`

, where `wᵢ`

and `wⱼ`

are the respective weights.

`DelaunayTriangulation.get_queue`

— Method`get_queue(boundary_enricher::BoundaryEnricher{P,B,C,I}) -> Queue{I}`

Returns the queue associated with `boundary_enricher`

.

`DelaunayTriangulation.get_radius_edge_ratio`

— Method`get_radius_edge_ratio(stats::TriangulationStatistics, T)`

Returns the radius*edge*ratio field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_reorder_cache`

— Method`get_reorder_cache(hierarchy::PolygonHierarchy) -> Vector{PolygonTree{I}}`

Returns the reorder cache of `hierarchy`

.

`DelaunayTriangulation.get_representative_point_coordinates`

— Method`get_representative_point_coordinates(tri::Triangulation, curve_index) -> NTuple{2, Number}`

Returns the coordinates of the representative point of the `curve_index`

th curve in `tri`

.

`DelaunayTriangulation.get_representative_point_list`

— Method`get_representative_point_list(tri::Triangulation) -> Dict`

Returns the `Dict`

of `RepresentativeCoordinates`

of `tri`

, mapping curve indices `i`

to the representative point for that curve. These representative points are how we interpret ghost triangles relative to that curve.

`DelaunayTriangulation.get_right`

— Method`get_right(node::BalancedBSTNode) -> Union{Nothing, BalancedBSTNode}`

Returns the right child of `node`

. If the `node`

is `nothing`

, returns `nothing`

.

`DelaunayTriangulation.get_right_boundary_node`

— Method`get_right_boundary_node(tri::Triangulation, k, ghost_vertex) -> Vertex`

Returns the boundary node to the right of the vertex `k`

in `tri`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`k`

: The boundary vertex.`ghost_vertex`

: The ghost vertex associated with the boundary section that`k`

is on.

**Outputs**

`r`

: The vertex right of`k`

on the boundary.

`DelaunayTriangulation.get_root`

— Method`get_root(tree::BalancedBST{K}) -> Union{Nothing,BalancedBSTNode{K}}`

Returns the root of `tree`

. If `tree`

is empty, returns `nothing`

.

`DelaunayTriangulation.get_root`

— Method`get_root(tree::RTree) -> Union{Branch,Leaf{Branch}}`

Returns the root of `tree`

.

`DelaunayTriangulation.get_section_index`

— Function```
get_section_index(dict, ghost_vertex) -> Int
get_section_index(ghost_vertex) -> Int
```

Given a `Dict`

from `construct_ghost_vertex_map`

and a `ghost_vertex`

, returns the index of the section corresponding to that ghost vertex. The second method maps `ghost_vertex`

to itself if it is an `Integer`

, `1`

if it is a `Vector`

, and `ghost_vertex[2]`

if it is a `Tuple`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.get_section_index((2, 3)) # 3rd section of the 2nd curve
3
julia> DelaunayTriangulation.get_section_index(4)
4
julia> DelaunayTriangulation.get_section_index([1, 2, 3, 4, 5, 1])
1
julia> gv_map = DelaunayTriangulation.construct_ghost_vertex_map([[[1, 5, 17, 18, 1]], [[23, 29, 31, 33], [33, 107, 101], [101, 99, 85, 23]]])
Dict{Int64, Tuple{Int64, Int64}} with 4 entries:
-1 => (1, 1)
-3 => (2, 2)
-2 => (2, 1)
-4 => (2, 3)
julia> DelaunayTriangulation.get_section_index(gv_map, -1)
1
julia> DelaunayTriangulation.get_section_index(gv_map, -2)
1
julia> DelaunayTriangulation.get_section_index(gv_map, -3)
2
julia> DelaunayTriangulation.get_section_index(gv_map, -4)
3
```

`DelaunayTriangulation.get_section_index`

— Method`get_section_index(tri::Triangulation, ℓ) -> Integer`

Returns the section index corresponding to the ghost vertex `ℓ`

in `tri`

.

`DelaunayTriangulation.get_segment`

— Method`get_segment(c::CatmullRomSpline, t) -> (CatmullRomSplineSegment, Int)`

Returns the `CatmullRomSplineSegment`

of the `CatmullRomSpline`

`c`

that contains the point at `t`

. Also returns the segment index.

`DelaunayTriangulation.get_segments`

— Method`get_segments(boundary_enricher::BoundaryEnricher{P,B,C,I,BM,S}) -> S`

Returns the segments associated with `boundary_enricher`

.

`DelaunayTriangulation.get_shared_vertex`

— Method`get_shared_vertex(e, f) -> Vertex`

Returns the vertex shared by the edges `e`

and `f`

, or `∅`

if they do not share a vertex.

**Arguments**

`e`

: The first edge.`f`

: The second edge.

**Outputs**

`u`

: The shared vertex.

**Example**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.get_shared_vertex((1, 3), (5, 7))
0
julia> DelaunayTriangulation.get_shared_vertex((1, 3), (3, 7))
3
julia> DelaunayTriangulation.get_shared_vertex((10, 3), (10, 5))
10
julia> DelaunayTriangulation.get_shared_vertex((9, 4), (9, 5))
9
```

`DelaunayTriangulation.get_sink`

— Method`get_sink(stats::TriangulationStatistics, T)`

Returns the sink field from the individual triangle statistics for the triangle `T`

in the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_size_limit`

— Method`get_size_limit(cache::NodeCache) -> Int`

Returns the size limit of `cache`

.

`DelaunayTriangulation.get_size_limit`

— Method`get_size_limit(tree::RTree) -> Int`

Returns the size limit of `tree`

.

`DelaunayTriangulation.get_skeleton`

— Method`get_skeleton(boundary_nodes, IntegerType) -> empty(boundary_nodes)`

Given a set of boundary nodes, returns the empty skeleton of the boundary nodes. This is essentially `empty`

applied to `boundary_nodes`

, but with vertices of type `IntegerType`

. This is mainly needed for `convert_boundary_curves!`

. You will need to implement a new method for this if you want your custom boundary node interface to be supported for curve-bounded domains.

`DelaunayTriangulation.get_small_angle_complexes`

— Function`get_small_angle_complexes(points, boundary_nodes, boundary_curves, segments=nothing; IntegerType=Int) -> Dict{IntegerType,Vector{SmallAngleComplex{IntegerType}}}`

Returns a map from an apex vertex to a list of all curves that define a small angle complex associated with that apex vertex.

`DelaunayTriangulation.get_small_angle_complexes`

— Method`get_small_angle_complex(boundary_enricher::BoundaryEnricher, apex) -> Vector{SmallAngleComplex}`

Returns the small angle complexes in `boundary_enricher`

associated with `apex`

.

`DelaunayTriangulation.get_small_angle_complexes`

— Method`get_small_angle_complexes(boundary_enricher::BoundaryEnricher{P,B,C,I}) -> Dict{I,Vector{SmallAngleComplex{I}}}`

Returns the small angle complexes associated with `boundary_enricher`

.

`DelaunayTriangulation.get_smallest_angle`

— Method`get_smallest_angle(stats::TriangulationStatistics)`

Returns the smallest_angle field from the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_smallest_area`

— Method`get_smallest_area(stats::TriangulationStatistics)`

Returns the smallest_area field from the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_smallest_radius_edge_ratio`

— Method`get_smallest_radius_edge_ratio(stats::TriangulationStatistics)`

Returns the smallest*radius*edge_ratio field from the `TriangulationStatistics`

`stats`

.

`DelaunayTriangulation.get_spatial_tree`

— Method`get_spatial_tree(boundary_enricher::BoundaryEnricher{P,B,C,I}) -> RTree`

Returns the spatial tree associated with `boundary_enricher`

.

`DelaunayTriangulation.get_state`

— Method`get_state(state::RTreeIntersectionIteratorState) -> DiametralBoundingBox`

Returns the current element in `state`

.

`DelaunayTriangulation.get_steepest_descent_direction`

— Method`get_steepest_descent_direction(a, b, c) -> NTuple{2, Number}`

Given three points in `ℝ³`

defining a plane, returns the direction `(x, y)`

of the steepest descent along the plane. In particular, if

`αx + βy + γz + δ = 0`

is the plane, then the steepest descent direction is `(α, β)/γ`

. The returned value is given by `(x, y) = sign(γ)(α, β)`

.

See also `get_plane_through_three_points`

.

`DelaunayTriangulation.get_steiner_point`

— Method`get_steiner_point(tri::Triangulation, args::RefinementArguments, T) -> Certificate, Point`

Computes the Steiner point for a triangle `T`

of `tri`

to improve its quality in `split_triangle!`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

to split a triangle of.`args::RefinementArguments`

: The`RefinementArguments`

for the refinement.`T`

: The triangle to split.

**Output**

`precision_flag`

: A`Certificate`

which is`Cert.PrecisionFailure`

if the Steiner point could not be computed due to precision issues, and`Cert.None`

otherwise.`c`

: The Steiner point. If`is_precision_failure(precision_flag)`

, then this is just an arbitrary point of`T`

to ensure type stability.

`DelaunayTriangulation.get_surrounding_polygon`

— Method`get_surrounding_polygon(cache::TriangulationCache) -> Vector{Vertex}`

Returns the polygon surrounding the triangulation stored in `cache`

.

`DelaunayTriangulation.get_surrounding_polygon`

— Method`get_surrounding_polygon(tri::Triangulation, u; skip_ghost_vertices=false) -> Vector`

Returns the counter-clockwise sequence of neighbours of `u`

in `tri`

.

**Arguments**

`tri::Triangulation`

:`Triangulation`

.`u`

: The vertex.

**Keyword Arguments**

`skip_ghost_vertices=false`

: Whether to skip ghost vertices in the returned polygon.

**Outputs**

`S`

: The surrounding polygon. This will not be circular, meaning`S[begin] ≠ S[end]`

. In case`u`

is an exterior ghost vertex, the returned polygon is a clockwise list of vertices for the associated boundary curve. If you do not have ghost triangles and you try to get the surrounding polygon of a boundary vertex, then this function may return an invalid polygon.

`DelaunayTriangulation.get_surrounding_polygon`

— Method`get_surrounding_polygon(vor::VoronoiTessellation, i) -> Vector{Vertex}`

Gets the polygon surrounding the generator with index `i`

in `vor`

.

You shouldn't need to use this, see `get_polygon`

instead.

`DelaunayTriangulation.get_tr_corner`

— Method`get_tr_corner(r::BoundingBox) -> NTuple{2,Float64}`

Returns the top-right corner of `r`

.

`DelaunayTriangulation.get_tree`

— Method`get_tree(hierarchy::PolygonHierarchy, index) -> PolygonTree{I}`

Returns the `PolygonTree`

of the `index`

th polygon in `hierarchy`

. The `index`

must be associated with an exterior polygon.

`DelaunayTriangulation.get_trees`

— Method`get_trees(hierarchy::PolygonHierarchy) -> Dict{I,PolygonTree{I}}`

Returns the trees of `hierarchy`

, mapping the index of an exterior polygon to its `PolygonTree`

.

`DelaunayTriangulation.get_triangle_to_circumcenter`

— Method`get_triangle_to_circumcenter(vor::VoronoiTessellation, T) -> Index`

Gets the circumcenter index associated with the triangle `T`

. The triangle should be sorted so that the minimum vertex is last.

`DelaunayTriangulation.get_triangle_to_circumcenter`

— Method`get_triangle_to_circumcenter(vorn::VoronoiTessellation) -> Dict{Triangle,Index}`

Gets the triangles of the Voronoi tessellation `vorn`

as a `Dict`

, mapping triangle indices to their corresponding circumcenters. The circumcenters are given as their vertices, referring to points in `get_polygon_points(vorn)`

.

`DelaunayTriangulation.get_triangles`

— Method`get_triangles(tri::Triangulation) -> Triangles`

Return the triangles of the triangulation. These triangles are all given in counter-clockwise order, and may include ghost triangles.

`DelaunayTriangulation.get_triangulation`

— Method`get_triangulation(cache::TriangulationCache) -> Triangulation`

Returns the `Triangulation`

stored in `cache`

.

`DelaunayTriangulation.get_triangulation`

— Method`get_triangulation(vorn::VoronoiTessellation) -> Triangulation`

Gets the underlying triangulation of the Voronoi tessellation `vorn`

.

`DelaunayTriangulation.get_triangulation_2`

— Method`get_triangulation_2(cache::TriangulationCache) -> Triangulation`

Returns the second `Triangulation`

stored in `cache`

.

`DelaunayTriangulation.get_triplet`

— Method`get_triplet(list::ShuffledPolygonLinkedList, i) -> (Vertex, Vertex, Vertex)`

Returns `(u, v, w) = (S[πᵢ], S[next[πᵢ]], S[prev[πᵢ]])`

, where `πᵢ = list.shuffled_indices[i]`

and `S = list.S`

.

`DelaunayTriangulation.get_twig_cache`

— Method`get_twig_cache(tree::RTree) -> TwigCache`

Returns the twig cache of `tree`

.

`DelaunayTriangulation.get_unbounded_polygon_coordinates`

— Method`get_unbounded_polygon_coordinates(vorn::VoronoiTessellation, i, bounding_box) -> Vector{NTuple{2,Number}}`

Returns the coordinates of the `i`

th polygon of `vorn`

, clipped to `bounding_box`

. The polygon is assumed to be unbounded.

`DelaunayTriangulation.get_unbounded_polygons`

— Method`get_unbounded_polygons(vorn::VoronoiTessellation) -> Set{Index}`

Gets the unbounded polygons of the Voronoi tessellation `vorn`

as a `Set`

of polygon indices.

`DelaunayTriangulation.get_vertical_distance_to_plane`

— Method`get_vertical_distance_to_plane(a, b, c, p) -> Number`

Returns the vertical distance from the point `p`

to the plane defined by the points `(a, b, c)`

. The distance is positive if `p`

is above the plane.

`DelaunayTriangulation.get_vertices`

— Method`get_vertices(convex_hull::ConvexHull) -> Vector{Vertices}`

Returns the vertices of `convex_hull`

. These are given in counter-clockwise order, and are defined so that the first and last vertices and equal.

`DelaunayTriangulation.get_vertices`

— Method`get_vertices(graph::Graph) -> Set{Vertex}`

Returns the set of vertices in `graph`

.

`DelaunayTriangulation.get_vertices`

— Method`get_vertices(tri::Triangulation) -> Set{Vertex}`

Returns the set of all vertices in `tri`

. Note that, if `has_ghost_triangles(tri)`

, then some of these vertices will be ghost vertices.

See also `each_vertex`

, `each_solid_vertex`

, and `each_ghost_vertex`

.

`DelaunayTriangulation.get_weight`

— Method`get_weight(weights, i) -> Float64`

Gets the `i`

th weight from `weights`

. The default definition for this is `weights[i]`

, but this can be extended - e.g., `ZeroWeight`

uses `get_weight(weights, i) = 0.0`

.

`DelaunayTriangulation.get_weight`

— Method`get_weight(tri::Triangulation, i) -> Number`

Gets the `i`

th weight from `tri`

.

`DelaunayTriangulation.get_weighted_nearest_neighbour`

— Function`get_weighted_nearest_neighbour(tri::Triangulation, i, j = rand(each_solid_vertex(tri))) -> Vertex`

Using a greedy search, finds the closest vertex in `tri`

to the vertex `i`

(which might not already be in `tri`

), measuring distance in lifted space (i.e., using the power distance - see `get_power_distance`

). The search starts from the vertex `j`

which should be in `tri`

.

`DelaunayTriangulation.get_weights`

— Method`get_weights(tri::Triangulation) -> Weights`

Return the weights of the triangulation. These are the weights of the vertices of the triangulation.

`DelaunayTriangulation.geti`

— Method`geti(T) -> Vertex`

Get the first vertex of `T`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.geti((1, 2, 3))
1
julia> DelaunayTriangulation.geti([2, 5, 1])
2
```

`DelaunayTriangulation.getj`

— Method`getj(T) -> Vertex`

Get the second vertex of `T`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.getj((5, 6, 13))
6
julia> DelaunayTriangulation.getj([10, 19, 21])
19
```

`DelaunayTriangulation.getk`

— Method`getk(T) -> Vertex`

Get the third vertex of `T`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.getk((1,2,3))
3
julia> DelaunayTriangulation.getk([1,2,3])
3
```

`DelaunayTriangulation.getn`

— Method`getn(c::RepresentativeCoordinates) -> Integer`

Returns the number of points represented by `c`

.

`DelaunayTriangulation.getpoint`

— Function`getpoint(points, vertex) -> NTuple{2, Number}`

Get the point associated with `vertex`

in `points`

, returned as a `Tuple`

of the coordinates. If `vertex`

is not an integer, then `vertex`

is returned so that points and vertices can be easily mixed.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [(0.3, 0.7), (1.3, 5.0), (5.0, 17.0)];
julia> DelaunayTriangulation.getpoint(points, 2)
(1.3, 5.0)
julia> points = [0.3 1.3 5.0; 0.7 5.0 17.0];
julia> DelaunayTriangulation.getpoint(points, 2)
(1.3, 5.0)
julia> DelaunayTriangulation.getpoint(points, (17.3, 33.0))
(17.3, 33.0)
```

`DelaunayTriangulation.getx`

— Method`getx(p) -> Number`

Get the x-coordinate of `p`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> p = (0.3, 0.7);
julia> getx(p)
0.3
```

`DelaunayTriangulation.getx`

— Method`getx(c::Cell) -> Number`

Returns the x-coordinate of `c`

.

`DelaunayTriangulation.getx`

— Method`getx(c::RepresentativeCoordinates) -> Number`

Returns the x-coordinate of `c`

.

`DelaunayTriangulation.getxy`

— Method`getxy(p) -> NTuple{2, Number}`

Get the coordinates of `p`

as a `Tuple`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> p = [0.9, 23.8];
julia> getxy(p)
(0.9, 23.8)
```

`DelaunayTriangulation.gety`

— Method`gety(p) -> Number`

Get the y-coordinate of `p`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> p = (0.9, 1.3);
julia> gety(p)
1.3
```

`DelaunayTriangulation.gety`

— Method`gety(c::Cell) -> Number`

Returns the y-coordinate of `c`

.

`DelaunayTriangulation.gety`

— Method`gety(c::RepresentativeCoordinates) -> Number`

Returns the y-coordinate of `c`

.

`DelaunayTriangulation.grow_polygon_outside_of_box`

— Method`grow_polygon_outside_of_box(vorn::VoronoiTessellation, i, bounding_box) -> (Vector{Int}, Vector{NTuple{2,Number}})`

Truncates the unbounded edges of the `i`

th polygon of `vorn`

so that the line connecting the truncated unbounded edges is entirely outside of `bounding_box`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`i`

: The index of the polygon. The polygon must be unbounded.`bounding_box`

: The bounding box to clip the polygon to. See also`polygon_bounds`

.

**Outputs**

`new_vertices`

: The new vertices of the polygon. This is not a circular vector.`new_points`

: The new points of the polygon. This is not a circular vector.

`DelaunayTriangulation.has_acute_neighbouring_angles`

— Method`has_acute_neighbouring_angles(enricher::BoundaryEnricher, i, j) -> Int, Vertex`

Given a boundary edge `(i, j)`

, tests if the neighbouring angles are acute. The first returned value is the number of angles adjoining `(i, j)`

that are acute (0, 1, or 2). The second returned value is the vertex that adjoins the edge `(i, j)`

that is acute. If there are no such angles, or if there are two, then this returned vertex is `0`

.

(The purpose of this function is similar to `segment_vertices_adjoin_other_segments_at_acute_angle`

.)

`DelaunayTriangulation.has_boundary_nodes`

— Method`has_boundary_nodes(tri::Triangulation) -> Bool`

Returns `true`

if `tri`

has boundary nodes, and `false`

otherwise.

`DelaunayTriangulation.has_children`

— Method`has_children(node::AbstractNode) -> Bool`

Returns `true`

if `node`

has children.

`DelaunayTriangulation.has_children`

— Method`has_children(queue::MaxPriorityQueue, k) -> Bool`

Returns `true`

if the element at index `k`

has children in the `queue`

.

`DelaunayTriangulation.has_children`

— Method`has_children(tree::PolygonTree) -> Bool`

Returns `true`

if `tree`

has children, and `false`

otherwise.

`DelaunayTriangulation.has_ghost_triangles`

— Method`has_ghost_triangles(tri::Triangulation) -> Bool`

Returns `true`

if `tri`

has ghost triangles, and `false`

otherwise.

`DelaunayTriangulation.has_ghost_vertices`

— Method`has_ghost_vertices(G::Graph) -> Bool`

Returns `true`

if `G`

has ghost vertices, and `false`

otherwise.

`DelaunayTriangulation.has_ghost_vertices`

— Method`has_ghost_vertices(tri::Triangulation) -> Bool`

Returns `true`

if `tri`

has ghost vertices, and `false`

otherwise.

`DelaunayTriangulation.has_left`

— Method`has_left(node::BalancedBSTNode) -> Bool`

Returns `true`

if `node`

has a left child, `false`

otherwise.

`DelaunayTriangulation.has_lookup_table`

— Method`has_lookup_table(c::AbstractParametricCurve) -> Bool`

Returns `true`

if `c`

has a lookup table, and `false`

otherwise.

`DelaunayTriangulation.has_max_angle_constraint`

— Method`has_max_angle_constraint(constraints::RefinementConstraints) -> Bool`

Return `true`

if `constraints`

has a maximum angle constraint, `false`

otherwise.

`DelaunayTriangulation.has_multiple_curves`

— Function`has_multiple_curves(boundary_nodes) -> Bool`

Check if `boundary_nodes`

has multiple curves.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.has_multiple_curves([1, 2, 3, 1])
false
julia> DelaunayTriangulation.has_multiple_curves([[1, 2, 3], [3, 4, 1]])
false
julia> DelaunayTriangulation.has_multiple_curves([[[1, 2, 3], [3, 4, 1]], [[5, 6, 7, 8, 5]]])
true
```

`DelaunayTriangulation.has_multiple_curves`

— Method`has_multiple_curves(tri::Triangulation) -> Bool`

Returns `true`

if `tri`

has multiple boundary curves, and `false`

otherwise.

`DelaunayTriangulation.has_multiple_intersections`

— Method`has_multiple_intersections(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Multiple`

, and `false`

otherwise. Synonymous with `is_multiple`

.

`DelaunayTriangulation.has_multiple_sections`

— Function`has_multiple_sections(boundary_nodes) -> Bool`

Check if `boundary_nodes`

has multiple sections.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.has_multiple_sections([1, 2, 3, 1])
false
julia> DelaunayTriangulation.has_multiple_sections([[1, 2, 3], [3, 4, 1]])
true
julia> DelaunayTriangulation.has_multiple_sections([[[1, 2, 3], [3, 4, 1]], [[5, 6, 7, 8, 5]]])
true
```

`DelaunayTriangulation.has_multiple_sections`

— Method`has_multiple_sections(tri::Triangulation) -> Bool`

Returns `true`

if `tri`

has multiple boundary sections, and `false`

otherwise.

`DelaunayTriangulation.has_no_intersections`

— Method`has_no_intersections(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `None`

, and `false`

otherwise. Synonymous with `is_none`

.

`DelaunayTriangulation.has_one_intersection`

— Method`has_one_intersection(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Single`

, and `false`

otherwise. Synonymous with `is_single`

.

`DelaunayTriangulation.has_parent`

— Method`has_parent(node::AbstractNode) -> Bool`

Returns `true`

if `node`

has a parent.

`DelaunayTriangulation.has_parent`

— Method`has_parent(node::BalancedBSTNode) -> Bool`

Returns `true`

if `node`

has a parent, `false`

otherwise.

`DelaunayTriangulation.has_parent`

— Method`has_parent(tree::PolygonTree) -> Bool`

Returns `true`

if `tree`

has a parent, and `false`

otherwise.

`DelaunayTriangulation.has_right`

— Method`has_right(node::BalancedBSTNode) -> Bool`

Returns `true`

if `node`

has a right child, `false`

otherwise.

`DelaunayTriangulation.has_root`

— Method`has_root(tree::BalancedBST{K}) -> Bool`

Returns `true`

if `tree`

has a root, `false`

otherwise.

`DelaunayTriangulation.has_segment_changes`

— Method`has_triangle_changes(events::InsertionEventHistory) -> Bool`

Returns `true`

if there are any changes to the segments in `events`

, and `false`

otherwise.

`DelaunayTriangulation.has_segments`

— Method`has_segments(boundary_enricher::BoundaryEnricher -> Bool`

Returns `true`

if `boundary_enricher`

has interior segments, and `false`

otherwise.

`DelaunayTriangulation.has_segments`

— Method`has_segments(queue::RefinementQueue) -> Bool`

Return `true`

if `queue`

has any segments, `false`

otherwise.

`DelaunayTriangulation.has_triangles`

— Method`has_triangles(queue::RefinementQueue) -> Bool`

Return `true`

if `queue`

has any triangles, `false`

otherwise.

`DelaunayTriangulation.has_vertex`

— Method`has_vertex(G::Graph, u) -> Bool`

Returns `true`

if `u`

is a vertex in `G`

, and `false`

otherwise.

`DelaunayTriangulation.has_vertex`

— Method`has_vertex(tri::Triangulation, u) -> Bool`

Returns `true`

if `u`

is a vertex in `tri`

, and `false`

otherwise.

`DelaunayTriangulation.hchildren`

— Method`hchildren(k) -> Tuple{Int, Int}`

Returns the indices of the children of the element at index `k`

in a heap.

`DelaunayTriangulation.hleft`

— Method`hleft(k) -> Int`

Returns the index of the left child of the element at index `k`

in a heap.

`DelaunayTriangulation.horizontal_inflection_points`

— Method`horizontal_inflection_points(c::AbstractParametricCurve; steps=200, iters = 50, tol = 1e-5) -> Vector{Float64}`

Returns points `t`

such that `x''(t) = 0`

and `0 ≤ t ≤ 1`

, where `x''`

is the second derivative of the `x`

-coordinate of `c`

. This function uses Newton's method to find the roots of `x''`

. Note that these are only technically inflection points if `x'''(t) ≠ 0`

at these points, but this is not checked.

For curves of very high degree, such as Bezier curves with `steps`

control points or greater, this function might fail to return all inflection points.

**Arguments**

`c::AbstractParametricCurve`

: The curve to find the horizontal inflection points of.

**Keyword Arguments**

`steps=200`

: The number of`t`

-values to use for seeding Newton's method. In particular, Newton's method is run for each initial value in`LinRange(0, 1, steps)`

.`iters=50`

: The number of iterations to run Newton's method for.`tol=1e-5`

: The tolerance to use for`uniquetol`

. Also used for deciding whether a root is a valid root, i.e. if`abs(x''(t)) > tol`

for a found root`t`

, then`t`

is not a valid root and is rejected.

**Output**

`t`

: All inflection points, given in sorted order.

`DelaunayTriangulation.horizontal_turning_points`

— Method`horizontal_turning_points(c::AbstractParametricCurve; steps=200, iters = 50, tol = 1e-5) -> Vector{Float64}`

Returns points `t`

such that `x'(t) = 0`

and `0 ≤ t ≤ 1`

, where `x'`

is the derivative of the `x`

-coordinate of `c`

. This function uses Newton's method to find the roots of `x'`

.

For curves of very high degree, such as Bezier curves with `steps`

control points or greater, this function might fail to return all turning points.

**Arguments**

`c::AbstractParametricCurve`

: The curve to find the horizontal turning points of.

**Keyword Arguments**

`steps=200`

: The number of`t`

-values to use for seeding Newton's method. In particular, Newton's method is run for each initial value in`LinRange(0, 1, steps)`

.`iters=50`

: The number of iterations to run Newton's method for.`tol=1e-5`

: The tolerance to use for`uniquetol`

. Also used for deciding whether a root is a valid root, i.e. if`abs(x'(t)) > tol`

for a found root`t`

, then`t`

is not a valid root and is rejected.

**Output**

`t`

: All turning points, given in sorted order.

`DelaunayTriangulation.hparent`

— Method`hparent(k) -> Int`

Returns the index of the parent of the element at index `k`

in a heap.

`DelaunayTriangulation.hright`

— Method`hright(k) -> Int`

Returns the index of the right child of the element at index `k`

in a heap.

`DelaunayTriangulation.hspan`

— Method`hspan(r::BoundingBox) -> Float64`

Returns the horizontal span of `r`

, i.e. `length(r.x)`

.

`DelaunayTriangulation.incircle_predicate`

— Method`incircle_predicate(a, b, c, p) -> Integer`

Returns `ExactPredicates.incircle(a, b, c, p)`

, in particular we return:

`1`

: If`p`

is inside the circle defined by`(a, b, c)`

.`0`

: If`p`

is on the circle defined by`(a, b, c)`

.`-1`

: If`p`

is outside the circle defined by`(a, b, c)`

.

**Extended help**

The incircle predicate is defined by the determinant

\[\text{incircle}(a, b, c, d) = \text{sgn} \det \begin{bmatrix} a_x & a_y & a_x^2 + a_y^2 & 1 \\ b_x & b_y & b_x62 + b_y^2 & 1 \\ c_x & c_y & c_x^2 + c_y^2 & 1 \\ d_x & d_y & d_x^2 + d_y^2 & 1 \end{bmatrix} = \text{sgn} \det \begin{bmatrix} a_x - d_x & a_y - d_y & (a_x - d_x)^2 + (a_y - d_y)^2 \\ b_x - d_x & b_y - d_y & (b_x - d_x)^2 + (b_y - d_y)^2 \\ c_x - d_x & c_y - d_y & (c_x - d_x)^2 + (c_y - d_y)^2 \end{bmatrix}.\]

`DelaunayTriangulation.increase_depth!`

— Method`increase_depth!(tree::PolygonTree)`

Increases the height of `tree`

and all of its children by `1`

.

`DelaunayTriangulation.increment_num_elements!`

— Method`increment_num_elements!(tree::RTree)`

Increments the number of elements in `tree`

by 1.

`DelaunayTriangulation.inflection_points`

— Method`inflection_points(c::AbstractParametricCurve; steps=200, iters = 50, tol = 1e-5) -> Vector{Float64}`

Returns points `t`

such that `κ(t) = 0`

and `0 ≤ t ≤ 1`

, where `κ`

is the curvature of `c`

. This function uses Newton's method to find the roots of `κ`

.

For curves of very high degree, such as Bezier curves with `steps`

control points or greater, this function might fail to return all inflection points.

**Arguments**

`c::AbstractParametricCurve`

: The curve to find the inflection points of.

**Keyword Arguments**

`steps=200`

: The number of`t`

-values to use for seeding Newton's method. In particular, Newton's method is run for each initial value in`LinRange(0, 1, steps)`

.`iters=50`

: The number of iterations to run Newton's method for.`tol=1e-5`

: The tolerance to use for`uniquetol`

. Also used for deciding whether a root is a valid root, i.e. if`abs(κ(t)) > tol`

for a found root`t`

, then`t`

is not a valid root and is rejected.

`DelaunayTriangulation.initial`

— Method`initial(e) -> Vertex`

Get the initial vertex of `e`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> e = (1, 3);
julia> DelaunayTriangulation.initial(e)
1
julia> e = [2, 5];
julia> DelaunayTriangulation.initial(e)
2
```

`DelaunayTriangulation.initialise_bowyer_watson!`

— Method`initialise_bowyer_watson!(tri::Triangulation, insertion_order) -> Triangulation`

Initialises the Bowyer-Watson algorithm.

**Arguments**

`tri`

: The triangulation.`insertion_order`

: The insertion order of the points. See`get_insertion_order`

.

**Output**

`tri`

is updated in place to contain the initial triangle from which the Bowyer-Watson algorithm starts.

`DelaunayTriangulation.initialise_clipping_arrays`

— Method`initialise_clipping_arrays(vorn::VoronoiTessellation) -> (Set{E}, Queue{Tuple{E,I}}, Dict{I,Set{I}}, NTuple{2,F}[], Set{Tuple{E,I}}, Pair{E,E}[], Set{I}, Set{E}, Set{E}, Set{E}, Dict{I,I})`

Initialise the arrays used in the clipping algorithm for the `VoronoiTessellation`

`vorn`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.

**Outputs**

`edges_to_process`

: The set of edges that are to be processed.`polygon_edge_queue`

: The queue of edges that are to be processed.`boundary_sites`

: A mapping from boundary sites to the indices of the segment intersections that are incident to the boundary site.`segment_intersections`

: The list of segment intersections.`processed_pairs`

: The set of pairs of edges and polygons that have been processed.`intersected_edge_cache`

: The list of intersected edges currently being considered.`exterior_circumcenters`

: The list of circumcenters of sites that are outside the boundary.`left_edge_intersectors`

: The set of sites that intersect the edge to the left of an edge currently being considered.`right_edge_intersectors`

: The set of sites that intersect the edge to the right of an edge currently being considered.`current_edge_intersectors`

: The set of sites that intersect the current edge being considered.`equal_circumcenter_mapping`

: A mapping from the indices of the segment intersections that are equal to the circumcenter of a site to the index of the site.

`DelaunayTriangulation.initialise_jump_and_march_boundary_vertex`

— Method`initialise_jump_and_march_boundary_vertex(tri::Triangulation, q, k, store_history:, history, ghost_vertex, concavity_protection) -> (Bool, Bool, Triangle, Point, Vertex, Vertex, Point, Point)`

Initialise the jump-and-march algorithm for a boundary vertex `k`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`q`

: The query point.`k`

: The boundary vertex to start from.`store_history`

: Whether to store the history of the algorithm.`history`

: The history of the algorithm. If`store_history`

, then this should be a`PointLocationHistory`

object.`ghost_vertex`

: The ghost vertex corresponding to the boundary that`k`

resides on.`concavity_protection`

: Whether to use concavity protection. See`concavity_protection_check`

. This is only needed if your triangulation is not convex.

**Outputs**

`restart_flag`

: Whether the algorithm needs to be restarted.`return_flag`

: Whether the algorithm can return immediately, returning`V`

.`V`

: Either a triangle that can returned if`return_flag = true`

, or some triangle that is used for type stability for this return value.`p`

: The point corresponding to the vertex`k`

, or it may be`q`

if the algorithm is going to be restarted or`return_flag = true`

.`i`

: The first vertex of the triangle adjoining`k`

to start from, or`k`

if the algorithm is going to be restarted or`return_flag = true`

.`j`

: The second vertex of the triangle adjoining`k`

to start from, or`k`

if the algorithm is going to be restarted or`return_flag = true`

.`pᵢ`

: The point corresponding to the vertex`i`

, or it may be`q`

if the algorithm is going to be restarted or`return_flag = true`

.`pⱼ`

: The point corresponding to the vertex`j`

, or it may be`q`

if the algorithm is going to be restarted or`return_flag = true`

.

**Extended help**

There are multiple stages to this initialisation, starting from `check_for_intersections_with_adjacent_boundary_edges`

.

If it is found that

`q`

is not outside of the triangulation, so that`q`

is collinear with one of the boundary edges, then we use`search_down_adjacent_boundary_edges`

to find where to start, noting that we can return immediately if`q`

is found to be on an adjacent boundary edge. Otherwise,`exterior_jump_and_march`

can then be used to find the ghost triangle containing`q`

; if`concavity_protection = true`

, then`concavity_protection_check`

is used to determine if a restart is needed.If is is not found that

`q`

is outside of the triangulation yet based on information from the adjacent boundary edges, then we need to check the neighbouring interior edges using`check_for_intersections_with_interior_edges_adjacent_to_boundary_vertex`

, returning early if`q`

is found to be inside one of the neighbouring triangles. If the line`pq`

, where`p = get_point(tri, k)`

, does not intersect any of the neighbouring edges and it is not inside any of the neighbouring triangles, then it must be outside of the triangulation and so we use`exterior_jump_and_march`

to find the triangle; as before,`concavity_protection_check`

is used on the found ghost triangle if needed. If there is an intersection, then we return the triangle containing the intersection point that we can start the algorithm from, and its associated vertices and points.

`DelaunayTriangulation.initialise_jump_and_march_interior_vertex`

— Method`initialise_jump_and_march_interior_vertex(tri::Triangulation, q, k, store_history::F, history, rng) -> (Bool, Point, Vertex, Vertex, Point, Point)`

Initialise the jump-and-march algorithm for an interior vertex `k`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`q`

: The query point.`k`

: The interior vertex to start from.`store_history`

: Whether to store the history of the algorithm.`history`

: The history of the algorithm. If`store_history`

, then this should be a`PointLocationHistory`

object.`rng`

: The random number generator to use.

**Outputs**

`restart_flag`

: Whether the algorithm needs to be restarted.`p`

: The point corresponding to the vertex`k`

.`i`

: The first vertex of the triangle adjoining`k`

to start from.`j`

: The second vertex of the triangle adjoining`k`

to start from.`pᵢ`

: The point corresponding to the vertex`i`

.`pⱼ`

: The point corresponding to the vertex`j`

.

**Extended help**

This function works by simply using `select_initial_triangle_interior_vertex`

to find the initial triangle to start from. A check is made to see if the edge `(i, j)`

refers to a non-existent edge `(0, 0)`

, in which case the algorithm needs to be restarted.

`DelaunayTriangulation.initialise_voronoi_tessellation`

— Method`initialise_voronoi_tessellation(tri::Triangulation) -> VoronoiTessellation`

Initialise a `VoronoiTessellation`

from the triangulation `tri`

.

**Arguments**

`tri`

: The`Triangulation`

.

**Output**

`vorn`

: The`VoronoiTessellation`

. This tessellation is not yet filled in, as all the polygons and other fields need to be properly defined. This simply defines all the initial objects that will be pushed into.

`DelaunayTriangulation.inorder`

— Method`inorder(tree::BalancedBST{K}) -> Vector{K}`

Returns the inorder traversal of `tree`

.

`DelaunayTriangulation.insert_boundary_node!`

— Method`insert_boundary_node!(boundary_nodes, pos, node)`

Inserts a boundary node `node`

into `boundary_nodes`

at the position `pos`

. Here, `pos[1]`

is such that `get_boundary_nodes(boundary_nodes, pos[1])`

is the section that the node will be inserted onto, and `pos[2]`

gives the position of the array to insert `node`

into. In particular,

`insert_boundary_node!(boundary_nodes, pos, node)`

is the same as

`insert!(get_boundary_nodes(boundary_nodes, pos[1]), pos[2], node)`

**Examples**

```
julia> using DelaunayTriangulation
julia> boundary_nodes = [1, 2, 3, 4, 5, 1];
julia> DelaunayTriangulation.insert_boundary_node!(boundary_nodes, (boundary_nodes, 4), 23)
7-element Vector{Int64}:
1
2
3
23
4
5
1
julia> boundary_nodes = [[7, 13, 9, 25], [25, 26, 29, 7]];
julia> DelaunayTriangulation.insert_boundary_node!(boundary_nodes, (2, 1), 57)
2-element Vector{Vector{Int64}}:
[7, 13, 9, 25]
[57, 25, 26, 29, 7]
julia> boundary_nodes = [[[17, 23, 18, 25], [25, 26, 81, 91], [91, 101, 17]], [[1, 5, 9, 13], [13, 15, 1]]];
julia> DelaunayTriangulation.insert_boundary_node!(boundary_nodes, ((1, 3), 3), 1001)
2-element Vector{Vector{Vector{Int64}}}:
[[17, 23, 18, 25], [25, 26, 81, 91], [91, 101, 1001, 17]]
[[1, 5, 9, 13], [13, 15, 1]]
```

`DelaunayTriangulation.insert_boundary_node!`

— Method`insert_boundary_node!(tri::Triangulation, pos, node)`

Inserts a boundary node into `tri`

at the specified position.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`pos`

: The position to insert the node at, given as a`Tuple`

so that`insert_boundary_node!(tri, pos, node)`

is the same as`insert!(get_boundary_nodes(tri, pos[1]), pos[2], node)`

.`node`

: The node to insert.

**Outputs**

There are no outputs, but the boundary nodes of `tri`

are updated in-place.

`DelaunayTriangulation.insert_cell!`

— Method`insert_cell!(queue::CellQueue, cell::Cell)`

Inserts a `cell`

into the `queue`

.

`DelaunayTriangulation.insert_detached!`

— Method`insert_detached!(tree::RTree, detached)`

Given the `detached`

nodes from `collapse_after_deletion!`

, inserts them back into `tree`

.

`DelaunayTriangulation.insert_node!`

— Method`insert_node!(node::Union{Nothing,BalancedBSTNode{K}}, key::K) -> Union{Nothing,BalancedBSTNode{K}}`

Inserts `key`

into the subtree rooted at `node`

if it is not already present. Returns the new root of the subtree.

`DelaunayTriangulation.integer_type`

— Method`integer_type(tri::Triangulation) -> DataType`

Returns the type used for representing vertices in `tri`

.

`DelaunayTriangulation.integer_type`

— Method`integer_type(vorn::VoronoiTessellation) -> DataType`

Type used for representing indices in the Voronoi tessellation.

`DelaunayTriangulation.intersection_of_edge_and_bisector_ray`

— Method`intersection_of_edge_and_bisector_ray(a, b, c) -> (Certificate, NTuple{2, Number})`

Given an edge `(a, b)`

and a ray emanating from `c`

perpendicular with the edge and collinear with its midpoint, tests if `c`

intersects the edge. The returned value is `(cert, p)`

, where:

`cert`

: A`Certificate`

indicating the position of`c`

relative to the line through`(a, b)`

.`p`

: The intersection point (which is the midpoint) if`c`

intersects the edge,`(NaN, NaN)`

otherwise.

`DelaunayTriangulation.intersection_of_ray_with_bounding_box`

— Method`intersection_of_ray_with_bounding_box(p, q, a, b, c, d) -> NTuple{2, Number}`

Compute the intersection of the ray emanating from `p`

and passing through `q`

with the box `[a, b] × [c, d]`

. It is assumed that `p`

is inside of the box.

`DelaunayTriangulation.is_above`

— Method`is_above(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Above`

, and `false`

otherwise.

`DelaunayTriangulation.is_acute`

— Method`is_acute(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Acute`

, and `false`

otherwise.

`DelaunayTriangulation.is_below`

— Method`is_below(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Below`

, and `false`

otherwise.

`DelaunayTriangulation.is_boundary_edge`

— Method```
is_boundary_edge(tri::Triangulation, ij) -> Bool
is_boundary_edge(tri::Triangulation, i, j) -> Bool
```

Tests if the edge `(i, j)`

is a boundary edge of `tri`

, meaning `(j, i)`

adjoins a ghost vertex.

`DelaunayTriangulation.is_boundary_node`

— Method`is_boundary_node(tri::Triangulation, i) -> (Bool, Vertex)`

Tests if the vertex `i`

is a boundary node of `tri`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`i`

: The vertex to test.

**Outputs**

`flag`

:`true`

if`i`

is a boundary node, and`false`

otherwise.`g`

: Either the ghost vertex corresponding with the section that`i`

lives on if`flag`

is true, or 0 otherwise.

`DelaunayTriangulation.is_boundary_triangle`

— Method```
is_boundary_triangle(tri::Triangulation, T) -> Bool
is_boundary_triangle(tri::Triangulation, i, j, k) -> Bool
```

Returns `true`

if the triangle `T = (i, j, k)`

of `tri`

has an edge on the boundary, and `false`

otherwise.

`DelaunayTriangulation.is_circular`

— Method`is_circular(A) -> Bool`

Tests if `A`

is circular, meaning that `A[begin] == A[end]`

.

`DelaunayTriangulation.is_closer`

— Method`is_closer(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Closer`

, and `false`

otherwise.

`DelaunayTriangulation.is_collinear`

— Method`is_collinear(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Collinear`

, and `false`

otherwise.

`DelaunayTriangulation.is_constrained`

— Method`is_constrained(tri::Triangulation) -> Bool`

Returns `true`

if `tri`

has constrained edges (segments), and `false`

otherwise.

`DelaunayTriangulation.is_curve_bounded`

— Function```
is_curve_bounded(tri::Triangulation) -> Bool
is_curve_bounded(boundary_nodes) -> Bool
```

Returns `true`

if `tri`

is curve bounded, and `false`

otherwise; similarly for the `boundary_nodes`

method.

`DelaunayTriangulation.is_curve_bounded`

— Method`is_curve_bounded(c::AbstractParametricCurve) -> Bool`

Returns `true`

if `c`

is not a `PiecewiseLinear`

curve. This is equivalent to `!is_piecewise_linear(c)`

.

`DelaunayTriangulation.is_degenerate`

— Method`is_degenerate(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Degenerate`

, and `false`

otherwise.

`DelaunayTriangulation.is_disjoint`

— Method`is_disjoint(tri::Triangulation) -> Bool`

Returns `true`

if `tri`

has disjoint exterior boundary curves, and `false`

otherwise.

`DelaunayTriangulation.is_encroached`

— Method`is_encroached(tri::Triangulation, args::RefinementArguments, edge) -> Bool`

Determines if a segment `edge`

of `tri`

is encroached upon.

See also `encroaches_upon`

.

`DelaunayTriangulation.is_encroachmentfailure`

— Method`is_encroachmentfailure(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `EncroachmentFailure`

, and `false`

otherwise.

`DelaunayTriangulation.is_equidistant`

— Method`is_equidistant(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Equidistant`

, and `false`

otherwise.

`DelaunayTriangulation.is_exterior_boundary_node`

— Method`is_exterior_boundary_node(tri::Triangulation, i) -> Bool`

Tests if the vertex `i`

is an exterior boundary node of `tri`

.

`DelaunayTriangulation.is_exterior_curve`

— Method`is_exterior_curve(tri::Triangulation, curve_index) -> Bool`

Returns `true`

if the `curve_index`

th curve in `tri`

is an exterior curve, and `false`

otherwise.

`DelaunayTriangulation.is_exterior_ghost_edge`

— Method`is_exterior_ghost_edge(tri::Triangulation, i, j) -> Bool`

Tests if the edge `(i, j)`

is an exterior ghost edge of `tri`

.

See also `is_exterior_ghost_vertex`

.

`DelaunayTriangulation.is_exterior_ghost_triangle`

— Method`is_exterior_ghost_triangle(tri::Triangulation, i, j, k) -> Bool`

Tests if the triangle `(i, j, k)`

is an exterior ghost triangle of `tri`

.

See also `is_exterior_ghost_vertex`

.

`DelaunayTriangulation.is_exterior_ghost_vertex`

— Method`is_exterior_ghost_vertex(tri::Triangulation, i) -> Bool`

Returns `true`

if the ghost vertex `i`

in `tri`

is an exterior ghost vertex, and `false`

otherwise.

See also `is_ghost_vertex`

and `is_interior_ghost_vertex`

.

**Extended help**

An exterior ghost vertex is a ghost vertex corresponding to a curve or section appearing on the exterior boundary.

`DelaunayTriangulation.is_failedinsertion`

— Method`is_failedinsertion(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `FailedInsertion`

, and `false`

otherwise.

`DelaunayTriangulation.is_finite_segment`

— Method`is_finite_segment(u, v) -> Bool`

Returns `true`

if the segment `(u, v)`

is finite, and `false`

otherwise.

`DelaunayTriangulation.is_first_ghost_vertex`

— Method`is_first_ghost_vertex(cell, i) -> Bool`

Assuming that the circular vector `cell`

is such that ghost vertices only appear next to eachother in `cell`

and there are only two, tests if `i`

is the first ghost vertex in `cell`

.

See also `is_last_ghost_vertex`

.

**Arguments**

`cell`

: The circular vector.`i`

: The index of the vertex in`cell`

.

**Outputs**

`flag`

:`true`

if`i`

is the first ghost vertex in`cell`

, and`false`

otherwise.

`DelaunayTriangulation.is_free`

— Method`is_free(args::RefinementArguments, u) -> Bool`

Returns `true`

if `u`

is a free vertex, and `false`

otherwise. A free vertex is a Steiner vertex (meaning a non-input vertex) that is not part of a segment or subsegment.

`DelaunayTriangulation.is_full`

— Method`is_full(node::AbstractNode, tree::RTree) -> Bool`

Returns `true`

if `node`

is full, i.e. if `num_children(node) ≥ get_size_limit(tree)`

.

`DelaunayTriangulation.is_full`

— Method`is_full(cache::NodeCache) -> Bool`

Returns `true`

if `cache`

is full, i.e. if `length(cache) ≥ get_size_limit(cache)`

.

`DelaunayTriangulation.is_further`

— Method`is_further(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Further`

, and `false`

otherwise.

`DelaunayTriangulation.is_ghost_edge`

— Method```
is_ghost_edge(ij) -> Bool
is_ghost_edge(i, j) -> Bool
```

Tests if the edge `(i, j)`

is a ghost edge, meaning `i`

or `j`

is a ghost vertex.

`DelaunayTriangulation.is_ghost_triangle`

— Method```
is_ghost_triangle(T) -> Bool
is_ghost_triangle(i, j, k) -> Bool
```

Tests if `T = (i, j, k)`

is a ghost triangle, meaning `i`

, `j`

or `k`

is a ghost vertex.

`DelaunayTriangulation.is_ghost_vertex`

— Method`is_ghost_vertex(i) -> Bool`

Tests if `i`

is a ghost vertex, meaning `i ≤ -1`

.

`DelaunayTriangulation.is_illegal`

— Method`is_illegal(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Illegal`

, and `false`

otherwise.

`DelaunayTriangulation.is_in_tree`

— Method`is_in_tree(hierarchy::PolygonHierarchy, points, boundary_nodes, tree::PolygonTree, p) -> Bool`

Tests if the point `p`

is inside `tree`

.

**Arguments**

`hierarchy::PolygonHierarchy`

: The`PolygonHierarchy`

containing`tree`

.`points`

: The point set.`boundary_nodes`

: The boundary nodes.`tree::PolygonTree`

: The`PolygonTree`

to test`p`

against.`p`

: The point to test.

**Output**

`true`

if`p`

is inside`tree`

, and`false`

otherwise.

`DelaunayTriangulation.is_inside`

— Method`is_inside(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Inside`

, and `false`

otherwise.

`DelaunayTriangulation.is_interior_curve`

— Method`is_interior_curve(tri::Triangulation, curve_index) -> Bool`

Returns `true`

if the `curve_index`

th curve in `tri`

is an interior curve, and `false`

otherwise.

`DelaunayTriangulation.is_interior_ghost_vertex`

— Method`is_interior_ghost_vertex(tri::Triangulation, i) -> Bool`

Returns `true`

if the ghost vertex `i`

in `tri`

is an interior ghost vertex, and `false`

otherwise.

See also `is_ghost_vertex`

and `is_exterior_ghost_vertex`

.

**Extended help**

An interior ghost vertex is a ghost vertex corresponding to a curve or section appearing on the interior boundary.

`DelaunayTriangulation.is_interpolating`

— Method`is_interpolating(c::AbstractParametricCurve) -> Bool`

Returns `true`

if `c`

goes through all its control points, and `false`

otherwise.

`DelaunayTriangulation.is_invisible`

— Method`is_invisible(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Invisible`

, and `false`

otherwise.

`DelaunayTriangulation.is_last_ghost_vertex`

— Method`is_last_ghost_vertex(cell, i) -> Bool`

Assuming that the circular vector `cell`

is such that ghost vertices only appear next to eachother in `cell`

, tests if `i`

is the last ghost vertex in `cell`

.

See also `is_first_ghost_vertex`

.

**Arguments**

`cell`

: The circular vector.`i`

: The index of the vertex in`cell`

.

**Outputs**

`flag`

:`true`

if`i`

is the last ghost vertex in`cell`

, and`false`

otherwise.

`DelaunayTriangulation.is_left`

— Method`is_left(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Left`

, and `false`

otherwise.

`DelaunayTriangulation.is_legal`

— Function```
is_legal(tri::Triangulation, i, j) -> Certificate
is_legal(p, q, r, s) -> Certificate
```

Tests if the edge `(p, q)`

(or the edge `(i, j)`

of `tri`

) is legal, where the edge `(p, q)`

is incident to two triangles `(p, q, r)`

and `(q, p, s)`

. In partiuclar, tests that `s`

is not inside the triangle through `(p, q, r)`

. The returned value is a `Certificate`

, which is one of:

`Legal`

: The edge`(p, q)`

is legal.`Illegal`

: The edge`(p, q)`

is illegal.

If the edge `(i, j)`

is a segment of `tri`

or is a ghost edge, then the edge is always legal.

`DelaunayTriangulation.is_legal`

— Method`is_legal(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Legal`

, and `false`

otherwise.

`DelaunayTriangulation.is_midpoint_split`

— Method`is_midpoint_split(args::RefinementArguments, u) -> Bool`

Returns `true`

if `u`

is a midpoint of an encroached segment, and `false`

otherwise.

`DelaunayTriangulation.is_multiple`

— Method`is_multiple(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Multiple`

, and `false`

otherwise.

`DelaunayTriangulation.is_negatively_oriented`

— Method`is_negatively_oriented(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `NegativelyOriented`

, and `false`

otherwise.

`DelaunayTriangulation.is_negativelyoriented`

— Method`is_negativelyoriented(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `NegativelyOriented`

, and `false`

otherwise.

`DelaunayTriangulation.is_none`

— Method`is_none(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `None`

, and `false`

otherwise.

`DelaunayTriangulation.is_obtuse`

— Method`is_obtuse(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Obtuse`

, and `false`

otherwise.

`DelaunayTriangulation.is_offcenter_split`

— Method`is_offcenter_split(args::RefinementArguments, u) -> Bool`

Returns `true`

if `u`

is an off-centre split of an encroached segment, and `false`

otherwise.

`DelaunayTriangulation.is_on`

— Method`is_on(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `On`

, and `false`

otherwise.

`DelaunayTriangulation.is_outside`

— Method`is_outside(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Outside`

, and `false`

otherwise.

`DelaunayTriangulation.is_piecewise_linear`

— Method`is_piecewise_linear(c::AbstractParametricCurve) -> Bool`

Returns `true`

if `c`

is `PiecewiseLinear`

, and `false`

otherwise.

`DelaunayTriangulation.is_piecewise_linear`

— Method`is_piecewise_linear(enricher::BoundaryEnricher, curve_index) -> Bool`

Returns `true`

if the `curve_index`

th curve in `enricher`

is piecewise linear, and `false`

otherwise.

`DelaunayTriangulation.is_positively_oriented`

— Method`is_positively_oriented(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `PositivelyOriented`

, and `false`

otherwise.

`DelaunayTriangulation.is_positively_oriented`

— Method`is_positively_oriented(tri::Triangulation, curve_index) -> Bool`

Tests if the `curve_index`

th curve in `tri`

is positively oriented, returning `true`

if so and `false`

otherwise.

`DelaunayTriangulation.is_positivelyoriented`

— Method`is_positivelyoriented(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `PositivelyOriented`

, and `false`

otherwise.

`DelaunayTriangulation.is_precisionfailure`

— Method`is_precisionfailure(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `PrecisionFailure`

, and `false`

otherwise.

`DelaunayTriangulation.is_ray_going_in`

— Method`is_ray_going_in(u, v) -> Bool`

Returns `true`

if the ray `(u, v)`

is coming in from infinity, and `false`

otherwise.

`DelaunayTriangulation.is_ray_going_out`

— Method`is_ray_going_out(u, v) -> Bool`

Returns `true`

if the ray `(u, v)`

is going out to infinity, and `false`

otherwise.

`DelaunayTriangulation.is_right`

— Method`is_right(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Right`

, and `false`

otherwise.

`DelaunayTriangulation.is_root`

— Method`is_root(k) -> Bool`

Returns `true`

if the element at index `k`

is the root of a heap.

`DelaunayTriangulation.is_root`

— Method`is_root(node::AbstractNode, tree::RTree) -> Bool`

Returns `true`

if `node`

is the root of `tree`

.

`DelaunayTriangulation.is_segment`

— Method`is_segment(enricher::BoundaryEnricher, i, j) -> Bool`

Returns `true`

if `(i, j)`

or `(j, i)`

is an interior segment of `enricher`

, and `false`

otherwise.

`DelaunayTriangulation.is_segment_between_two_ghosts`

— Method`is_segment_between_two_ghosts(u, v) -> Bool`

Returns `true`

if the segment `(u, v)`

is between two ghost vertices, and `false`

otherwise.

`DelaunayTriangulation.is_segment_vertex`

— Method`is_segment_vertex(args::RefinementArguments, u) -> Bool`

Returns `true`

if `u`

is a vertex of a segment, and `false`

otherwise. Note that this excludes vertices of subsegments.

`DelaunayTriangulation.is_single`

— Method`is_single(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Single`

, and `false`

otherwise.

`DelaunayTriangulation.is_small_angle_complex_apex`

— Method`is_small_angle_complex_apex(boundary_enricher::BoundaryEnricher, apex) -> Bool`

Returns `true`

if `apex`

is the apex of a small angle complex in `boundary_enricher`

, and `false`

otherwise.

`DelaunayTriangulation.is_small_angle_complex_member`

— Method`is_small_angle_complex_member(enricher::BoundaryEnricher, i, j) -> Bool, I, IntegerType, IntegerType`

Returns `true`

if the edge `(i, j)`

is a member of a small angle complex in `enricher`

, and `false`

otherwise.

**Outputs**

`flag`

:`true`

if the edge is a member of a small angle complex, and`false`

otherwise.`apex`

: If the edge is a member of a small angle complex, then`apex`

is the apex of the complex. Otherwise,`apex`

is`0`

.`complex_id`

: If the edge is a member of a small angle complex, then`complex_id`

is the index of the complex in the list of complexes associated with`apex`

. Otherwise,`complex_id`

is`0`

.`member_id`

: If the edge is a member of a small angle complex, then`member_id`

is the index of the member in the list of members associated with`complex_id`

. Otherwise,`member_id`

is`0`

.

`DelaunayTriangulation.is_submerged`

— Function```
is_submerged(tri::Triangulation, i) -> Bool
is_submerged(tri::Triangulation, i, V) -> Bool
```

Returns `true`

if the vertex `i`

is submerged in `tri`

and `false`

otherwise. In the second method, `V`

is a triangle containing `tri`

.

`DelaunayTriangulation.is_subsegment`

— Method`is_subsegment(args::RefinementArguments, u, v) -> Bool`

Returns `true`

if the edge `(u, v)`

is a subsegment, and `false`

otherwise.

`DelaunayTriangulation.is_successfulinsertion`

— Method`is_successfulinsertion(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `SuccessfulInsertion`

, and `false`

otherwise.

`DelaunayTriangulation.is_touching`

— Method`is_touching(r1::BoundingBox, r2::BoundingBox) -> Bool`

Tests whether `r1`

and `r2`

are touching, i.e. if they share a common boundary. This only considers interior touching.

`DelaunayTriangulation.is_touching`

— Method`is_touching(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Touching`

, and `false`

otherwise.

`DelaunayTriangulation.is_triangle_nestled`

— Method`is_triangle_nestled(tri::Triangulation, T, idx) -> Bool`

Determines if a triangle `T`

of `tri`

is nestled in the corner of a small input angle.

See also `is_triangle_seditious`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`T`

: The triangle.`idx`

: The index of the smallest edge of the triangle, so that`1`

means`uv`

is the smallest edge,`2`

means`vw`

is the smallest edge, and`3`

means`wu`

is the smallest edge.

**Output**

`flag`

: Whether the triangle is nestled in the corner of a small input angle.

A triangle is nestled in the corner of a small input angle if it is nestled in the corner of a small input angle and the shortest edge is seditious. The size of the angle is not checked by this function, and is instead determined by `assess_triangle_quality`

.

`DelaunayTriangulation.is_triangle_seditious`

— Method`is_triangle_seditious(tri::Triangulation, args, u, v, w, smallest_idx) -> Bool`

Determines if a triangle `uvw`

of `tri`

is seditious according to the `RefinementArguments`

.

See also `is_triangle_nestled`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`args`

: The`RefinementArguments`

.`u, v, w`

: The vertices of the triangle.`smallest_idx`

: The index of the smallest edge of the triangle, so that`1`

means`uv`

is the smallest edge,`2`

means`vw`

is the smallest edge, and`3`

means`wu`

is the smallest edge.

**Output**

`flag`

: Whether the triangle is seditious.

A triangle is seditious if it is nestled in the corner of a small input angle, or if it is nestled in the corner of a small input angle and the shortest edge is seditious. Here, 'small' is defined by `args.constraints.seditious_angle`

.

`DelaunayTriangulation.is_true`

— Function`is_true(b) -> Bool`

Returns `b`

represents a `true`

value, and `false`

otherwise.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.is_true(true)
true
julia> DelaunayTriangulation.is_true(false)
false
julia> DelaunayTriangulation.is_true(Val(true))
true
julia> DelaunayTriangulation.is_true(Val(false))
false
```

`DelaunayTriangulation.is_vertex_closer_than_neighbours`

— Method```
is_vertex_closer_than_neighbours(tri::Triangulation, u, v, jᵢ, jᵢ₋₁, jᵢ₊₁) -> Bool
is_vertex_closer_than_neighbours(tri::Triangulation, list::ShuffledPolygonLinkedList, u, v, j) -> Bool
```

Tests if the vertex `jᵢ`

is closer to the line `(u, v)`

than its neighbours `jᵢ₋₁`

and `jᵢ₊₁`

, assuming all these vertices are to the left of the line.

See also `point_closest_to_line`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`u`

,`v`

: The vertices of the line.`jᵢ`

,`jᵢ₋₁`

,`jᵢ₊₁`

: The vertices to compare.

The second method extracts these latter two vertices using the doubly-linked `list`

of vertices.

**Outputs**

`flag`

: Whether`jᵢ`

is closer to the line than`jᵢ₋₁`

and`jᵢ₊₁`

.

`DelaunayTriangulation.is_visible`

— Method`is_visible(cert::Certificate) -> Bool`

Returns `true`

if `cert`

is `Visible`

, and `false`

otherwise.

`DelaunayTriangulation.is_weighted`

— Method`is_weighted(weights) -> Bool`

Returns `true`

if `weights`

represents a set of `weights`

that are not all zero, and `false`

otherwise. Note that even for vectors like `zeros(n)`

, this will return `true`

; by default, `false`

is returned only for `weights = ZeroWeight()`

.

`DelaunayTriangulation.is_weighted`

— Method`is_weighted(tri::Triangulation) -> Bool`

Returns `true`

if `tri`

is weighted, and `false`

otherwise.

`DelaunayTriangulation.iterated_neighbourhood`

— Method`iterated_neighbourhood(tri::Triangulation, i, d) -> Set{Vertex}`

Returns the set of vertices of `tri`

in the iterated neighbourhood of the vertex `i`

of depth `d`

.

**Extended help**

The $d$-times iterated neighbourhood is defined by

\[N_i^d = \bigcup_{j \in N_i^{d-1}} N_j \setminus \{i\},\]

where $N_i^1 = N_i$ is the set of neighbours of $i$.

`DelaunayTriangulation.jump_and_march`

— Method`jump_and_march(tri, q; kwargs...) -> Triangle[, Bool]`

Find the triangle in the triangulation `tri`

containing the query point `q`

using the jump-and-march algorithm.

**Arguments**

`tri`

: The`Triangulation`

.`q`

: The query point.

**Keyword Arguments**

`point_indices=each_solid_vertex(tri)`

: The indices of the vertices to consider as possible starting points for the algorithm.`m=default_num_samples(num_vertices(point_indices))`

: The number of samples to use when selecting the initial point.`try_points=()`

: A list of points to try as the initial point in addition to the`m`

sampled.`rng=Random.default_rng()`

: The random number generator to use.`k=select_initial_point(tri, q; point_indices, m, try_points, rng)`

: The initial point to start the algorithm from. See`select_initial_point`

.`store_history=Val(false)`

: Whether to store the history of the algorithm.`history=nothing`

: The history of the algorithm. If`store_history`

, then this should be a`PointLocationHistory`

object.`maxiters=2 + num_exterior_curves(tri) - num_solid_vertices(tri) + num_solid_edges(tri)`

: The maximum number of iterations to perform before restarting the algorithm with`restart_jump_and_march`

.

If the algorithm restarts, then the initial point `k`

is selected again using `select_initial_point`

, and the algorithm is restarted from there. This is done if the algorithm gets stuck in a loop, or if the algorithm is not able to find the correct triangle containing `q`

after `maxiters`

iterations. For a convex geometry, `maxiters`

can be safely ignored, as the sequence of triangles visited is acyclic [see H. Edelsbrunner, An acyclicity theorem for cell complexes in d dimensions, Combinatorica 10 (1990) 251-260.)].

`concavity_protection=false`

: Whether to use concavity protection. See`concavity_protection_check`

. This is only needed if your triangulation is not convex.`use_barriers::Val{U}=Val(false)`

: Whether to stop searching beyond any segments in the triangulation.

If you are using barriers, it will be your responsibility to verify that any found triangle from this function actually contains the triangle. This can be verified using the returned `flag`

(see below), although the point might still be on the triangle's boundary.

If you are using barriers, it is possible that the algorithm can walk past vertices of barriers. One way this can happen is if the initial search line intersects a vertex, in which case the segment might not be considered. Another way this can happen is if you start the algorithm directly on a segment vertex, in which case the algorithm can go past it (e.g. this means that it is possible that a ghost triangle might still be returned if you start the algorithm on a boundary node).

**Output**

`V`

: The triangle containing`q`

, with type given by`triangle_type(tri)`

.

If a barrier is hit before any initial triangle is properly identified, the returned triangle is `(0, 0, 0)`

; this is only possible if `use_barriers == Val(true)`

. Moreover, if `use_barriers == Val(true)`

, the final triangle may not even be valid if `invisible_flag == true`

(defined below).

If you have `use_barriers == Val(true)`

, then we also return

`invisible_flag`

:`false`

if the triangle was found without hitting a barrier, and`true`

otherwise.

While this function does still work for non-convex geometries, it may be significantly slower than for convex geometries, as most of the details of the algorithm assume that the geometry is convex, and so the algorithm may have to restart many times at new initial vertices `k`

.

For this function to work best, the triangulation should have ghost triangles, which you can add using `add_ghost_triangles!`

in case `tri`

does not already have them. Without ghost triangles, the function may not be able to find the correct triangle containing `q`

.

**Extended help**

The algorithm underlying this function is complicated and broken into many parts. Here, we describe a brief overview of the algorithm, but note that the documentation contains a much more detailed description.

- Firstly, the algorithm is initialised depending on whether
`k`

is a boundary or an interior vertex, using`initialise_jump_and_march_boundary_vertex`

or`initialise_jump_and_march_interior_vertex`

respectively. - From the initial triangle
`(i, j, k)`

chosen, we then check if`q`

is one of`pᵢ`

,`pⱼ`

, and`p = pₖ`

and then return according to`jump_and_march_return_on_vertex`

if needed. - If we do not return above, we need to step from the initial triangle towards
`q`

. Since we put`pᵢ`

and`pⱼ`

to the left and right of the line`pq`

, respectively, this means that we step until the triangle`pᵢpⱼq`

is no longer positively oriented. So, while the triangle is positively oriented, we step according to`jump_and_march_across_triangle`

. - If we have not yet returned and the triangle is no longer positively oriented, we check if the triangle is degenerate using
`jump_and_march_degenerate_arrangement`

and reinitialise the algorithm if needed. Otherwise, we have found the triangle containing`q`

and return the triangle.

`DelaunayTriangulation.jump_and_march_across_triangle`

— Method`jump_and_march_across_triangle(tri::Triangulation, q, k, store_history, history, maxiters, cur_iter, concavity_protection, arrangement, original_k, last_changed, p, i, j, pᵢ, pⱼ) -> (Bool, Bool, Bool, Triangle, Integer, Certificate, Vertex, Vertex, Vertex, Point, Point, Integer, Integer)`

Walks across the current triangle past the edge `(i, j)`

. progressing the `jump_and_march`

algorithm.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`q`

: The query point.`k`

: The vertex that the algorithm started from.`store_history`

: Whether to store the history of the algorithm.`history`

: The history of the algorithm. If`store_history`

, then this should be a`PointLocationHistory`

object.`maxiters`

: The maximum number of iterations to perform before restarting the algorithm with`restart_jump_and_march`

.`cur_iter`

: The current iteration of the algorithm.`concavity_protection`

: Whether to use concavity protection. See`concavity_protection_check`

. This is only needed if your triangulation is not convex.`arrangement`

: A`Certificate`

defining the orientation of the triangle`pᵢpⱼq`

.`original_k`

: The original vertex that the algorithm started from.`last_changed`

: The last vertex that was changed in the algorithm.`p`

: The point corresponding to the vertex`original_k`

.`i`

: The first vertex of the triangle adjoining`k`

to step from.`j`

: The second vertex of the triangle adjoining`k`

to step from.`pᵢ`

: The point corresponding to the vertex`i`

.`pⱼ`

: The point corresponding to the vertex`j`

.

**Outputs**

`restart_flag`

: Whether the algorithm needs to be restarted.`return_flag`

: Whether the algorithm can return immediately, returning`V`

.`reinitialise_flag`

: Whether the algorithm needs to be reinitialised at a new vertex`k`

. (This would only be needed if`!has_ghost_triangles(tri)`

.)`V`

: The triangle stepped into.`cur_iter`

: The new number of iterations of the algorithm.`arrangement`

: A`Certificate`

defining the orientation of the triangle`pᵢpⱼq`

with the updated values of`i`

and`j`

.`k`

: The new vertex that the algorithm is at.`last_changed`

: The last vertex that was changed in the algorithm.`original_k`

: The original vertex that the algorithm started from.`pᵢ`

: The point corresponding to the vertex`i`

.`pⱼ`

: The point corresponding to the vertex`j`

.`i`

: The first vertex of the triangle adjoining`k`

to step from.`j`

: The second vertex of the triangle adjoining`k`

to step from.

**Extended help**

This part of the algorithm is relatively complicated because there are many cases that need to be accounted for. Here we give a brief description of how this step works, and note that the documentation contains a much more detailed description.

Firstly, we need to check whether

`k`

is an exterior ghost vertex or not. If`k`

is an exterior ghost vertex, then this means that we are stepping outside of the triangulation. Thus, we use`exterior_jump_and_march`

to find where`q`

is, starting from the`last_changed`

vertex. If`concavity_protection = true`

, then`concavity_protection_check`

is used to determine if a restart is needed, or if we can return safely. If we reach this step but`!has_ghost_triangles(tri)`

, then the algorithm should need to be reinitialised since`q`

should not be outside of the triangulation, and so we return with`reinitialise_flag = true`

.Now we consider the case where

`k`

is not an exterior ghost vertex. We move forward by updating the value of`k`

so that`k = get_adjacent(tri, i, j)`

, and then consider where`pₖ`

is relative to the line`pq`

.`2a. If `pₖ` is to the right of `pq`, then we should update `j` by `j = k`, ensuring that `j` is always to the right of `pq`. 2b. If `pₖ` is to the left of `pq`, then we should update `i` by `i = k`, ensuring that `i` is always to the left of `pq`. 2c. The alternative to 2a and 2b is that `pₖ` is collinear with the edge of `pq`, which could mean that `q` is in the current triangle or it is in a triangle further away. We compute a [`Certificate`](@ref) that determines where `q` is relative to the triangle `pᵢpⱼpₖ`. If `q` is inside or on this triangle, then we return, restarting if necessary according to `concavity_protection` and [`concavity_protection_check`](@ref). If we do not yet need to return, then we need to make a decision as to which of `i` and `j` to update, noting that we want `i` to be left of `pq` and `j` to be right of `pq`, but this is no longer unambiguous since `pₖ` is collinear with `pq`. We make this decision according to `last_changed`: If `last_changed = i`, then moving left is what caused us to find this collinear edge, and so we send `k` left by letting `i = k`. Otherwise, we send `k` right by letting `j = k`.`

Now having stepped forward, we recompute the

`Certificate`

for arrangement and return, setting`restart_flag = true`

if`cur_iters ≥ maxiters`

.

`DelaunayTriangulation.jump_and_march_degenerate_arrangement`

— Method`jump_and_march_degenerate_arrangement(tri::Triangulation, q, k, store_history::F, history, pᵢ, pⱼ, i, j) -> Bool`

Given a degenerate arrangement `pᵢpⱼq`

, reinitialise the jump and march algorithm.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`q`

: The query point.`k`

: The vertex that the algorithm started from.`store_history`

: Whether to store the history of the algorithm.`history`

: The history of the algorithm. If`store_history`

, then this should be a`PointLocationHistory`

object.`pᵢ`

: The point corresponding to the vertex`i`

.`pⱼ`

: The point corresponding to the vertex`j`

.`i`

: The first vertex of the triangle adjoining`k`

to step from.`j`

: The second vertex of the triangle adjoining`k`

to step from.

**Outputs**

`Bool`

: Whether the algorithm needs to be restarted.

`DelaunayTriangulation.jump_and_march_return_on_vertex`

— Method`jump_and_march_return_on_vertex(tri::Triangulation, q, k, p, pᵢ, pⱼ, i, j) -> (Bool, Bool, Triangle)`

Check if `q`

is one of the vertices of the triangle `(i, j, k)`

and return if needed.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`q`

: The query point.`k`

: The vertex`k`

that the algorithm started from.`p`

: The point corresponding to the vertex`k`

.`pᵢ`

: The point corresponding to the vertex`i`

.`pⱼ`

: The point corresponding to the vertex`j`

.`i`

: The first vertex of the triangle adjoining`k`

to start from.`j`

: The second vertex of the triangle adjoining`k`

to start from.

**Outputs**

`restart_flag`

: Whether the algorithm needs to be restarted.`return_flag`

: Whether the algorithm can return immediately, returning`V`

.`V`

: The triangle`(i, j, k)`

.

**Extended help**

An extra check is made in this algorithm for the case that the point that `q`

is equal to is one of the points corresponding to a ghost vertex, so it may be for example that `q == pᵢ`

but `is_ghost_vertex(i)`

, in which case the algorithm would need to restart.

`DelaunayTriangulation.keep_iterating`

— Method`keep_iterating(tri::Triangulation, args::RefinementArguments) -> Bool`

Returns `true`

if the refinement should continue, and `false`

otherwise. The check is based on whether the `RefinementQueue`

is empty or not, and whether the number of points in the triangulation is less than or equal to the maximum number of points allowed by the `RefinementConstraints`

.

`DelaunayTriangulation.keep_splitting`

— Method`keep_splitting(tri::Triangulation, args::RefinementArguments) -> Bool`

Returns `true`

if more encroached segments need to be split, and `false`

otherwise. The check is based on whether the segment queue in the `RefinementQueue`

of `args`

is empty or not, and whether the number of points in the triangulation is less than or equal to the maximum number of points allowed by the `RefinementConstraints`

in `args`

.

`DelaunayTriangulation.legalise_edge!`

— Function`legalise_edge!(tri::Triangulation, i, j, r, store_event_history=Val(false), event_history=nothing)`

Legalises the edge `(i, j)`

and other neighbouring edges in `tri`

if they are illegal, assuming the vertex `r`

was just added into a triangle that contains `(i, j)`

. `flip_edge!`

is used.

See also `is_legal`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`i`

: The first vertex of the edge to legalise.`j`

: The second vertex of the edge to legalise.`r`

: The vertex that was just added into a triangle that contains`(i, j)`

.`store_event_history=Val(false)`

: Whether to store the event history of the flip.`event_history=nothing`

: The event history. Only updated if`store_event_history`

is true, in which case it needs to be an`InsertionEventHistory`

object.

**Outputs**

There is no output, as `tri`

is updated in-place.

Edge flipping can lead to `event_history`

having triangles both in `event_history.added_triangles`

and `event_history.deleted_triangles`

. To get around this, we only store in these fields the triangles necessary to allow `undo_insertion!`

to work, so that at a triangle that might have appeared in both will only appear in one.

`DelaunayTriangulation.legalise_split_edge!`

— Function`legalise_split_edge!(tri::Triangulation, i, j, k, r, store_event_history=Val(false), event_history=nothing)`

Legalises the newly added edges in `tri`

after the edge `(i, j)`

was split using `split_edge!`

.

See also `complete_split_edge_and_legalise!`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`i`

: The first vertex of the edge that was split.`j`

: The second vertex of the edge that was split.`k`

: The vertex that was originally adjacent to`(i, j)`

.`r`

: The vertex that`(i, j)`

was split at.`store_event_history=Val(false)`

: Whether to store the event history of the flip.`event_history=nothing`

: The event history. Only updated if`store_event_history`

is true, in which case it needs to be an`InsertionEventHistory`

object.

**Outputs**

There is no output, as `tri`

is updated in-place.

`DelaunayTriangulation.legalise_split_triangle!`

— Method`legalise_split_triangle!(tri::Triangulation, i, j, k, r)`

Legalises the newly added edges in `tri`

after the triangle `(i, j, k)`

was split using `split_triangle!`

.

See also `complete_split_triangle_and_legalise!`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`i`

: The first vertex of the triangle.`j`

: The second vertex of the triangle.`k`

: The third vertex of the triangle.`r`

: The vertex to split the triangle at.

**Outputs**

There is no output, as `tri`

is updated in-place.

`DelaunayTriangulation.lexicographic_order`

— Method`lexicographic_order(points) -> Vector{Int}`

Returns a set of indices that give the lexicographic ordering of `points`

, meaning the indices so that the points are sorted first by `x`

and then by `y`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [(1.0, 5.0), (0.0, 17.0), (0.0, 13.0), (5.0, 17.3), (3.0, 1.0), (5.0, -2.0)]
6-element Vector{Tuple{Float64, Float64}}:
(1.0, 5.0)
(0.0, 17.0)
(0.0, 13.0)
(5.0, 17.3)
(3.0, 1.0)
(5.0, -2.0)
julia> DelaunayTriangulation.lexicographic_order(points)
6-element Vector{Int64}:
3
2
1
5
6
4
julia> hcat(points, points[ans])
6×2 Matrix{Tuple{Float64, Float64}}:
(1.0, 5.0) (0.0, 13.0)
(0.0, 17.0) (0.0, 17.0)
(0.0, 13.0) (1.0, 5.0)
(5.0, 17.3) (3.0, 1.0)
(3.0, 1.0) (5.0, -2.0)
(5.0, -2.0) (5.0, 17.3)
```

`DelaunayTriangulation.liang_barsky`

— Method`liang_barsky(a, b, c, d, p, q) -> (Point, Point)`

Applies the Liang-Barsky algorithm to find the intersection of the line segment `pq`

with the rectangle `[a, b] × [c, d]`

.

**Arguments**

`p`

: The first point of the line segment.`q`

: The second point of the line segment.`a`

: The minimum x-coordinate of the rectangle.`b`

: The maximum x-coordinate of the rectangle.`c`

: The minimum y-coordinate of the rectangle.`d`

: The maximum y-coordinate of the rectangle.

**Output**

`u`

: The first coordinate of the intersection, or`(NaN, NaN)`

if there is no intersection.`v`

: The second coordinate of the intersection, or`(NaN, NaN)`

if there is no intersection.

`DelaunayTriangulation.line_segment_intersection_type`

— Function```
line_segment_intersection_type(p, q, a, b) -> Certificate
line_segment_intersection_type(tri::Triangulation, u, v, i, j) -> Certificate
```

Given the coordinates `(p, q)`

(or vertices `(u, v)`

) and `(a, b)`

(or vertices `(i, j)`

) defining two line segments, tests the number of intersections between the two segments. The returned value is a `Certificate`

, which is one of:

`None`

: The line segments do not meet at any points.`Multiple`

: The closed line segments`[p, q]`

and`[a, b]`

meet in one or several points.`Single`

: The open line segments`(p, q)`

and`(a, b)`

meet in a single point.`Touching`

: One of the endpoints is on`[a, b]`

, but there are no other intersections.

`DelaunayTriangulation.locate_intersecting_triangles`

— Function`locate_intersecting_triangles(tri::Triangulation, e, rotate=Val(true), rng::AbstractRNG=Random.default_rng()) -> (Vector, Vector, Vector, Vector)`

Find all the triangles intersected by an edge `e`

.

See also `jump_and_march`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`e`

: The edge going through the triangulation.`rotate=Val(true)`

: Whether to rotate the edge so that the minimum degree vertex of`e`

is first.`rng::AbstractRNG=Random.default_rng()`

: The random number generator to use.

**Outputs**

`intersecting_triangles`

: The intersected triangles.`collinear_segments`

: Segments that are collinear with`e`

.`left_vertices`

: The vertices of the intersected triangles that are left of`e`

.`right_vertices`

: The vertices of the intersected triangles that are right of`e`

.

`DelaunayTriangulation.locate_steiner_point`

— Method`locate_steiner_point(tri::Triangulation, args::RefinementArguments, T, c) -> Triangle, Cert`

Locates the Steiner point `c`

of a triangle `T`

of `tri`

in `get_steiner_point`

. The Steiner point is located by walking from the initial vertex `init`

to `c`

using `jump_and_march`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

to split a triangle of.`args::RefinementArguments`

: The`RefinementArguments`

for the refinement.`T`

: The triangle that the Steiner point is from.`c`

: The Steiner point.

**Output**

`V`

: The triangle that the Steiner point is in.`flag`

: A`Certificate`

which is`Cert.On`

if the Steiner point is on the boundary of`V`

,`Cert.Outside`

if the Steiner point is outside of`V`

, and`Cert.Inside`

if the Steiner point is inside of`V`

.

`DelaunayTriangulation.lock_convex_hull!`

— Method`lock_convex_hull!(tri::Triangulation)`

Locks the convex hull of the unconstrained triangulation `tri`

so that it is now treated as a constrained triangulation with boundary given by its convex hull.

If an edge is encountered along the convex hull that contains a segment from `tri.interior_segments`

, then this edge will be deleted from `tri.interior_segments`

; this will be undone from `unlock_convex_hull!`

, possibly splitting the segments in case they were split before unlocking.

`DelaunayTriangulation.make_shortest_edge_first`

— Method`make_shortest_edge_first(p, q, r, idx) -> (NTuple{2, Number}, NTuple{2, Number}, NTuple{2, Number})`

Given a triangle `(p, q, r)`

, rotate it (preserving orientation) so that the shortest edge is first. The argument `idx`

gives the index of the shortest edge, where `idx == 1`

means `(p, q)`

, `idx == 2`

means `(q, r)`

, and `idx == 3`

means `(r, p)`

.

`DelaunayTriangulation.map_curve_index`

— Method`map_curve_index(boundary_enricher::BoundaryEnricher, curve_index) -> Integer`

Returns the curve index in `boundary_enricher`

associated with `curve_index`

.

`DelaunayTriangulation.map_ghost_vertex`

— Method`map_ghost_vertex(tri::Triangulation, ℓ) -> Vertex`

Given a ghost vertex `ℓ`

in `tri`

, returns the corresponding section in the `boundary_nodes`

of `tri`

. See also `get_ghost_vertex_map`

.

`DelaunayTriangulation.marked_total_variation`

— Method`marked_total_variation(b::AbstractParametricCurve, t₁, t₂)`

Returns the total variation of the curve `b`

over the interval `[t₁, t₂]`

using the orientation markers of `b`

.

`DelaunayTriangulation.maximum_distance_to_box`

— Method`maximum_distance_to_box(a, b, c, d, p) -> Number`

Computes the maximum squared distance from the point `p`

to the box with corners `(a, c)`

, `(b, c)`

, `(b, d)`

, `(a, d)`

.

**Arguments**

`a`

: The minimum`x`

-coordinate of the box.`b`

: The maximum`x`

-coordinate of the box.`c`

: The minimum`y`

-coordinate of the box.`d`

: The maximum`y`

-coordinate of the box.`p`

: The point.

**Outputs**

`dist`

: The maximum squared distance from`p`

to the box.

`DelaunayTriangulation.mean_points`

— Function`mean_points(points[, vertices = each_point_index(points)]) -> NTuple{2, Number}`

Returns the mean of the points in `points`

indexed by `vertices`

, given as a `Tuple`

of the form `(mean_x, mean_y)`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [(1.0, 2.0), (2.3, 5.0), (17.3, 5.3)]
3-element Vector{Tuple{Float64, Float64}}:
(1.0, 2.0)
(2.3, 5.0)
(17.3, 5.3)
julia> DelaunayTriangulation.mean_points(points)
(6.866666666666667, 4.1000000000000005)
julia> (1.0 + 2.3 + 17.3)/3, (2.0 + 5.0 + 5.3)/3
(6.866666666666667, 4.1000000000000005)
julia> points = [1.0 2.3 17.3; 2.0 5.0 5.3]
2×3 Matrix{Float64}:
1.0 2.3 17.3
2.0 5.0 5.3
julia> DelaunayTriangulation.mean_points(points)
(6.866666666666667, 4.1000000000000005)
julia> DelaunayTriangulation.mean_points(points, (1, 3))
(9.15, 3.65)
julia> (1.0 + 17.3)/2, (2.0 + 5.3)/2
(9.15, 3.65)
```

`DelaunayTriangulation.meet_predicate`

— Method`meet_predicate(p, q, a, b)`

Returns `ExactPredicates.meet(p, q, a, b)`

, in particular we return:

`1`

: The open line segments`(p, q)`

and`(a, b)`

meet in a single point.`0`

: The closed line segments`[p, q]`

and`[a, b]`

meet in one or several points.`-1`

: Otherwise.

`DelaunayTriangulation.merge_boundary_edge!`

— Method```
merge_boundary_edge!(tri::Triangulation, ij, node)
merge_boundary_edge!(tri::Triangulation, i, j, node)
```

Merges the edges `(i, node)`

and `(node, j)`

into a single edge `(i, j)`

, i.e. does the inverse operation to `split_boundary_edge!`

.

`DelaunayTriangulation.merge_segments`

— Method`merge_segments(tri::Triangulation, ghost_vertex_map) -> Edges`

Creates a set of edges that merge all the boundary nodes in `tri`

as well as its interior segments into a single collection.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`ghost_vertex_map`

: The ghost vertex map to use.

**Outputs**

`all_segments`

: The set of edges that merge all the boundary nodes in`tri`

as well as its interior segments into a single collection, with type equal to that of`get_interior_segments(tri)`

's.

`DelaunayTriangulation.midpoint`

— Method`midpoint(r::BoundingBox) -> NTuple{2,Float64}`

Returns the center of `r`

.

`DelaunayTriangulation.midpoint`

— Method`midpoint(I::BoundingInterval) -> Float64`

Returns the midpoint of `I`

.

`DelaunayTriangulation.midpoint`

— Method`midpoint(p, q) -> Number or NTuple{2, Number}`

Assuming `p`

and `q`

are either both numbers are both 2-vectors, computes their average.

`DelaunayTriangulation.midpoint`

— Method```
midpoint(tri::Triangulation, u, v) -> NTuple{2, Number}
midpoint(tri::Triangulation, e) -> NTuple{2, Number}
```

Computes the midpoint of `e = (u, v)`

.

`DelaunayTriangulation.min_med_max`

— Method`min_med_max(a, b, c) -> (Number, Number, Number)`

Returns the arguments in sorted order.

`DelaunayTriangulation.minimise_enlargement`

— Method`minimise_enlargement(node, bounding_box) -> EnlargementValues`

Returns the `EnlargementValues`

associated with the child of `node`

that minimises the enlargement, where enlargement is defined as the difference between the area of `bounding_box`

and the area of the child's bounding box.

`DelaunayTriangulation.move_generator_to_centroid!`

— Method`move_generator_to_centroid!(points, vorn::VoronoiTessellation, generator) -> Number`

Moves the generator `generator`

to the centroid of its Voronoi cell. Returns the distance moved.

**Arguments**

`points`

: The underlying point set. This is a`deepcopy`

of the points of the underlying triangulation.`vorn`

: The`VoronoiTessellation`

.`generator`

: The generator to move.

**Outputs**

`dist`

: The distance moved.

`DelaunayTriangulation.new_representative_point!`

— Method`new_representative_point!(tri::Triangulation, curve_index)`

Creates a new representative point for the `curve_index`

th curve in `tri`

.

`DelaunayTriangulation.nextindex_circular`

— Method`nextindex_circular(C, i) -> Integer`

Returns the next index after `i`

in the circular vector `C`

.

`DelaunayTriangulation.norm`

— Method`norm(p) -> Number`

Assuming `p`

is two-dimensional, computes the Euclidean norm of `p`

.

`DelaunayTriangulation.norm_sqr`

— Method`norm_sqr(p) -> Number`

Assuming `p`

is two-dimensional, computes the square of the Euclidean norm of `p`

.

`DelaunayTriangulation.num_boundary_edges`

— Method`num_boundary_edges(boundary_nodes) -> Integer`

Get the number of boundary edges in `boundary_nodes`

, assuming that `boundary_nodes`

defines a boundary with only one curve and a single section.

`DelaunayTriangulation.num_boundary_segments`

— Method`num_boundary_segments(stats::TriangulationStatistics)`

Returns the num*boundary*segments field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_children`

— Method`num_children(node::AbstractNode) -> Int`

Returns the number of children of `node`

.

`DelaunayTriangulation.num_children`

— Method`has_children(tree::PolygonTree) -> Bool`

Returns `true`

if `tree`

has children, and `false`

otherwise.

`DelaunayTriangulation.num_convex_hull_vertices`

— Method`num_convex_hull_vertices(stats::TriangulationStatistics)`

Returns the num*convex*hull_vertices field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_curves`

— Method`num_curves(boundary_nodes) -> Integer`

Get the number of curves in `boundary_nodes`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.num_curves([1, 2, 3, 1])
1
julia> DelaunayTriangulation.num_curves([[1, 2, 3], [3, 4, 1]])
1
julia> DelaunayTriangulation.num_curves([[[1, 2, 3], [3, 4, 1]], [[5, 6, 7, 8, 5]]])
2
```

`DelaunayTriangulation.num_curves`

— Method`num_curves(tri::Triangulation) -> Integer`

Returns the number of curves in `tri`

.

`DelaunayTriangulation.num_edges`

— Method`num_edges(E) -> Integer`

Get the number of edges in `E`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> e = [(1, 2), (3, 4), (1, 5)];
julia> num_edges(e)
3
```

`DelaunayTriangulation.num_edges`

— Method`num_edges(G::Graph) -> Integer`

Returns the number of edges in `G`

. The edges `(i, j)`

and `(j, i)`

are counted as one edge.

`DelaunayTriangulation.num_edges`

— Method`num_edges(history::PointLocationHistory) -> Integer`

Returns the number of edges in `history.collinear_segments`

.

`DelaunayTriangulation.num_edges`

— Method`num_edges(stats::TriangulationStatistics)`

Returns the num_edges field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_edges`

— Method`num_edges(tri::Triangulation) -> Integer`

Returns the number of edges in `tri`

. Note that, if `has_ghost_triangles(tri)`

, then some of these edges will be ghost edges.

See also `num_solid_edges`

and `num_ghost_edges`

.

`DelaunayTriangulation.num_elements`

— Method`num_elements(tree::RTree) -> Int`

Returns the number of elements in `tree`

.

`DelaunayTriangulation.num_exterior_curves`

— Method`num_exterior_curves(tri::Triangulation) -> Integer`

Returns the number of exterior curves in `tri`

.

`DelaunayTriangulation.num_generators`

— Method`num_generators(vor::VoronoiTessellation) -> Integer`

Returns the number of generators in the Voronoi tessellation `vor`

.

`DelaunayTriangulation.num_ghost_edges`

— Method`num_ghost_edges(stats::TriangulationStatistics)`

Returns the num*ghost*edges field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_ghost_edges`

— Method`num_ghost_edges(tri::Triangulation) -> Integer`

Returns the number of ghost edges in `tri`

.

See also `num_solid_edges`

and `num_edges`

.

`DelaunayTriangulation.num_ghost_triangles`

— Method`num_ghost_triangles(stats::TriangulationStatistics)`

Returns the num*ghost*triangles field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_ghost_triangles`

— Method`num_ghost_triangles(tri::Triangulation) -> Integer`

Returns the number of ghost triangles in `tri`

.

`DelaunayTriangulation.num_ghost_vertices`

— Method`num_ghost_vertices(stats::TriangulationStatistics)`

Returns the num*ghost*vertices field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_ghost_vertices`

— Method`num_ghost_vertices(tri::Triangulation) -> Integer`

Returns the number of ghost vertices in `tri`

.

See also `num_solid_vertices`

and `num_vertices`

.

`DelaunayTriangulation.num_interior_segments`

— Method`num_interior_segments(stats::TriangulationStatistics)`

Returns the num*interior*segments field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_neighbours`

— Method`num_neighbours(G::Graph, u) -> Integer`

Returns the number of neighbours of `u`

in `G`

.

`DelaunayTriangulation.num_neighbours`

— Method`num_neighbours(tri::Triangulation, u) -> Integer`

Returns the number of neighbours of `u`

in `tri`

. Note that, if `has_ghost_triangles(tri)`

, then some of the neighbours counted might be ghost vertices if `u`

is a boundary vertex.

`DelaunayTriangulation.num_points`

— Function`num_points(points) -> Integer`

Returns the number of points in `points`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [(1.0, 1.0), (2.3, 1.5), (0.0, -5.0)];
julia> DelaunayTriangulation.num_points(points)
3
julia> points = [1.0 5.5 10.0 -5.0; 5.0 2.0 0.0 0.0];
julia> DelaunayTriangulation.num_points(points)
4
```

`DelaunayTriangulation.num_points`

— Method`num_points(tri::Triangulation) -> Integer`

Returns the number of points in `tri`

.

If `tri`

has vertices that are not yet present in the triangulation, e.g. if you have deleted vertices or have some submerged vertices in a weighted triangulation, then the corresponding points will still be counted in this function. It is recommended that you instead consider `num_vertices`

, `num_solid_vertices`

, or `num_ghost_vertices`

.

`DelaunayTriangulation.num_polygon_vertices`

— Method`num_polygon_vertices(vor::VoronoiTessellation) -> Integer`

Returns the number of polygon vertices in the Voronoi tessellation `vor`

. This might include duplicate vertices if `get_polygon_points(vor)`

has duplicates.

`DelaunayTriangulation.num_polygons`

— Method`num_polygons(vor::VoronoiTessellation) -> Integer`

Returns the number of polygons in the Voronoi tessellation `vor`

.

`DelaunayTriangulation.num_sections`

— Method`num_sections(boundary_nodes) -> Integer`

Assuming `boundary_nodes`

has only one curve, get the number of sections in `boundary_nodes`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.num_sections([1, 2, 3, 4, 5, 1])
1
julia> DelaunayTriangulation.num_sections([[1, 2, 3, 4], [4, 5, 1]])
2
julia> DelaunayTriangulation.num_sections([[1, 2, 3], [3, 4, 5, 6, 7, 8], [8, 9], [9, 1]])
4
```

`DelaunayTriangulation.num_sections`

— Method`num_sections(tri::Triangulation) -> Integer`

Assuming `tri`

only has one curve, returns the number of sections in `tri`

.

`DelaunayTriangulation.num_segments`

— Method`num_segments(stats::TriangulationStatistics)`

Returns the num_segments field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_solid_edges`

— Method`num_solid_edges(stats::TriangulationStatistics)`

Returns the num*solid*edges field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_solid_edges`

— Method`num_solid_edges(tri::Triangulation) -> Integer`

Returns the number of solid edges in `tri`

.

See also `num_ghost_edges`

and `num_edges`

.

`DelaunayTriangulation.num_solid_triangles`

— Method`num_solid_triangles(stats::TriangulationStatistics)`

Returns the num*solid*triangles field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_solid_triangles`

— Method`num_solid_triangles(tri::Triangulation) -> Integer`

Returns the number of solid triangles in `tri`

.

`DelaunayTriangulation.num_solid_vertices`

— Method`num_solid_vertices(stats::TriangulationStatistics)`

Returns the num*solid*vertices field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_solid_vertices`

— Method`num_solid_vertices(tri::Triangulation) -> Integer`

Returns the number of solid vertices in `tri`

.

See also `num_ghost_vertices`

and `num_vertices`

.

`DelaunayTriangulation.num_triangles`

— Method`num_triangles(T) -> Integer`

Get the number of triangles in `T`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> T1, T2, T3 = (1, 5, 10), (17, 23, 10), (-1, 10, 5);
julia> T = Set((T1, T2, T3));
julia> num_triangles(T)
3
```

`DelaunayTriangulation.num_triangles`

— Method`num_triangles(stats::TriangulationStatistics)`

Returns the num_triangles field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_triangles`

— Method`num_triangles(tri::Triangulation) -> Integer`

Returns the number of triangles in `tri`

. Note that, if `has_ghost_triangles(tri)`

, then some of these triangles will be ghost triangles.

`DelaunayTriangulation.num_vertices`

— Method`num_vertices(G::Graph) -> Integer`

Returns the number of vertices in `G`

.

`DelaunayTriangulation.num_vertices`

— Method`num_vertices(stats::TriangulationStatistics)`

Returns the num_vertices field from the TriangulationStatistics` `stats`

.

`DelaunayTriangulation.num_vertices`

— Method`num_vertices(tri::Triangulation) -> Integer`

Returns the number of vertices in `tri`

. Note that, if `has_ghost_triangles(tri)`

, then some of these vertices will be ghost vertices.

See also `num_solid_vertices`

and `num_ghost_vertices`

.

`DelaunayTriangulation.number_type`

— Function`number_type(x) -> DataType`

Given a container `x`

, returns the number type used for storing coordinates.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.number_type([1, 2, 3])
Int64
julia> DelaunayTriangulation.number_type((1, 2, 3))
Int64
julia> DelaunayTriangulation.number_type([1.0 2.0 3.0; 4.0 5.0 6.0])
Float64
julia> DelaunayTriangulation.number_type([[[1, 2, 3, 4, 5, 1]], [[6, 8, 9], [9, 10, 11], [11, 12, 6]]])
Int64
julia> DelaunayTriangulation.number_type((1.0f0, 2.0f0))
Float32
julia> DelaunayTriangulation.number_type(Vector{Float64})
Float64
julia> DelaunayTriangulation.number_type(Vector{Vector{Float64}})
Float64
julia> DelaunayTriangulation.number_type(NTuple{2, Float64})
Float64
```

`DelaunayTriangulation.number_type`

— Method`number_type(tri::Triangulation) -> DataType`

Returns the type used for representing individual coordinates in `tri`

.

`DelaunayTriangulation.number_type`

— Method`number_type(vorn::VoronoiTessellation) -> DataType`

Type used for representing individual coordinates in the Voronoi tessellation.

`DelaunayTriangulation.opposite_angle`

— Method`opposite_angle(p, q, r) -> Certificate`

Tests the angle opposite to the edge `(p, q)`

in the triangle `(p, q, r)`

, meaning `∠prq`

. The returned value is a `Certificate`

, which is one of:

`Obtuse`

: The angle opposite to`(p, q)`

is obtuse.`Right`

: The angle opposite to`(p, q)`

is a right angle.`Acute`

: The angle opposite to`(p, q)`

is acute.

This function computes `(p - r) ⋅ (q - r)`

. If you want the angle between vectors `a = pq`

and `b = pr`

, then you should use `opposite_angle(r, q, p) = (r - p) ⋅ (q - p)`

.

`DelaunayTriangulation.opposite_signs`

— Method`opposite_signs(x, y) -> Bool`

From ExactPredicates.jl, returns `true`

if `x`

and `y`

have opposite signs, and `false`

otherwise.

`DelaunayTriangulation.optimise_edge_order`

— Method`optimise_edge_order(tri::Triangulation, segment) -> Edge`

Optimises the orientation of `segment`

for inserting it into the triangulation.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`segment`

: The segment to arrange.

**Outputs**

`e`

: If`segment`

is a boundary edge, then`e = segment`

, Otherwise,`e = sort_edge_by_degree(tri, segment)`

so that`initial(e)`

has the smaller degree of the two vertices.

`DelaunayTriangulation.orient_predicate`

— Method`orient_predicate(p, q, r, s) -> Integer`

Returns `ExactPredicates.orient(p, q, r, s)`

, in particular we return:

`1`

:`(p, q, r, s)`

is positively oriented.`0`

:`(p, q, r, s)`

is collinear / degenerate.`-1`

:`(p, q, r, s)`

is negatively oriented.

Here, a positively oriented tetrahedron `(p, q, r, s)`

takes the form

```
z.
.
,/
s
,/|'\
,/ | '\
,/ '. '\
,/ | '\
,/ | '\
p-----------'.--------q --> x
'\. | ,/
'\. | ,/
'\. '. ,/
'\. |/
'r
'\.
```

**Extended help**

The orient predicate is defined by the determinant

\[\text{orient}(p, q, r, s) = \text{sgn} \det \begin{bmatrix} p_x & p_y & p_y & 1 \\ q_x & q_y & q_r & 1 \\ r_x & r_y & r_z & 1 \\ s_x & s_y & s_z & 1 \end{bmatrix} = \text{sgn} \det \begin{bmatrix} p_x - s_x & p_y - s_y & p_z - s_y \\ q_x - s_x & q_y - s_y & q_z - s_z \\ r_x - s_x & r_y - s_y & r_z - s_z \end{bmatrix}.\]

`DelaunayTriangulation.orient_predicate`

— Method`orient_predicate(p, q, r) -> Integer`

Returns `ExactPredicates.orient(p, q, r)`

, in particular we return:

`1`

:`(p, q, r)`

is positively oriented.`0`

:`(p, q, r)`

is collinear / degenerate.`-1`

:`(p, q, r)`

is negatively oriented.

**Extended help**

The orient predicate is defined by the determinant

\[\text{orient}(p, q, r) = \text{sgn} \det \begin{bmatrix} p_x & p_y & 1 \\ q_x & q_y & 1 \\ r_x & r_y & 1 \end{bmatrix} = \text{sgn} \det \begin{bmatrix} p_x-r_x & p_y-r_y \\ q_x-r_x & q_y-r_y \end{bmatrix}.\]

`DelaunayTriangulation.orientation_markers`

— Method`orientation_markers(c::AbstractParametricCurve; steps=200, iters=50, tol=1e-5) -> Vector{Float64}`

Finds all orientation markers of the `AbstractParametricCurve`

`c`

. These are points `t`

where any of the following conditions hold (not necessarily simultaneously), letting `c(t) = (x(t), y(t))`

:

`x'(t) = 0`

`y'(t) = 0`

`κ(t; x) = 0`

, where`κ(t; x)`

is the curvature of the component function`x(t)`

`κ(t; y) = 0`

, where`κ(t; y)`

is the curvature of the component function`y(t)`

`κ(t) = 0`

, where`κ`

is the curvature of`c(t)`

Note that the third and fourth conditions give all the inflection points of the component functions, and similarly for the fifth condition.

See also `horizontal_turning_points`

, `vertical_turning_points`

, `horizontal_inflection_points`

, `vertical_inflection_points`

, and `inflection_points`

.

For curves of very high degree, such as Bezier curves with `steps`

control points or greater, this function might fail to return all inflection points.

**Arguments**

`c::AbstractParametricCurve`

: The`AbstractParametricCurve`

.

**Keyword Arguments**

`steps=200`

: The number of equally spaced points to use for initialising Newton's method.`iters=50`

: How many iterations to use for Newton's method.`tol=1e-5`

: The tolerance used for determining if two`t`

-values are the same.

**Output**

`markers::Vector{Float64}`

: The`t`

-values of the orientation markers of`b`

. The returned vector is sorted, and also includes the endpoints`0`

and`1`

; any`t`

-values outside of`[0, 1]`

are discarded, and multiplicity of any`t`

is not considered (so the`t`

-values in the returned vector are unique). These values can be used to split the curve into monotone pieces, meaning the orientation is monotone. These markers also guarantee that, over any monotone piece, the orientation changes by an angle of at most`π/2`

.

`DelaunayTriangulation.overflow_insert!`

— Method`overflow_insert!(node, child, tree) -> Bool`

Inserts `child`

into `node`

in `tree`

when `node`

is full. Returns `true`

.

`DelaunayTriangulation.parallelorder_predicate`

— Method`parallelorder_predicate(a, b, p, q) -> Integer`

Returns `ExactPredicates.parallelorder(a, b, p, q)`

, in particular we return:

`1`

:`q`

is closer to the line`(a, b)`

than`p`

.`0`

:`p`

and`q`

are equidistant from the line`(a, b)`

.`-1`

:`p`

is closer to the line`(a, b)`

than`q`

.

`DelaunayTriangulation.partition_members`

— Method`partition_members(complexes::Vector{SmallAngleComplex{I}}, points) where {I} -> Vector{SmallAngleComplex{I}}`

Partitions the members of each complex in `complexes`

into a new set of complexes. The complexes in `complexes`

are assumed to be sorted in a counter-clockwise order around the apex of each complex. The partitioning is done so that the original set of members are now correctly split into their own complexes, since the original complexes might not have formed a properly contiguous set of small angles.

`DelaunayTriangulation.point_closest_to_line`

— Function```
point_closest_to_line(a, b, p, q) -> Certificate
point_closest_to_line(tri::Triangulation, i, j, u, v) -> Certificate
```

Given a line `ℓ`

through `(a, b)`

(or through the vertices `(i, j)`

), tests if `p`

(or the vertex `u`

) is closer to `ℓ`

than `q`

(or the vertex `v`

), assuming that `p`

and `q`

are to the left of `ℓ`

, returning a `Certificate`

which is one of:

`Closer`

:`p`

is closer to`ℓ`

.`Further`

:`q`

is closer to`ℓ`

.`Equidistant`

:`p`

and`q`

are the same distance from`ℓ`

.

`DelaunayTriangulation.point_position_on_line_segment`

— Function```
point_position_on_line_segment(a, b, p) -> Certificate
point_position_on_line_segment(tri::Triangulation, i, j, u) -> Certificate
```

Given a point `p`

(or vertex `u`

) and the line segment `(a, b)`

(or edge `(i, j)`

), assuming `p`

to be collinear with `a`

and `b`

, computes the position of `p`

relative to the line segment. The returned value is a `Certificate`

which is one of:

`On`

:`p`

is on the line segment, meaning between`a`

and`b`

.`Degenerate`

: Either`p == a`

or`p == b`

, i.e.`p`

is one of the endpoints.`Left`

:`p`

is off and to the left of the line segment.`Right`

:`p`

is off and to the right of the line segment.

`DelaunayTriangulation.point_position_relative_to_circle`

— Method`point_position_relative_to_circle(a, b, c, p) -> Certificate`

Given a circle through the coordinates `(a, b, c)`

, assumed to be positively oriented, computes the position of `p`

relative to the circle. Returns a `Certificate`

, which is one of:

`Inside`

:`p`

is inside the circle.`On`

:`p`

is on the circle.`Outside`

:`p`

is outside the triangle.

`DelaunayTriangulation.point_position_relative_to_circumcircle`

— Function```
point_position_relative_to_circumcircle(tri::Triangulation, i, j, k, ℓ) -> Certificate
point_position_relative_to_circumcircle(tri::Triangulation, T, ℓ) -> Certificate
```

Tests the position of the vertex `ℓ`

of `tri`

relative to the circumcircle of the triangle `T = (i, j, k)`

. The returned value is a `Certificate`

, which is one of:

`Outside`

:`ℓ`

is outside of the circumcircle of`T`

.`On`

:`ℓ`

is on the circumcircle of`T`

.`Inside`

:`ℓ`

is inside the circumcircle of`T`

.

The circumcircle of a ghost triangle is defined as the oriented outer halfplane of the solid edge of the triangle. See `point_position_relative_to_oriented_outer_halfplane`

.

If `tri`

is a weighted triangulation, then an orientation test is instead applied, testing the orientation of the lifted companions of each point to determine if `ℓ`

is above or below the witness plane relative to `(i, j, k)`

. For ghost triangles, the same rule applies, although if the vertex is on the solid edge of the ghost triangle then, in addition to checking `point_position_relative_to_oriented_outer_halfplane`

, we must check if the new vertex is not submerged by the adjoining solid triangle.

`DelaunayTriangulation.point_position_relative_to_curve`

— Method`point_position_relative_to_curve(e::AbstractParametricCurve, p) -> Certificate`

Returns the position of the point `p`

relative to the curve `c`

. This function returns a [`Certificate`

]:

`Left`

:`p`

is to the left of`c`

.`Right`

:`p`

is to the right of`c`

.`On`

:`p`

is on`c`

.

`DelaunayTriangulation.point_position_relative_to_curve`

— Method`point_position_relative_to_curve(enricher::BoundaryEnricher, curve_index, p) -> Certificate`

Returns a `Certificate`

which is

`Left`

: If`p`

is to the left of the`curve_index`

th curve.`Right`

: If`p`

is to the right of the`curve_index`

th curve.`On`

: If`p`

is on the`curve_index`

th curve.

`DelaunayTriangulation.point_position_relative_to_curve`

— Method`point_position_relative_to_curve(L::LineSegment, p) -> Certificate`

Returns the position of `p`

relative to `L`

, returning a `Certificate`

:

`Left`

:`p`

is to the left of`L`

.`Right`

:`p`

is to the right of`L`

.`On`

:`p`

is on`L`

.

See also `point_position_relative_to_line`

.

`DelaunayTriangulation.point_position_relative_to_diametral_circle`

— Method`point_position_relative_to_diametral_circle(p, q, r) -> Certificate`

Given an edge `(p, q)`

and a point `r`

, returns the position of `r`

relative to the diametral circle of `(p, q)`

. The returned value is a `Certificate`

, which is one of:

`Inside`

:`r`

is inside the diametral circle.`On`

:`r`

is on the diametral circle.`Outside`

:`r`

is outside the diametral circle.

**Extended help**

The check is done by noting that a point is in the diametral circle if, and only if, the angle at `r`

is obtuse.

`DelaunayTriangulation.point_position_relative_to_diametral_lens`

— Function`point_position_relative_to_diametral_lens(p, q, r, lens_angle=30.0) -> Certificate`

Given an edge `(p, q)`

and a point `r`

, returns the position of `r`

relative to the diametral lens of `(p, q)`

with lens angle `lens_angle`

(in degrees). The returned value is a `Certificate`

, which is one of:

`Inside`

:`r`

is inside the diametral lens.`On`

:`r`

is on the diametral lens.`Outside`

:`r`

is outside the diametral lens.

This function assumes that the lens angle is at most 45°.

**Extended help**

The diametral lens is slightly similar to a diametral circle. Let us first define the standard definition of a diametral lens, where `lens_angle = 30°`

, and then we define its generalisation. The standard definition was introduced by Shewchuk in 2002 in this paper, and the generalisation was originally described in Section 3.4 of Shewchuk's 1997 PhD thesis here (as was the standard definition, of course).

Standard definition: Let the segment be `s ≔ (p, q)`

and let `ℓ`

be the perpendicular bisector of `s`

. Define two circles `C⁺`

and `C⁻`

whose centers lie left and right of `s`

, respectively, both the same distance away from the midpoint `m = (p + q)/2`

. By placing each disk a distance `|s|/(2√3)`

away from `m`

and extending the disks so that they both touch `p`

and `q`

, meaning they each have radius `|s|/√3`

, we obtain disks that touch `p`

and `q`

as well as the center of the other disk. The intersection of the two disks defines the diametral lens. The lens angle associated with this lens is `30°`

, as we could draw lines between `p`

and `q`

and the poles of the disks to form isosceles triangles on each side, giving angles of `30°`

at `p`

and `q`

.

Generalised definition: The generalisation of the above definition aims to generalise the lens angle to some angle `θ`

. In particular, let us draw a line from `p`

towards some point `u`

which is left of `s`

and on the perpendicular bisector, where the line is at an angle `θ`

. This defines a triplet of points `(p, q, u)`

from which we can define a circle, and similarly for a point `v`

right of `s`

. The intersection of these two circles is the diametral lens with angle `θ`

. We can also figure out how far `u`

is along the perpendicular bisector, i.e. how far away it is from `(p + q)/2`

, using basic trigonometry. Let `m = (p + q)/2`

, and consider the triangle `△pmu`

. The side lengths of this triangle are `|pm| = |s|/2`

, `|mu| ≔ b`

, and `|up| ≔ c`

. Let us first compute `c`

. We have `cos(θ) = |pm|/|up| = |s|/(2c)`

, and so `c = |s|/(2cos(θ))`

. So, `sin(θ) = |mu|/|up| = b/c`

, which gives `b = csin(θ) = |s|sin(θ)/(2cos(θ)) = |s|tan(θ)/2`

. So, `u`

is a distance `|s|tan(θ)/2`

from the midpoint. Notice that in the case `θ = 30°`

, `tan(θ) = √3/3`

, giving `b = |s|√3/6 = |s|/(2√3)`

, which is the same as the standard definition.

To test if a point `r`

is inside the diametral lens with lens angle `θ°`

, we simply have to check the angle at that point, i.e. the angle at `r`

in the triangle `pqr`

. If this angle is greater than `180° - 2θ°`

, then `r`

is inside of the lens. This result comes from Shewchuk (2002). Note that this is the same as a diametral circle in the case `θ° = 45°`

.

`DelaunayTriangulation.point_position_relative_to_line`

— Function```
point_position_relative_to_line(a, b, p) -> Certificate
point_position_relative_to_line(tri::Triangulation, i, j, u) -> Certificate
```

Tests the position of `p`

(or the vertex `u`

of `tri`

) relative to the edge `(a, b)`

(or the edge with vertices `(i, j)`

of `tri`

), returning a `Certificate`

which is one of:

`Left`

:`p`

is to the left of the line.`Collinear`

:`p`

is on the line.`Right`

:`p`

is to the right of the line.

`DelaunayTriangulation.point_position_relative_to_oriented_outer_halfplane`

— Method`point_position_relative_to_oriented_outer_halfplane(a, b, p) -> Certificate`

Given an edge with coordinates `(a, b)`

and a point `p`

, tests the position of `p`

relative to the oriented outer halfplane defined by `(a, b)`

. The returned value is a `Certificate`

, which is one of:

`Outside`

:`p`

is outside of the oriented outer halfplane, meaning to the right of the line`(a, b)`

or collinear with`a`

and`b`

but not on the line segment`(a, b)`

.`On`

:`p`

is on the line segment`[a, b]`

.`Inside`

:`p`

is inside of the oriented outer halfplane, meaning to the left of the line`(a, b)`

.

**Extended help**

The oriented outer halfplane is the union of the open halfplane defined by the region to the left of the oriented line `(a, b)`

, and the open line segment `(a, b)`

.

`DelaunayTriangulation.point_position_relative_to_triangle`

— Function```
point_position_relative_to_triangle(a, b, c, p) -> Certificate
point_position_relative_to_triangle(tri::Triangulation, i, j, k, u) -> Certificate
point_position_relative_to_triangle(tri::Triangulation, T, u) -> Certificate
```

Given a positively oriented triangle with coordinates `(a, b, c)`

(or triangle `T = (i, j, k)`

of `tri`

), computes the position of `p`

(or vertex `u`

) relative to the triangle. The returned value is a `Certificate`

, which is one of:

`Outside`

:`p`

is outside of the triangle.`On`

:`p`

is on one of the edges.`Inside`

:`p`

is inside the triangle.

If `T`

is a ghost triangle, then it is not checked if the point is on any of the ghost edges,

`DelaunayTriangulation.point_position_relative_to_witness_plane`

— Method`point_position_relative_to_witness_plane(tri::Triangulation, i, j, k, ℓ) -> Certificate`

Given a positively oriented triangle `T = (i, j, k)`

of `tri`

and a vertex `ℓ`

of `tri`

, returns the position of `ℓ`

relative to the witness plane of `T`

. The returned value is a `Certificate`

, which is one of:

`Above`

:`ℓ`

is above the witness plane of`T`

.`On`

:`ℓ`

is on the witness plane of`T`

.`Below`

:`ℓ`

is below the witness plane of`T`

.

**Extended help**

The witness plane of a triangle is defined as the plane through the triangle `(i⁺, j⁺, k⁺)`

where, for example, `pᵢ⁺ = (x, y, x^2 + y^2 - wᵢ)`

is the lifted companion of `i`

and `(x, y)`

are the coordinates of the `i`

th vertex. Moreover, by the orientation of `ℓ`

relative to this witness plane we are referring to `ℓ⁺`

's position, not the plane point `ℓ`

.

`DelaunayTriangulation.points_are_unique`

— Method`points_are_unique(points) -> Bool`

Returns `true`

if all points in `points`

are unique.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [1.0 2.0 3.0 4.0 5.0; 0.0 5.5 2.0 1.3 17.0]
2×5 Matrix{Float64}:
1.0 2.0 3.0 4.0 5.0
0.0 5.5 2.0 1.3 17.0
julia> DelaunayTriangulation.points_are_unique(points)
true
julia> points[:, 4] .= points[:, 1];
julia> DelaunayTriangulation.points_are_unique(points)
false
```

`DelaunayTriangulation.pole_of_inaccessibility`

— Method`pole_of_inaccessibility(points, boundary_nodes; precision = one(number_type(points)))`

Finds the pole of inaccessibility for the polygon defined by `points`

and `boundary_nodes`

. The `boundary_nodes`

must match the specification given in the documentation. See also `check_args`

for this specification.

**Arguments**

`points`

: The points defining the polygon.`boundary_nodes`

: The boundary nodes defining the polygon.

**Keyword Arguments**

`precision=one(number_type(points))`

: The precision of the returned pole. The default is`one(number_type(points))`

.

**Outputs**

`x`

: The x-coordinate of the pole.`y`

: The y-coordinate of the pole.

**Extended help**

The pole of inaccessibility is the point within a polygon that is furthest from an edge. For DelaunayTriangulation.jl, this is useful as it is a representative point for ghost edges that is guaranteed to be inside the polygon, in contrast to for example a centroid which is not always inside the polygon. Some useful links are this blog post and the the original repo. Our implementation is partially based on on the python implementation and this other Julia implementation.

`DelaunayTriangulation.polygon_bounds`

— Function`polygon_bounds(points, boundary_nodes, check_all_curves=Val(false)) -> (Number, Number, Number, Number)`

Computes the bounding box of the polygon defined by `(points, boundary_nodes)`

. The `boundary_nodes`

must match the specification in the documentation and in `check_args`

. If `check_all_curves`

is `true`

, then the bounding box of the union of all curves of the `polygon`

is computed instead of just the first curve.

`DelaunayTriangulation.polygon_bounds`

— Function`polygon_bounds(vorn::VoronoiTessellation, unbounded_extension_factor=0.0; include_polygon_vertices=true) -> (Number, Number, Number, Number)`

Gets the bounding box for the Voronoi tessellation `vorn`

.

**Arguments**

`vorn::VoronoiTessellation`

: The Voronoi tessellation.`unbounded_extension_factor=0.0`

: The factor by which to extend the bounding box for unbounded polygons.

**Keyword Arguments**

`include_polygon_vertices=true`

: If`true`

, then the bounding box will also include the polygon vertices. Otherwise, only the generators are included.

**Output**

`xmin`

: Given by`xmin′ - unbounded_extension_factor * (xmin′ - xmin′)`

, where`xmin′`

is the original minimum`x`

-coordinate of the computed bounding box and similarly for`xmax′`

.`xmax`

: Given by`xmax′ + unbounded_extension_factor * (xmax′ - xmax′)`

, where`xmax′`

is the original maximum`x`

-coordinate of the computed bounding box and similarly for`xmin′`

.`ymin`

: Given by`ymin′ - unbounded_extension_factor * (ymin′ - ymin′)`

, where`ymin′`

is the original minimum`y`

-coordinate of the computed bounding box and similarly for`ymax′`

.`ymax`

: Given by`ymax′ + unbounded_extension_factor * (ymax′ - ymax′)`

, where`ymax′`

is the original maximum`y`

-coordinate of the computed bounding box and similarly for`ymin′`

.

`DelaunayTriangulation.polygon_features`

— Method`polygon_features(points, boundary_nodes) -> (Number, NTuple{2, Number})`

Computes the signed area and centroid of the polygon defined by `(points, boundary_nodes)`

. The `boundary_nodes`

must match the specification in the documentation and in `check_args`

.

`DelaunayTriangulation.polygon_features`

— Method`polygon_features(vor::VoronoiTessellation, i) -> (Number, NTuple{2, Number})`

Gets the area and centroid of the polygon with index `i`

in `vor`

.

`DelaunayTriangulation.polygonise`

— Method`polygonise(points, boundary_nodes, boundary_curves; n=4096)`

Fills out a set of points for a curve-bounded domain for use with `PolygonHierarchy`

.

If the boundary curves are complicated so that they take a lot of points in order to be accurately resolved, then you should increase `n`

.

**Arguments**

`points`

: The point set.`boundary_nodes`

: The boundary nodes.`boundary_curves`

: The boundary curves.

**Keyword Arguments**

`n=4096`

: The number of points to use for filling in each boundary curves.

**Output**

`new_points`

: The points defining the filled out boundaries.`new_boundary_nodes`

: The boundary nodes associated with`new_points`

.

If the boundary is not curve bounded, then `new_points`

and `new_boundary_nodes`

remain aliased with the input `points`

and `boundary_nodes`

.

`DelaunayTriangulation.pop_child!`

— Method`pop_child!(node::AbstractNode)`

Removes the last child of `node`

via `pop!`

.

`DelaunayTriangulation.pop_point!`

— Function`pop_point!(points)`

Pops the last point from `points`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [(1.0, 2.0), (1.3, 5.3)]
2-element Vector{Tuple{Float64, Float64}}:
(1.0, 2.0)
(1.3, 5.3)
julia> DelaunayTriangulation.pop_point!(points) # returns the popped vector
(1.3, 5.3)
julia> points
1-element Vector{Tuple{Float64, Float64}}:
(1.0, 2.0)
```

`DelaunayTriangulation.pop_point!`

— Method`pop_point!(tri::Triangulation)`

Pops the last point from the points of `tri`

.

`DelaunayTriangulation.popfirst_segment!`

— Method`popfirst_segment!(queue::RefinementQueue) -> Edge`

Dequeue the next segment from `queue`

, returning the segment and its squared length.

`DelaunayTriangulation.popfirst_triangle!`

— Method`popfirst_triangle!(queue::RefinementQueue) -> (Triangle, Number)`

Dequeue the next triangle from `queue`

, returning the triangle and its radius-edge ratio.

`DelaunayTriangulation.postprocess_triangulate!`

— Method`postprocess_triangulate!(tri; delete_ghosts=false, delete_empty_features=true, recompute_representative_points=true)`

Postprocesses the triangulation `tri`

after it has been constructed using `triangulate`

. This includes:

- Deleting ghost triangles using
`delete_ghost_triangles!`

if`delete_ghosts`

is`true`

. - Clearing empty features using
`clear_empty_features!`

if`delete_empty_features`

is`true`

. - Recomputing the representative points using
`compute_representative_points!`

if`recompute_representative_points`

is`true`

.

`DelaunayTriangulation.postprocess_triangulate_convex!`

— Method`postprocess_triangulate_convex!(tri::Triangulation, S; delete_ghosts, delete_empty_features)`

Postprocesses the completed triangulation `tri`

of the convex polygon `S`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`S`

: The vertices of the convex polygon, as in`triangulate_convex`

.

**Keyword Arguments**

`delete_ghosts=false`

: If`true`

, the ghost triangles are deleted after triangulation.`delete_empty_features=true`

: If`true`

, the empty features are deleted after triangulation.

**Output**

There are no output, as `tri`

is modified in-place. The postprocessing that is done is:

- The convex hull of
`tri`

is set to`S`

. - The ghost triangles are deleted if
`delete_ghosts=true`

. - The empty features are deleted if
`delete_empty_features=true`

. - The representative points are set to the centroid of
`S`

.

`DelaunayTriangulation.prepare_add_voronoi_polygon`

— Method`prepare_add_voronoi_polygon(vorn::VoronoiTessellation, i) -> (Vector, Vector)`

Prepare to add a Voronoi polygon for the vertex `i`

to the Voronoi tessellation `vorn`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`i`

: The vertex.

**Outputs**

`S`

: The surrounding polygon of`i`

. See`get_surrounding_polygon`

.`B`

: The buffer for the circumcenters. This is an empty`Vector{I}`

, where`I = integer_type(tri)`

.

`DelaunayTriangulation.prepare_initial_edge`

— Function`prepare_initial_edge(tri::Triangulation, edges, p, q, rng::AbstractRNG=Random.default_rng()) -> (Vertex, Vertex, Point, Point, Certificate, Certificate)`

Selects a random edge from the set of edges `edges`

and computes the certificates for the points corresponding to the initial and terminal vertices of the edge.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`edges`

: The set of edges to sample from.`p`

: The initial point.`q`

: The query point.`rng::AbstractRNG=Random.default_rng()`

: The random number generator to use.

**Outputs**

`i`

: The initial vertex of the edge.`j`

: The terminal vertex of the edge.`pᵢ`

: The point corresponding to`i`

.`pⱼ`

: The point corresponding to`j`

.`line_cert_i`

: The`Certificate`

for`pᵢ`

's position relative to the oriented line`pq`

.`line_cert_j`

: The`Certificate`

for`pⱼ`

's position relative to the oriented line`pq`

.

`DelaunayTriangulation.prepare_vertex_linked_list`

— Method`prepare_vertex_linked_list(V) -> ShuffledPolygonLinkedList`

Given a list of polygon vertices `V`

, returns the doubly-linked list of polygon vertices.

**Arguments**

`V`

: The list of polygon vertices.

**Outputs**

`list::ShuffledPolygonLinkedList`

: A`ShuffledPolygonLinkedList`

. In`list`

,`prev[begin]`

,`prev[end]`

,`next[begin]`

, and`next[end]`

are all`0`

as are`shuffled_indices[begin]`

and`shuffled_indices[end]`

. Moreover,`shuffled_indices`

will not have been shuffled yet.

`DelaunayTriangulation.previndex_circular`

— Method`previndex_circular(C, i) -> Integer`

Returns the previous index before `i`

in the circular vector `C`

.

`DelaunayTriangulation.process_collinear_segments!`

— Method`process_intersecting_triangles!(tri::Triangulation, e, collinear_segments; rng::AbstractRNG=Random.default_rng()) -> Bool`

Given segments in `collinear_segments`

that are collinear with an edge `e`

, updates `tri`

so that this edge `e`

is instead split so that it is instead represented by `collinear_segments`

. These new segments will be placed into the triangulation using `add_segment!`

.

See also `connect_segments!`

, `extend_segments!`

, `split_segment!`

and `split_boundary_edge_at_collinear_segments!`

.

`DelaunayTriangulation.process_intersection_points!`

— Method```
process_intersection_points!(polygon_edge_queue, vorn, current_incident_polygon,
left_edge_intersectors, right_edge_intersectors, current_edge_intersectors,
left_edge, right_edge, current_edge, processed_pairs, segment_intersections, boundary_sites)
```

Process the intersection points in `left_edge_intersectors`

, `right_edge_intersectors`

, and `current_edge_intersectors`

and add the new edges to `polygon_edge_queue`

if necessary. Special care is taken to not miss any corner points.

**Arguments**

`polygon_edge_queue`

: The queue of edges that need to be processed.`vorn`

: The`VoronoiTessellation`

.`current_incident_polygon`

: The index of the current polygon being processed.`left_edge_intersectors`

: The intersection points of`left_edge`

with other edges.`right_edge_intersectors`

: The intersection points of`right_edge`

with other edges.`current_edge_intersectors`

: The intersection points of`current_edge`

with other edges.`left_edge`

: The left edge of the current polygon.`right_edge`

: The right edge of the current polygon.`current_edge`

: The current edge of the current polygon.`processed_pairs`

: A set of pairs of edges and polygons that have already been processed.`segment_intersections`

: A dictionary of segment intersections.`boundary_sites`

: A dictionary of boundary sites.

**Outputs**

There are no outputs, but the caches and queues are updated in-place.

**Extended help**

The rules are based on the paper "Efficient Computation of Clipped Voronoi Diagram for Mesh Generation" by Yan, Wang, Levy, and Liu. Namely, an edge that intersects a boundary edge and one adjacent to it has its shared vertex added to the queue together with the current polygon (`current_incident_polygon`

) being considered, and any intersections have the adjacent polygon added to the queue together with the intersecting edge. (These are not strictly the rules in the paper.)

This function works as follows:

- First, assuming that there is more than one triangle in the underlying triangulation of
`vorn`

, we need to consider`left_edge`

and`right_edge`

individually. - The procedure for each edge is the same, so here we just describe the
`left_edge`

. If there are any intersectors with the`left_edge`

, and neither of`(left_edge, current_incident_polygon)`

or`(reverse_edge(left_edge), current_incident_polygon)`

have already been processed (i.e., in`processed_pairs`

), then we enqueue`(left_edge, i)`

and`(left_edge, j)`

into`polygon_edge_queue`

, where`i`

and`j`

are the vertices of`left_edge`

which correspond to polygons. This will ensure that we can find intersections next to this polygon. - After enqueueing these pairs, we also need to protect against corner points, which we check for by considering
`current_incident_polygon ∈ all_indices`

, where`all_indices`

are the vertices of`left_edge`

,`right_edge`

, and`current_edge`

. If this is true, and if the shared vertex of`current_edge`

and`left_edge`

is equal to`current_incident_polygon`

, then we need to add the point generator of`current_incident_polygon`

as an intersection. This need comes from having to worry about corners, i.e. points where the two unbounded polygons meet and go directly left and right of a vertex so that that vertex is not considered an intersection; this point needs to be included. - Once the
`left_edge`

and`right_edge`

have been processed as above, we need to then consider all of`left_edge`

,`right_edge`

, and`current_edge`

, and each of the intersections through the respective edge. This step is done regardless of whether there is a single triangle in the underlying triangulation. The procedure for each edge is the same, so let us just describe the`current_edge`

. For each edge`uv`

in the`current_edge_intersectors`

, we need to get the polygon adjacent to that edge. Then, if`(current_edge, adjacent_incident_polygon)`

or`(reverse_edge(current_edge), adjacent_incident_polygon)`

have not been processed, we enqueue`(current_edge, adjacent_incident_polygon)`

. - Once the edges have all been processed as above, we return.

`DelaunayTriangulation.process_polygon!`

— Method`process_polygon!(vorn::VoronoiTessellation, e, incident_polygon, boundary_sites, segment_intersections, intersected_edge_cache, exterior_circumcenters, equal_circumcenter_mapping) -> (Edge, Edge, Edge)`

Processes the polygon `incident_polygon`

for all of its intersections based on the boundary edge `e`

.

**Arguments**

`vorn::VoronoiTessellation`

: The`VoronoiTessellation`

.`e`

: The edge on the boundary being considered.`incident_polygon`

: The index of the polygon being considered.`boundary_sites`

: The mapping from the indices of the sites on the boundary to the indices of the edges on the boundary that they intersect.`segment_intersections`

: The list of segment intersections.`intersected_edge_cache`

: A cache of the edges that have been intersected by the ray from`u`

to`v`

.`exterior_circumcenters`

: A list of the circumcenters of the sites that are outside the convex hull of the sites on the boundary.`equal_circumcenter_mapping`

: A mapping from the indices of the segment intersections that are equal to the circumcenter of a site to the index of the site.

**Outputs**

`left_edge`

: The edge to the left of`e`

on the boundary.`right_edge`

: The edge to the right of`e`

on the boundary.`e`

: The edge on the boundary being considered.

In addition to these outputs, the caches are also updated in-place.

**Extended help**

This function works as follows:

- First, for the current edge
`e`

, we get the edges`left_edge`

and`right_edge`

that neighbour it via`get_neighbouring_boundary_edges`

. - For each edge of the
`incident_polygon`

, we need to process it depending on whether the edge`(u, v)`

is finite, between two ghosts, going out to infinity, or coming in from infinity. If the edge is between two ghosts, we skip the edge. For rays that go out or in to infinity, we use`process_ray_intersection!`

and`process_ray_intersection_with_other_edges!`

to process the intersection of the ray with the boundary edges. The function`process_ray_intersection_with_other_edges!`

is needed since rays going out to infinity may have to go through other boundary edges in order to do so, e.g. at a corner it may be that it crosses two boundary edges. For finite segments,`process_segment_intersection!`

is used to process the intersection. We apply this function with each of`e`

,`left_edge`

, and`right_edge`

to check for all intersections. - The function is done once each of the polygon edges has been considered.

`DelaunayTriangulation.process_ray_intersection!`

— Method```
process_ray_intersection!(
vorn::VoronoiTessellation,
u,
v,
incident_polygon,
intersected_edge_cache,
segment_intersections,
boundary_sites,
exterior_circumcenters,
equal_circumcenter_mapping) -> Point
```

Process the intersection of the Voronoi polygon of the site `u`

with the ray emanating from the circumcenter of the site `v`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`u`

: The index of the site`u`

, given as a ghost vertex for the associated ghost triangle.`v`

: The index of the site`v`

.`incident_polygon`

: The index of the Voronoi polygon of the site`u`

that is incident to the ray emanating from the circumcenter of the site`v`

.`intersected_edge_cache`

: The list of intersected edges currently being considered.`segment_intersections`

: The list of segment intersections.`boundary_sites`

: A mapping from boundary sites to the indices of the segment intersections that are incident to the boundary site.`exterior_circumcenters`

: The list of circumcenters of sites that are outside the boundary.`equal_circumcenter_mapping`

: A mapping from the indices of the segment intersections that are equal to the circumcenter of a site to the index of the site.

**Outputs**

`p`

: The coordinates of the intersection.

In addition to the point `p`

, `add_segment_intersection!`

is also updated to incorporate the new intersection point, as is `add_to_intersected_edge_cache!`

.

`DelaunayTriangulation.process_ray_intersection_with_other_edges!`

— Method```
process_ray_intersection_with_other_edges!(vorn::VoronoiTessellation,
u,
v,
e,
left_edge,
right_edge,
r,
segment_intersections,
boundary_sites,
incident_polygon,
equal_circumcenter_mapping,
intersected_edge_cache)
```

Process the intersection of the ray from the ghost site `u`

to the site `v`

with the edges `e`

, `left_edge`

and `right_edge`

.

**Arguments**

`vorn::VoronoiTessellation`

: The`VoronoiTessellation`

.`u`

: The index of the ghost site.`v`

: The index of the site`u`

is going to.`e`

: The edge on the boundary being considered.`left_edge`

: The edge to the left of`e`

on the boundary.`right_edge`

: The edge to the right of`e`

on the boundary.`r`

: The coordinates of the intersection of the ray from`u`

to`v`

with some edge. If`any(isnan, r)`

, then the ray does not intersect any edge and we skip.`segment_intersections`

: The list of segment intersections.`boundary_sites`

: The mapping from the indices of the sites on the boundary to the indices of the edges on the boundary that they intersect.`incident_polygon`

: The index of the polygon that contains the intersection of the ray from`u`

to`v`

with the boundary.`equal_circumcenter_mapping`

: A mapping from the indices of the segment intersections that are equal to the circumcenter of a site to the index of the site.`intersected_edge_cache`

: A cache of the edges that have been intersected by the ray from`u`

to`v`

.

**Outputs**

There are no outputs, but `add_segment_intersection!`

and `add_to_intersected_edge_cache!`

are used to update the intersection objects.

`DelaunayTriangulation.process_roots_and_residuals!`

— Method`process_roots_and_residuals!(roots, residuals, tol) -> Vector{Float64}`

Processes the roots and residuals of a root-finding algorithm. This function removes all `NaN`

values from `roots`

and `residuals`

, sorts the roots in ascending order, and removes all roots with residuals greater than `tol`

. The returned vector is the vector of roots with duplicates (i.e. roots that are within `tol`

of each other) removed.

`DelaunayTriangulation.process_segment_intersection!`

— Method```
process_segment_intersection!(
vorn::VoronoiTessellation,
u,
v,
e,
incident_polygon,
intersected_edge_cache,
segment_intersections,
boundary_sites,
exterior_circumcenters,
equal_circumcenter_mapping) -> Point
```

Process the intersection of the Voronoi polygon's edge `(u, v)`

with the edge `e`

of the boundary, returning the coordinates of the intersection and updating via `add_segment_intersection!`

.

**Arguments**

`vorn`

: The`VoronoiTessellation`

.`u`

: The index of the site`u`

.`v`

: The index of the site`v`

.`e`

: The edge`e`

of the boundary.`incident_polygon`

: The index of the Voronoi polygon currently being considered.`intersected_edge_cache`

: The list of intersected edges currently being considered.`segment_intersections`

: The list of segment intersections.`boundary_sites`

: A mapping from boundary sites to the indices of the segment intersections that are incident to the boundary site.`exterior_circumcenters`

: The list of circumcenters of sites that are outside the boundary.`equal_circumcenter_mapping`

: A mapping from the indices of the segment intersections that are equal to the circumcenter of a site to the index of the site.

**Outputs**

`p`

: The coordinates of the intersection. If there is no intersection, this is`(NaN, NaN)`

.

In addition to the point `p`

, `add_segment_intersection!`

is also updated to incorporate the new intersection point, as is `add_to_intersected_edge_cache!`

.

`DelaunayTriangulation.protect_against_bad_division!`

— Method`protect_against_bad_division!(roots, residuals, val, i) -> Bool`

Protects against bad division in root-finding algorithms. This function checks if `val`

is close to `0`

or if `roots[i]`

is outside of `[0, 1]`

. If either of these conditions are true, then `roots[i]`

and `residuals[i]`

are set to `NaN`

and `true`

is returned. Otherwise, `false`

is returned.

`DelaunayTriangulation.push_point!`

— Function```
push_point!(points, x, y)
push_point!(points, p) = push_point!(points, getx(p), gety(p))
```

Pushes the point `p = (x, y)`

into `points`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [(1.0, 3.0), (5.0, 1.0)]
2-element Vector{Tuple{Float64, Float64}}:
(1.0, 3.0)
(5.0, 1.0)
julia> DelaunayTriangulation.push_point!(points, 2.3, 5.3)
3-element Vector{Tuple{Float64, Float64}}:
(1.0, 3.0)
(5.0, 1.0)
(2.3, 5.3)
julia> DelaunayTriangulation.push_point!(points, (17.3, 5.0))
4-element Vector{Tuple{Float64, Float64}}:
(1.0, 3.0)
(5.0, 1.0)
(2.3, 5.3)
(17.3, 5.0)
```

`DelaunayTriangulation.push_point!`

— Method```
push_point!(tri::Triangulation, x, y)
push_point!(tri::Triangulation, p)
```

Pushes the point `p = (x, y)`

into the points of `tri`

.

`DelaunayTriangulation.push_polygon_point!`

— Method```
push_polygon_point!(vor::VoronoiTessellation, p)
push_polygon_point!(vor::VoronoiTessellation, x, y)
```

Adds the point `p = (x, y)`

into the vector of polygon points of `vor`

.

`DelaunayTriangulation.random_edge`

— Function`random_edge([rng], E) -> E`

Get a random edge from `E`

.

**Examples**

```
julia> using DelaunayTriangulation, StableRNGs
julia> E = Set(((1,2),(10,15),(23,20)))
Set{Tuple{Int64, Int64}} with 3 elements:
(1, 2)
(23, 20)
(10, 15)
julia> rng = StableRNG(123);
julia> DelaunayTriangulation.random_edge(rng, E)
(10, 15)
julia> DelaunayTriangulation.random_edge(rng, E)
(10, 15)
julia> DelaunayTriangulation.random_edge(rng, E)
(23, 20)
```

```
julia> DelaunayTriangulation.random_edge(E)
(1, 2)
```

`DelaunayTriangulation.refine!`

— Method`refine!(tri::Triangulation; kwargs...)`

Refines the given `Triangulation`

`tri`

to meet the given quality constraints.

See the documentation for more information about mesh refinement, e.g. convergence issues and issues with small input-angles.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

to refine.

**Keyword Arguments**

`min_angle=30.0`

: The minimum angle constraint, in degrees.`max_angle=180.0`

: The maximum angle constraint, in degrees.

Maximum angle constraints are not currently implemented.

`min_area=get_area(tri) / 1e9`

: The minimum area constraint.`max_area=typemax(number_type(tri))`

: The maximum area constraint.`max_points=max(1_000, num_solid_vertices(tri))^2`

: The maximum number of vertices allowed in the triangulation. Note that this refers to`num_solid_vertices`

, not the amount returned by`num_points`

.`seditious_angle=20.0`

: The angle at which a triangle is considered seditious, in degrees. See`is_triangle_seditious`

.`custom_constraint=(tri, T) -> false`

: A custom constraint function that takes a`Triangulation`

and a triangle, and returns`true`

if the triangle should be refined and`false`

otherwise.`use_circumcenter=true`

: Whether to insert circumcenters for refining a triangle or generalised Steiner points.

Generalised Steiner points are not yet implemented. Thus, this argument must be `true`

(and the `steiner_scale`

keyword below is ignored).

`use_lens=true`

: Whether to use the diametral lens or the diametral circle for checking encroachment.`steiner_scale=0.999`

: The perturbation factor to use for generalised Steiner points if`use_circumcenter=false`

. (Not currently used - see above.)`rng=Random.default_rng()`

: The random number generator to use in case it is needed during point location.`concavity_protection=false`

: Whether to use concavity protection or not for`jump_and_march`

. Most likely not needed, but may help in pathological cases.

**Output**

The triangulation is refined in-place.

During refinement, points are often deleted, which may often lead to points in `get_points(tri)`

that do not appear anywhere in the triangulation. (This is why we recommend e.g. `each_solid_vertex`

over `each_point`

.) Similarly, since points are deleted, when two triangles have a common circumcenter it might happen (if they are near an input segment) that a point is duplicated inside `get_points(tri)`

, in case one circumcenter was deleted previously.

`DelaunayTriangulation.refine_itr!`

— Method`refine_itr!(tri::Triangulation, args::RefinementArguments)`

Performs a single iteration of the refinement algorithm.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

to refine.`args::RefinementArguments`

: The`RefinementArguments`

for the refinement.

**Output**

The triangulation is refined in-place.

`DelaunayTriangulation.remake_triangulation_with_constraints`

— Method`remake_triangulation_with_constraints(tri::Triangulation, segments, boundary_nodes) -> (Dict, Dict, Triangulation)`

Remakes the triangulation `tri`

so that it contains `segments`

and `boundary_nodes`

in its fields.

See also `replace_ghost_vertex_information`

.

**Arguments**

`tri::Triangulation`

: The triangulation to remake.`segments`

: The segments to add to the triangulation.`boundary_nodes`

: The boundary nodes to add to the triangulation.

**Outputs**

`new_ghost_vertex_map`

: The new ghost vertex map. This will not yet be added to the triangulation.`new_ghost_vertex_ranges`

: The new ghost vertex ranges. This will not yet be added to the triangulation.`new_tri::Triangulation`

: The new triangulation, now containing`boundary_nodes`

in the`boundary_nodes`

field and`segments`

in the`interior_segments`

field.

`DelaunayTriangulation.reorder_hierarchy!`

— Method`reorder_hierarchy!(hierarchy::PolygonHierarchy, points, boundary_nodes, new_tree::PolygonTree)`

Given a `new_tree`

that is not contained inside any other polygon in `hierarchy`

, adds it into `hierarchy`

. The existing trees are checked to see if they are contained inside `new_tree`

, and if so, they are added as children of `new_tree`

and removed from `hierarchy`

.

**Arguments**

`hierarchy::PolygonHierarchy`

: The`PolygonHierarchy`

to add`new_tree`

to.`points`

: The point set.`boundary_nodes`

: The boundary nodes.`new_tree::PolygonTree`

: The`PolygonTree`

to add to`hierarchy`

.

`DelaunayTriangulation.reorder_subtree!`

— Method`reorder_subtree!(hierarchy::PolygonHierarchy, points, boundary_nodes, tree::PolygonTree, new_tree)`

Given a `new_tree`

contained inside `tree`

, adds it into `hierarchy`

. The children of `tree`

are reordered if necessary, in case they are now contained inside `new_tree`

.

**Arguments**

`hierarchy::PolygonHierarchy`

: The`PolygonHierarchy`

to add`new_tree`

to.`points`

: The point set.`boundary_nodes`

: The boundary nodes.`tree::PolygonTree`

: The`PolygonTree`

to add`new_tree`

to.`new_tree::PolygonTree`

: The`PolygonTree`

to add to`hierarchy`

and`tree`

.

`DelaunayTriangulation.reorient_edge`

— Method`reorient_edge(enricher::BoundaryEnricher, i, j) -> NTuple{2,Integer}`

Given an edge `(i, j)`

, reorients it so that it is correctly oriented with the boundary. If `(i, j)`

is instead an interior segment rather than a boundary edge, then `(i, j)`

is returned.

`DelaunayTriangulation.replace!`

— Method`replace!(node::AbstractNode, left, right, original_bounding_box, tree::RTree)`

Replaces the `node`

in `tree`

with `left`

and `right`

. Returns `true`

if the `tree`

's bounding boxes had to be adjusted and `false`

otherwise.

`DelaunayTriangulation.replace_boundary_triangle_with_ghost_triangle`

— Method`replace_boundary_triangle_with_ghost_triangle(tri::Triangulation, V) -> Triangle`

Given a boundary triangle `V`

of `tri`

, returns the adjacent ghost triangle.

`DelaunayTriangulation.replace_ghost_triangle_with_boundary_triangle`

— Method`replace_ghost_triangle_with_boundary_triangle(tri::Triangulation, V) -> Triangle`

Given a ghost triangle `V`

of `tri`

, returns the adjacent boundary triangle.

`DelaunayTriangulation.replace_ghost_vertex_information`

— Method`replace_ghost_vertex_information(tri::Triangulation, ghost_vertex_map, ghost_vertex_ranges) -> Triangulation`

Replaces the ghost vertex information in `tri`

with `ghost_vertex_map`

and `ghost_vertex_ranges`

, using the results from `remake_triangulation_with_constraints`

.

**Arguments**

`tri::Triangulation`

: The triangulation to remake.`ghost_vertex_map`

: The ghost vertex map to add to the triangulation.`ghost_vertex_ranges`

: The ghost vertex ranges to add to the triangulation.

**Outputs**

`new_tri::Triangulation`

: The new triangulation, now containing`ghost_vertex_map`

in the`ghost_vertex_map`

field and`ghost_vertex_ranges`

in the`ghost_vertex_ranges`

field.

`DelaunayTriangulation.replace_next_edge!`

— Method`replace_next_edge!(enricher::BoundaryEnricher, apex, complex_id, member_id, next_edge)`

Replaces the next edge of the `member_id`

th member of the `complex_id`

th complex associated with `apex`

with `next_edge`

.

`DelaunayTriangulation.replace_next_edge!`

— Method`replace_next_edge!(complex::SmallAngleComplex, member_id, next_edge)`

Replaces the next edge of the `member_id`

th member of `complex`

with `next_edge`

.

See also `replace_next_edge`

.

`DelaunayTriangulation.replace_next_edge`

— Method`replace_next_edge(member::SmallAngleComplexMember{I}, next_edge) where {I} -> SmallAngleComplexMember{I}`

Returns a new `SmallAngleComplexMember`

with the same parent curve as `member`

but with `next_edge`

as the next edge.

`DelaunayTriangulation.reset!`

— Method`reset!(list::ShuffledPolygonLinkedList; rng::AbstractRNG=Random.default_rng())`

Resets the linked `list`

, so that `list.next[i] = mod1(i+1, list.k)`

and `list.prev[i] = mod1(i-1, list.k)`

, and also reshuffles the `list.shuffled_indices`

vector.

`DelaunayTriangulation.reset!`

— Method`reset!(c::RepresentativeCoordinates)`

Resets the coordinates of `c`

to zero.

`DelaunayTriangulation.reset_representative_points!`

— Method`reset_representative_points!(tri::Triangulation)`

Resets each representative point of `tri`

to the origin.

`DelaunayTriangulation.restart_jump_and_march`

— Method`restart_jump_and_march(tri::Triangulation, q, store_history, history, rng, maxiters, cur_iter, concavity_protection, num_restarts, use_barriers) -> Triangle[, Bool]`

Restart the `jump_and_march`

algorithm, or use `brute_force_search`

to find `q`

if `num_restarts ≥ 25`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`q`

: The query point.`store_history`

: Whether to store the history of the algorithm.`history`

: The history of the algorithm. If`store_history`

, then this should be a`PointLocationHistory`

object.`rng`

: The random number generator to use.`maxiters`

: The maximum number of iterations to perform before restarting the algorithm with`restart_jump_and_march`

.`cur_iter`

: The current iteration of the algorithm.`concavity_protection`

: Whether to use concavity protection. See`concavity_protection_check`

. This is only needed if your triangulation is not convex.`num_restarts`

: The number of times the algorithm has been restarted.`use_barriers`

: Whether to use barriers, stopping the algorithm at any segment.

**Outputs**

`V`

: The triangle containing`q`

.

In addition, if `use_barriers = Val(true)`

, then a second output is returned, which is a boolean indicating whether the algorithm reached a barrier (`true`

) or not (`false`

).

`DelaunayTriangulation.retriangulate`

— Method`retriangulate(tri::Triangulation, points=get_points(tri); kwargs...)`

Retriangulates the triangulation `tri`

using the points `points`

, returning a new `Triangulation`

.

**Arguments**

`tri::Triangulation`

: The triangulation to retriangulate.`points=get_points(tri)`

: The points to use for retriangulating the triangulation. By default, this is simply`get_points(tri)`

.

**Keyword Arguments**

`skip_points=Set(filter(i -> !has_vertex(tri, i), each_point_index(tri)))`

: The points to skip when inserting points into the triangulation.`kwargs...`

: Extra keyword arguments passed to`triangulate`

. Other keyword arguments, like`segments`

and`boundary_nodes`

, are automatically passed from the fields of`tri`

, but may be overridden by passing the corresponding keyword arguments.

`DelaunayTriangulation.retriangulate_fan!`

— Method`retriangulate_fan!(tri::Triangulation, tri_fan::Triangulation, fan, fan_triangles; rng::AbstractRNG=Random.default_rng())`

Given a sorted set of vertices `fan`

in a fan of triangles associated with `fan_triangles`

, retriangulates the fan, updating `tri`

to do so and using `tri_fan`

as a temporary triangulation. (This implements Lines 17–19 and Line 28 of the algorithms in this paper.)

`DelaunayTriangulation.reverse_edge`

— Method`reverse_edge(e) -> Edge`

Get the edge with the vertices of `e`

in reverse order.

**Examples**

```
julia> using DelaunayTriangulation
julia> e = (17, 3);
julia> DelaunayTriangulation.reverse_edge(e)
(3, 17)
julia> e = [1, 2];
julia> DelaunayTriangulation.reverse_edge(e)
2-element Vector{Int64}:
2
1
```

`DelaunayTriangulation.rotate_left!`

— Method`rotate_left!(parent::BalancedBSTNode{K}) -> BalancedBSTNode{K}`

Rotates a subtree rooted at `parent`

to the left, returning the new root of the subtree. This local operation is used to preserve the binary search tree property after inserting or deleting a node.

`DelaunayTriangulation.rotate_right!`

— Method`rotate_right!(parent::BalancedBSTNode{K}) -> BalancedBSTNode{K}`

Rotates a subtree rooted at `parent`

to the right, returning the new root of the subtree. This local operation is used to preserve the binary search tree property after inserting or deleting a node.

`DelaunayTriangulation.rotate_triangle`

— Method`rotate_triangle(T, rotation) -> Triangle`

Rotate the vertices of `T`

by `rotation`

. In particular, if `T = (i, j, k)`

:

`rotation = 0`

:`(i, j, k)`

`rotation = 1`

:`(j, k, i)`

`rotation = 2`

:`(k, i, j)`

- Otherwise, return
`rotate_triangle(T, rotation % 3)`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> T = (1, 2, 3)
(1, 2, 3)
julia> DelaunayTriangulation.rotate_triangle(T, 0)
(1, 2, 3)
julia> DelaunayTriangulation.rotate_triangle(T, 1)
(2, 3, 1)
julia> DelaunayTriangulation.rotate_triangle(T, 2)
(3, 1, 2)
julia> DelaunayTriangulation.rotate_triangle(T, 3)
(1, 2, 3)
```

`DelaunayTriangulation.sameside_predicate`

— Method`sameside_predicate(a, b, p) -> Integer`

Returns `ExactPredicates.sameside(p, a, b)`

where all three points are collinear, in particular we return:

`1`

:`a`

and`b`

are on the same side of`p`

on the line.`0`

:`a == p`

or`b == p`

.`-1`

:`a`

and`b`

are on different sides of`p`

on the line.

The difference in the argument order to ExactPredicates.jl is to match the convention that the main point being tested is the last argument.

`DelaunayTriangulation.search_down_adjacent_boundary_edges`

— Method`search_down_adjacent_boundary_edges(tri::Triangulation, k, q, direction_cert, q_pos_cert, next_vertex, store_history=Val(false), history=nothing, ghost_vertex=𝒢) -> (Bool, Certificate, Vertex, Vertex, Vertex)`

Starting at the boundary vertex `k`

, walks down the boundary in the direction of `q`

until finding `q`

or finding that it is outside of the triangulation.

See also `check_for_intersections_with_adjacent_boundary_edges`

, which uses this function to determine an initial direction to search along.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`k`

: The boundary vertex to start from.`q`

: The query point.`direction_cert`

: The direction of`q`

relative to the vertex`k`

along the boundary, defined from`check_for_intersections_with_adjacent_boundary_edges`

.`q_pos_cert`

: The position of`q`

relative to the vertex`k`

along the boundary, defined from`check_for_intersections_with_adjacent_boundary_edges`

.`next_vertex`

: The next vertex along the boundary in the direction of`q`

, defined from`check_for_intersections_with_adjacent_boundary_edges`

.`store_history=Val(false)`

: Whether to store the history of the algorithm.`history=nothing`

: The history of the algorithm. If`store_history`

, then this should be a`PointLocationHistory`

object.`ghost_vertex=𝒢`

: The ghost vertex corresponding to the boundary that`k`

resides on.

**Outputs**

`return_flag`

: Whether to return, or throw an exception.`q_pos_cert`

: A`Certificate`

that is`On`

if`q`

is on the edge`(u, v)`

, and`Outside`

if`q`

is outside of the triangulation.`u`

: If`is_on(q_pos_cert)`

, this is the first vertex of a positively oriented triangle that`q`

is on, so that`q`

is on the edge`(u, v)`

. Otherwise,`(u, v, w)`

is a ghost triangle close to`q`

.`v`

: If`is_on(q_pos_cert)`

, this is the second vertex of a positively oriented triangle that`q`

is on, so that`q`

is on the edge`(u, v)`

. Otherwise,`(u, v, w)`

is a ghost triangle close to`q`

.`w`

: If`is_on(q_pos_cert)`

, this is the third vertex of a positively oriented triangle that`q`

is on, so that`q`

is on the edge`(u, v)`

and`w = get_adjacent(tri, u, v)`

. Otherwise,`(u, v, w)`

is a ghost triangle close to`q`

.

This function assumes that the geometry is convex. The function will still be able to return, but `is_outside(q_pos_cert)`

may not necessarily mean `q`

is outside of the triangulation. The main function `jump_and_march`

will have to restart the algorithm if it is found that `is_outside(q_pos_cert)`

was incorrect.

**Extended help**

This function works by stepping along vertices on the boundaries in the direction specified by `direction_cert`

, using `search_right_down_adjacent_boundary_edges`

if `is_right(direction_cert)`

and `search_left_down_adjacent_boundary_edges`

otherwise. In these functions, a `while`

loop is used to keep stepping until `q_pos_cert`

, which is updated at each iteration, changes value.

`DelaunayTriangulation.segment_intersection_coordinates`

— Method`segment_intersection_coordinates(a, b, c, d) -> NTuple{2, Number}`

Given two segments `(a, b)`

and `(c, d)`

that are assumed to intersect, computes the coordinates of the intersection.

`DelaunayTriangulation.segment_vertices_adjoin_other_segments_at_acute_angle`

— Method`segment_vertices_adjoin_other_segments_at_acute_angle(tri::Triangulation, e) -> Int, Vertex`

Determines if the vertices of a segment `e`

of `tri`

adjoin other segments at an acute angle.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`e`

: The segment.

**Output**

`num_adjoin`

: The number of vertices of`e`

that adjoin other segments at an acute angle.`adjoin_vert`

: The vertex of`e`

that adjoins another segment at an acute angle if`num_adjoin == 1`

, and`∅`

otherwise.

`DelaunayTriangulation.select_initial_point`

— Function`select_initial_point(tri::Triangulation, q; kwargs...) -> Vertex`

Selects the initial point for `jump_and_march`

to start from.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`q`

: The query point. Can be either a point or a vertex - if it is a vertex, the corresponding point`get_point(tri, q)`

will be used.

**Keyword Arguments**

`point_indices=each_solid_vertex(tri)`

: The indices to sample from.`m=default_num_samples(num_vertices(point_indices))`

: The number of samples to take. Replacement is not used, so there may be duplicates.`try_points=()`

: A list of points to try in addition to those randomly sampled.`allow_boundary_points=!is_disjoint(tri)`

: Whether to allow boundary points to be selected.`rng=Random.default_rng()`

: The random number generator to use.

**Outputs**

`i`

: The index of the point closest to`q`

out of those queried.

`DelaunayTriangulation.select_initial_triangle_interior_vertex`

— Method`select_initial_triangle_interior_vertex(tri::Triangulation, k, q, store_history=Val(false), history=nothing, rng::AbstractRNG=Random.default_rng()) -> (Point, Vertex, Vertex, Point, Point)`

Selects the initial triangle for `jump_and_march`

to start from, for the case where `k`

is an interior vertex.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`k`

: The vertex to start from.`q`

: The query point.`store_history=Val(false)`

: Whether to store the history of the algorithm.`history=nothing`

: The history of the algorithm. If`store_history`

, then this should be a`PointLocationHistory`

object.`rng::AbstractRNG=Random.default_rng()`

: The random number generator to use.

**Outputs**

`p`

: The point corresponding to`k`

.`i`

: The initial vertex of the triangle.`j`

: The terminal vertex of the triangle.`pᵢ`

: The point corresponding to`i`

.`pⱼ`

: The point corresponding to`j`

.

This function assumes that the geometry is convex. To deal with this, when an infinite loop is detected we return `∅`

for both `i`

and `j`

, and then let `jump_and_march`

handle how to correct the algorithm from there.

**Extended help**

This part of the algorithm works by rotating around the vertex `k`

, looking for a triangle whose edges adjoining `k`

are to the left and to the right of `k`

. By choosing the initial edge at random via `prepare_initial_edge`

, and computing the position of `q`

relative to this initial edge, the rotation will be either clockwise or counter-clockwise, and the triangle is then found using either `select_initial_triangle_clockwise`

or `select_initial_triangle_counterclockwise`

, respectively.

In case the initial edge is collinear with the line `pq`

, where `p = get_point(tri, q)`

, then `fix_initial_collinear_edge_for_interior_vertex`

to find a non-collinear edge resample more edges from `prepare_initial_edge`

if necessary.

`DelaunayTriangulation.select_random_edge`

— Function`select_random_edge(tri::Triangulation, edges, rng::AbstractRNG=Random.default_rng()) -> (Vertex, Vertex, Point, Point)`

Selects a random edge from the set of edges `edges`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`edges`

: The set of edges to sample from.`rng::AbstractRNG=Random.default_rng()`

: The random number generator to use.

**Outputs**

`i`

: The initial vertex of the edge.`j`

: The terminal vertex of the edge.`pᵢ`

: The point corresponding to`i`

.`pⱼ`

: The point corresponding to`j`

.

`DelaunayTriangulation.select_random_vertex`

— Method`select_random_vertex(tri::Triangulation, list::ShuffledPolygonLinkedList, u, v, range, rng) -> Vertex`

Selects a random vertex that is not closer to the line `(u, v)`

than both of its neighbours.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`list::ShuffledPolygonLinkedList`

: The linked list of polygon vertices.`u`

,`v`

: The vertices of the line.`range`

: The range of indices of the vertices to select from.`rng::AbstractRNG`

: The random number generator to use.

**Outputs**

`j`

: The selected vertex.

`DelaunayTriangulation.select_shortest_edge_for_offcenter`

— Method`select_shortest_edge_for_offcenter(p, q, r, c, ℓ²) -> (NTuple{2, Number}, NTuple{2, Number}, NTuple{2, Number})`

Given a triangle `(p, q, r)`

with more than one edge attaining the shortest length, selects the appropriate shortest edge for `triangle_offcenter`

.

**Arguments**

`p`

: The first vertex of the triangle.`q`

: The second vertex of the triangle.`r`

: The third vertex of the triangle.`c`

: The circumcenter of the triangle.`ℓ²`

: The squared shortest edge length.

The arguments should be so that `(p, q, r)`

is positively oriented and `ℓ² = |p - q|²`

is the squared shortest edge length.

**Outputs**

`u`

: The first vertex of the rotated triangle.`v`

: The second vertex of the rotated triangle.`w`

: The third vertex of the rotated triangle.

These outputs `(u, v, w)`

are a permutation of `(p, q, r)`

(maintaining positive orientation) such that `|m - c₁|`

is maximised over all other shortest edges, where `m = (u + v)/2`

. If there is no unique maximiser, then the output is the permutation that is lexicographically smallest (i.e., sorted by x and then by y).

`DelaunayTriangulation.self_eval`

— Method`self_eval(f, args...)`

Evaluates `f(args...)`

.

`DelaunayTriangulation.set_bounding_box!`

— Method`set_bounding_box!(node::AbstractNode, bounding_box::BoundingBox)`

Sets the bounding box of `node`

to be `bounding_box`

.

`DelaunayTriangulation.set_bounding_box!`

— Method`set_bounding_box!(hierarchy::PolygonHierarchy, index, bounding_box)`

Sets the bounding box of the `index`

th polygon in `hierarchy`

to `bounding_box`

. If `index`

is greater than the length of the bounding boxes vector, the vector is resized.

`DelaunayTriangulation.set_child!`

— Method`set_child!(parent_node::AbstractNode, child_node, i::Integer)`

Sets the `i`

th child of `parent_node`

to be `child_node`

.

`DelaunayTriangulation.set_count!`

— Method`set_count!(tree::BalancedBST{K}, count::Int32)`

Sets the count of `tree`

to `count`

.

`DelaunayTriangulation.set_count!`

— Method`set_count!(node::BalancedBSTNode[, count = compute_count(node)])`

Sets the count of `node`

to `count`

. If `count`

is not provided, the count is computed using `compute_count`

.

`DelaunayTriangulation.set_height!`

— Method`set_height!(node::BalancedBSTNode[, height = compute_height(node)])`

Sets the height of `node`

to `height`

. If `height`

is not provided, the height is computed using `compute_height`

.

`DelaunayTriangulation.set_height!`

— Method`set_height!(tree::PolygonTree, height::Int)`

Sets the height of `tree`

to `height`

.

`DelaunayTriangulation.set_key!`

— Method`set_key!(node::BalancedBSTNode{K}, key::K)`

Sets the key associated with `node`

to `key`

.

`DelaunayTriangulation.set_left!`

— Method`set_left!(node::BalancedBSTNode, left::Union{Nothing, BalancedBSTNode})`

Sets the left child of `node`

to `left`

.

`DelaunayTriangulation.set_level!`

— Method`set_level!(branch::Branch, level::Integer)`

Sets the level of `branch`

to be `level`

.

`DelaunayTriangulation.set_orientation!`

— Method`set_orientation!(hierarchy::PolygonHierarchy, index, orientation)`

Sets the polygon orientation of the `index`

th polygon in `hierarchy`

to `orientation`

. If `index`

is greater than the length of the polygon orientations vector, the vector is resized.

`DelaunayTriangulation.set_parent!`

— Method`set_parent!(child_node::AbstractNode, parent_node::AbstractNode)`

Sets the parent of `child_node`

to be `parent_node`

.

`DelaunayTriangulation.set_parent!`

— Method`set_parent!(node::BalancedBSTNode, parent::Union{Nothing, BalancedBSTNode})`

Sets the parent of `node`

to `parent`

.

`DelaunayTriangulation.set_parent!`

— Method`set_parent!(boundary_enricher::BoundaryEnricher, i, j, k)`

Sets the parent of the edge `(i, j)`

in `boundary_enricher`

to `k`

.

`DelaunayTriangulation.set_parent!`

— Method`set_parent!(tree::PolygonTree, parent::PolygonTree)`

Sets the parent of `tree`

to `parent`

.

`DelaunayTriangulation.set_point!`

— Function```
set_point!(points, i, x, y)
set_point!(points, i, p) = set_point!(points, i, getx(p), gety(p))
```

Sets the point at index `i`

in `points`

to `(x, y)`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> points = [(1.0, 3.0), (5.0, 17.0)]
2-element Vector{Tuple{Float64, Float64}}:
(1.0, 3.0)
(5.0, 17.0)
julia> DelaunayTriangulation.set_point!(points, 1, 0.0, 0.0)
(0.0, 0.0)
julia> points
2-element Vector{Tuple{Float64, Float64}}:
(0.0, 0.0)
(5.0, 17.0)
julia> points = [1.0 2.0 3.0; 4.0 5.0 6.0]
2×3 Matrix{Float64}:
1.0 2.0 3.0
4.0 5.0 6.0
julia> DelaunayTriangulation.set_point!(points, 2, (17.3, 0.0))
2-element view(::Matrix{Float64}, :, 2) with eltype Float64:
17.3
0.0
julia> points
2×3 Matrix{Float64}:
1.0 17.3 3.0
4.0 0.0 6.0
```

`DelaunayTriangulation.set_point!`

— Method```
set_point!(tri::Triangulation, i, x, y)
set_point!(tri::Triangulation, i, p)
```

Sets the `i`

th point of `tri`

to `p = (x, y)`

.

`DelaunayTriangulation.set_right!`

— Method`set_right!(node::BalancedBSTNode, right::Union{Nothing, BalancedBSTNode})`

Sets the right child of `node`

to `right`

.

`DelaunayTriangulation.set_root!`

— Method`set_root!(tree::BalancedBST{K}, root::Union{Nothing,BalancedBSTNode{K}})`

Sets the root of `tree`

to `root`

.

`DelaunayTriangulation.set_root!`

— Method`set_root!(tree::RTree, node::AbstractNode)`

Sets the root of `tree`

to be `node`

.

`DelaunayTriangulation.set_tree!`

— Method`set_tree!(hierarchy::PolygonHierarchy, index, tree)`

Sets the `PolygonTree`

of the `index`

th polygon in `hierarchy`

to `tree`

, or adds it if it is not an existing key. The `index`

must be associated with an exterior polygon.

`DelaunayTriangulation.setup_cavity_cdt`

— Method`setup_cavity_cdt(tri::Triangulation, V; rng::AbstractRNG=Random.default_rng()) -> ShuffledPolygonLinkedList`

Prepares the linked list required for triangulating a cavity excavated by segment insertion in a constrained triangulation.

See also `prepare_vertex_linked_list`

and `delete_polygon_vertices_in_random_order!`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`V`

: The list of polygon vertices, given as a counter-clockwise list of vertices, defining the cavity.

**Keyword Arguments**

`rng::AbstractRNG=Random.default_rng()`

: The random number generator to use.

**Outputs**

`list::ShuffledPolygonLinkedList`

: The linked list of polygon vertices representing the cavity.

`DelaunayTriangulation.sort_convex_polygon!`

— Method`sort_convex_polygon!(vertices, points)`

Sorts the vertices of a convex polygon in counter-clockwise order. The polygon is defined by `(points, vertices)`

, and the vertices are sorted in-place. It is assumed that the vertices are not circular, i.e. `vertices[begin] ≠ vertices[end]`

.

`DelaunayTriangulation.sort_edge_by_degree`

— Method`sort_edge_by_degree(tri::Triangulation, e) -> Edge`

Returns the edge `e`

sorted so that `initial(e)`

has the smaller degree of the two vertices.

`DelaunayTriangulation.sort_fan!`

— Method`sort_fan!(fan, fan_triangles, tri::Triangulation)`

Given a set of triangles in a fan, `fan_triangles`

, associated with some triangulation `tri`

, places all the triangle vertices and sorts them counter-clockwise, placing the results into `fan`

.

`DelaunayTriangulation.sort_members!`

— Method`sort_members!(complex::SmallAngleComplex, points)`

Sorts the members of `complex`

in a counter-clockwise order around the apex of `complex`

.

`DelaunayTriangulation.sort_triangle`

— Function```
sort_triangle(T) -> Triangle
sort_triangle(i, j, k) -> Triangle
```

Sort the triangle `T = (i, j, k)`

so that its last vertex is the smallest, respecting the orientation of `T`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.sort_triangle((1, 5, 3))
(5, 3, 1)
julia> DelaunayTriangulation.sort_triangle((1, -1, 2))
(2, 1, -1)
julia> DelaunayTriangulation.sort_triangle((3, 2, 1))
(3, 2, 1)
```

`DelaunayTriangulation.sort_triangles`

— Method`sort_triangles(T) -> Triangle`

Sort the triangles in `T`

so that the first vertex of each triangle is the largest, respecting the orientation of the triangles. See `sort_triangle`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> T = Set(((1, 3, 2), (5, 2, 3), (10, 1, 13), (-1, 10, 12), (10, 1, 17), (5, 8, 2)))
Set{Tuple{Int64, Int64, Int64}} with 6 elements:
(5, 8, 2)
(10, 1, 13)
(10, 1, 17)
(5, 2, 3)
(1, 3, 2)
(-1, 10, 12)
julia> DelaunayTriangulation.sort_triangles(T)
Set{Tuple{Int64, Int64, Int64}} with 6 elements:
(13, 10, 1)
(3, 5, 2)
(10, 12, -1)
(5, 8, 2)
(17, 10, 1)
(3, 2, 1)
```

`DelaunayTriangulation.spawn_branch!`

— Method`spawn_branch!(tree::RTree, bounding_box::BoundingBox, level) -> Branch`

Returns a new branch node with bounding box `bounding_box`

and level `level`

from `tree`

.

`DelaunayTriangulation.spawn_leaf!`

— Method`spawn_leaf!(tree::RTree, bounding_box::BoundingBox) -> Leaf{Branch}`

Returns a new leaf node with bounding box `bounding_box`

from `tree`

.

`DelaunayTriangulation.spawn_node!`

— Method`spawn_node!(cache::NodeCache{Node}) where {Node} -> Node`

Returns a node from `cache`

. If `cache`

is empty, returns a new node.

`DelaunayTriangulation.spawn_node!`

— Method`spawn_node!(tree::RTree, ::Type{N}, [bounding_box::BoundingBox], level) where {N} -> N`

Returns a new node of type `N`

with bounding box `bounding_box`

and level `level`

from `tree`

. If `bounding_box`

is not provided, it is replaced with `InvalidBoundingBox`

.

`DelaunayTriangulation.split!`

— Method`split!(node::AbstractNode, tree::RTree) -> Branch, Branch`

Splits `node`

into two other nodes using a linear splitting rule. Returns the two new nodes.

`DelaunayTriangulation.split_all_encroached_segments!`

— Method`split_all_encroached_segments!(tri::Triangulation, args::RefinementArguments)`

Splits all encroached segments of `tri`

according to `split_subsegment!`

until no more encroached segments exist in `args.queue`

.

`DelaunayTriangulation.split_boundary_edge!`

— Function`split_boundary_edge!(enricher::BoundaryEnricher, i, j, r, update_boundary_nodes = Val(true))`

Updates the fields of `enricher`

after splitting a boundary edge `(i, j)`

at the `r`

th vertex. The `update_boundary_nodes`

argument can be used to avoid inserting an additional boundary node when `boundary_nodes`

was already updated somewhere else (e.g., we need this for mesh refinement which already updates the `boundary_nodes`

which is aliased with the same field in the enricher).

`DelaunayTriangulation.split_boundary_edge!`

— Method```
split_boundary_edge!(tri::Triangulation, ij, node)
split_boundary_edge!(tri::Triangulation, i, j, node)
```

Splits the boundary edge `edge`

in `tri`

at the edge `(i, j)`

.

See also `merge_boundary_edge!`

.

`DelaunayTriangulation.split_boundary_edge!`

— Method`split_boundary_edge!(events::InsertionEventHistory, u, v, new_point)`

Add the edge `(u, v)`

to the `deleted_boundary_segments`

of `events`

and add the edges `(u, new_point)`

and `(new_point, v)`

to the `added_boundary_segments`

of `events`

.

`DelaunayTriangulation.split_boundary_edge_at_collinear_segments!`

— Method`split_boundary_edge_at_collinear_segments!(tri::Triangulation, collinear_segments)`

Splits a boundary edge into pieces defined by `collinear_segments`

. In particular, if `r = collinear_segments`

and

```
u = initial(r[1])
v = terminal(r[end]),
```

then the boundary edge is `(u, v)`

and the edges are split so that all segments in `collinear_segments`

appear instead.

`DelaunayTriangulation.split_boundary_edge_map!`

— Method`split_boundary_edge_map!(boundary_edge_map, boundary_nodes, pos)`

After splitting an edge starting at `pos`

on the boundary, updates the `boundary_edge_map`

to reflect the new boundary edges. See `split_boundary_edge!`

.

`DelaunayTriangulation.split_edge!`

— Function`split_edge!(enricher::BoundaryEnricher, i, j, r, update_boundary_nodes = Val(true), update_segments = Val(true), is_interior = is_segment(enricher, i, j))`

Updates the fields of `enricher`

after splitting an edge `(i, j)`

at the `r`

th vertex. The `update_boundary_nodes`

argument can be used to avoid inserting an additional boundary node when `boundary_nodes`

was already updated somewhere else (e.g., we need this for mesh refinement which already updates the `boundary_nodes`

which is aliased with the same field in the enricher). The same point goes for `update_segments`

which can be used to avoid inserting an additional segment when `segments`

was already updated somewhere else. The `is_interior`

argument can be used to specify whether the edge is an interior segment or a boundary edge.

See also `split_boundary_edge!`

and `split_interior_segment!`

.

`DelaunayTriangulation.split_edge!`

— Function`split_edge!(tri::Triangulation, i, j, r, store_event_history=Val(false), event_history=nothing)`

Splits the edge `(i, j)`

in `tri`

at the vertex `r`

. For the triangulation to be valid after this splitting, it is assumed that `r`

is collinear with, or at least very close to collinear with, the edge `(i, j)`

.

See also `legalise_split_edge!`

and `complete_split_edge_and_legalise!`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`i`

: The first vertex of the edge to split.`j`

: The second vertex of the edge to split.`r`

: The vertex to split the edge at.`store_event_history=Val(false)`

: Whether to store the event history of the flip.`event_history=nothing`

: The event history. Only updated if`store_event_history`

is true, in which case it needs to be an`InsertionEventHistory`

object.

**Outputs**

There is no output, as `tri`

is updated in-place.

The triangulation will only be updated as if `(i, j)`

has been split rather than also `(j, i)`

. You will need to call `split_edge!`

again with `(j, i)`

if you want to split that edge as well.

`DelaunayTriangulation.split_edge!`

— Method`split_edge!(tree::BoundaryRTree, i, j, r)`

Splits the diametral bounding box associated with `(i, j)`

into two new boxes associated with the diametral circles of `(i, r)`

and `(j, r)`

.

`DelaunayTriangulation.split_interior_segment!`

— Function`split_interior_segment!(enricher::BoundaryEnricher, i, j, r, update_segments = Val(true))`

Updates the fields of `enricher`

after splitting an interior segment `(i, j)`

at the `r`

th vertex. The `update_segments`

argument can be used to avoid inserting an additional segment when `segments`

was already updated somewhere else (e.g., we need this for mesh refinement which already updates the `interior_segments`

which is aliased with the `segments`

field in the enricher).

`DelaunayTriangulation.split_marked_vertices!`

— Method`split_marked_vertices!(fan_triangles, tri::Triangulation, marked_vertices)`

Given a set of `marked_vertices`

indicating a crossed triangle (like in Figure 9 of this paper), finds all triangles whose three vertices are all in `marked_vertices`

and places them into `fan_triangles`

.

`DelaunayTriangulation.split_seeds`

— Method`split_seeds(node::AbstractNode) -> NTuple{2, Int}`

Returns the indices of two children in `node`

used to initiate the split in `split!`

.

`DelaunayTriangulation.split_segment!`

— Method```
split_segment!(tri::Triangulation, segment, collinear_segments)
split_segment!(segments, segment, collinear_segments)
```

Splits `segment`

at the segments in `collinear_segments`

, which are assumed to be collinear with `segment`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`segments`

: The underlying set of segments. This is`get_interior_segments(tri)`

if`tri`

is a`Triangulation`

.`segment`

: The segment to split.`collinear_segments`

: The segments that are collinear with`segment`

.

**Outputs**

There is no output, as `segments`

is updated in-place.

**Example**

```
julia> using DelaunayTriangulation
julia> segments = Set(((2, 3), (3, 5), (10, 12)))
Set{Tuple{Int64, Int64}} with 3 elements:
(2, 3)
(3, 5)
(10, 12)
julia> collinear_segments = [(2, 10), (11, 15), (2, 3)]
3-element Vector{Tuple{Int64, Int64}}:
(2, 10)
(11, 15)
(2, 3)
julia> segment = (3, 5)
(3, 5)
julia> DelaunayTriangulation.split_segment!(segments, segment, collinear_segments)
Set{Tuple{Int64, Int64}} with 4 elements:
(2, 10)
(2, 3)
(11, 15)
(10, 12)
```

`DelaunayTriangulation.split_subcurve!`

— Method`split_subcurve!(enricher::BoundaryEnricher, i, j) -> Bool`

Splits the curve associated with the edge `(i, j)`

into two subcurves by inserting a point `r`

between `(i, j)`

such that the total variation of the subcurve is equal on `(i, r)`

and `(r, j)`

. The returned value is a `flag`

that is `true`

if there was a precision issue, and `false`

otherwise.

`DelaunayTriangulation.split_subsegment!`

— Method`split_subsegment!(tri::Triangulation, args::RefinementArguments, e)`

Splits a subsegment `e`

of `tri`

at a position determined by `compute_split_position`

; for curve-bounded domains, the position is determined by `split_subcurve!`

. After the split, `assess_triangle_quality`

is used to find any new bad quality triangles. Before splitting, all free vertices in the segment's diametral circle are deleted using `delete_free_vertices_around_subsegment!`

.

`DelaunayTriangulation.split_triangle!`

— Method`split_triangle!(tri::Triangulation, args::RefinementArguments, T) -> Certificate`

Splits a bad triangle `T`

of `tri`

to improve its quality.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

to split a triangle of.`args::RefinementArguments`

: The`RefinementArguments`

for the refinement.`T`

: The triangle to split.

**Output**

`cert`

: A`Certificate`

indicating whether the split was successful or not. In particular, returns one of:`Cert.SuccessfulInsertion`

: The triangle was split successfully.`Cert.EncroachmentFailure`

: The triangle was not split successfully as the newly inserted point encroached upon a segment.`Cert.PrecisionFailure`

: The triangle was not split successfully due to precision issues.

`DelaunayTriangulation.split_triangle!`

— Method`split_triangle!(tri::Triangulation, i, j, k, r)`

Splits the triangle `(i, j, k)`

at the vertex `r`

, assumed to be inside the triangle.

See also `legalise_split_triangle!`

and `complete_split_triangle_and_legalise!`

.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

.`i`

: The first vertex of the triangle.`j`

: The second vertex of the triangle.`k`

: The third vertex of the triangle.`r`

: The vertex to split the triangle at.

**Outputs**

There is no output, but `tri`

will be updated so that it now contains the triangles `(i, j, r)`

, `(j, k, r)`

, and `(k, i, r)`

.

`DelaunayTriangulation.squared_distance_to_segment`

— Method`squared_distance_to_segment(x₁, y₁, x₂, y₂, x, y) -> Number`

Given a line segment `(x₁, y₁) → (x₂, y₂)`

and a query point `(x, y)`

, returns the squared distance from `(x, y)`

to the line segment.

`DelaunayTriangulation.squared_triangle_area`

— Method`squared_triangle_area(p, q, r) -> Number`

Computes the squared area of the triangle with coordinates `p`

, `q`

, `r`

. Initially, `squared_triangle_area`

is used for this, unless the squared area is found to be negative due to precision issues, in which case `squared_triangle_area_v2`

is used instead.

`DelaunayTriangulation.squared_triangle_area`

— Method`squared_triangle_area(ℓ₁², ℓ₂², ℓ₃²) -> Number`

Compute the squared area of a triangle given the squares of its edge lengths. Heron's formula is used, so that the squared area is

\[A^2 = \dfrac{1}{16}\left[4\ell_1^2\ell_2^2 - \left(\ell_1^2 + \ell_2^2 - \ell_3^2\right)^2\right]..\]

See also `squared_triangle_area_v2`

.

`DelaunayTriangulation.squared_triangle_area_v2`

— Method`squared_triangle_area_v2(ℓ₁², ℓ₂², ℓ₃²) -> Number`

Compute the squared area of a triangle given the squares of its edge lengths, given in sorted order so that `ℓ₁² ≤ ℓ₂² ≤ ℓ₃²`

. This is a more numerically stable version of `squared_triangle_area`

using the formula from Kahan (2014):

\[A^2 = \dfrac{1}{16}\left\{\left[\ell_3 + \left(\ell_2 + \ell_1\right)\right]\left[\ell_1 - \left(\ell_3 - \ell_2\right)\right]\left[\ell_1 + \left(\ell_3 - \ell_2\right)\right]\left[\ell_3 + \left(\ell_2 - \ell_1\right)\right]\right\}.\]

`DelaunayTriangulation.squared_triangle_lengths`

— Method`squared_triangle_lengths(p, q, r) -> (Number, Number, Number)`

Computes the squared lengths of the edges of the triangle with coordinates `p`

, `q`

, `r`

. The squared lengths are returned in sorted order.

`DelaunayTriangulation.squared_triangle_lengths_and_smallest_index`

— Method`squared_triangle_lengths_and_smallest_index(p, q, r) -> (Number, Number, Number, Integer)`

Computes the squared lengths of the edges of the triangle with coordinates `p`

, `q`

, `r`

. The squared lengths are returned in sorted order, and the index of the shortest edge is returned as well. Here, the index refers to which edge in the order `(p, q)`

, `(q, r)`

, `(q, p)`

.

`DelaunayTriangulation.statistics`

— Method`statistics(tri::Triangulation) -> TriangulationStatistics`

Returns a `TriangulationStatistics`

object containing statistics about the triangulation `tri`

.

`DelaunayTriangulation.swap!`

— Method`swap!(queue::MaxPriorityQueue, i, j)`

Swaps the elements at indices `i`

and `j`

in `queue`

.

`DelaunayTriangulation.swap_permutation!`

— Method`swap_permutation!(list::ShuffledPolygonLinkedList, i, j)`

Reorders the permutation `list.shuffled_indices`

of the linked `list`

, swapping `πᵢ`

and `πⱼ`

where `πₖ = list.shuffled_indices[k]`

.

`DelaunayTriangulation.terminal`

— Method`terminal(e) -> Vertex`

Get the terminal vertex of `e`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> e = (1, 7);
julia> DelaunayTriangulation.terminal(e)
7
julia> e = [2, 13];
julia> DelaunayTriangulation.terminal(e)
13
```

`DelaunayTriangulation.test_intersection`

— Method`test_intersection(node::AbstractNode, itr::RTreeIntersectionIterator) -> QueryResult`

Tests whether `node`

intersects with the bounding box in `itr`

, returning a `QueryResult`

.

`DelaunayTriangulation.test_visibility`

— Method`test_visibility(enricher::BoundaryEnricher, i, j, k) -> Certificate`

Tests if the vertex `k`

is visible from the edge `(i, j)`

. Returns a `Certificate`

which is

`Invisible`

: If`k`

is not visible from`(i, j)`

.`Visible`

: If`k`

is visible from`(i, j)`

.

For this function, `k`

should be inside the diametral circle of `(i, j)`

.

We say that `k`

is invisibile from `(i, j)`

if the edges `(i, k)`

or `(j, k)`

intersect any other boundary edges, or there is a hole between `(i, j)`

and `k`

.

This is not the same definition used in defining constrained Delaunay triangulations, where visibility means visible from ANY point on the edge instead of only from the endpoints.

`DelaunayTriangulation.test_visibility`

— Method`test_visibility(tri::Triangulation, u, v, i; shift=0.0, attractor=get_point(tri,i)) -> Certificate`

Tests if the edge `(u, v)`

and the point `i`

can see each other. Here, visibility means that any point in the interior of `(u, v)`

can see `i`

. To test this, we only check `10`

points equally spaced between `u`

and `v`

, excluding `u`

and `v`

.

**Arguments**

`tri`

: The`Triangulation`

.`u`

: The first vertex of the edge.`v`

: The second vertex of the edge.`i`

: The vertex we are testing visibility of.

**Keyword Arguments**

`shift=0.0`

: The amount by which to shift each point on the edge towards`attractor`

, i.e. if`p`

is a point on the edge, then`p .+ shift .* (attractor - p)`

is the point used to test visibility rather than`p`

itself.

**Outputs**

`cert`

: A`Certificate`

. This will be`Visible`

if`i`

is visible from`(u, v)`

, and`Invisible`

otherwise.

`DelaunayTriangulation.test_visibility`

— Method`test_visibility(tri::Triangulation, q, i) -> Certificate`

Tests if the vertex `i`

and the point `q`

can see each other. Here, visibility means that the line segment joining the two does not intersect any segments.

**Arguments**

`tri`

: The`Triangulation`

.`1`

: The point from which we are testing visibility.`i`

: The vertex we are testing visibility of.

**Outputs**

`cert`

: A`Certificate`

. This will be`Visible`

if`i`

is visible from`q`

, and`Invisible`

otherwise.

`DelaunayTriangulation.thrice_differentiate`

— Function`thrice_differentiate(c::AbstractParametricCurve, t) -> NTuple{2, Float64}`

Evaluates the third derivative of `c`

at `t`

.

`DelaunayTriangulation.to_boundary_curves`

— Method`to_boundary_curves(points, boundary_nodes) -> NTuple{N, AbstractParametricCurve} where N`

Returns the set of boundary curves associated with `boundary_nodes`

and `points`

.

`DelaunayTriangulation.toggle_inf_warn!`

— Method`toggle_inf_warn!()`

Toggle the warning for infinite circumcenters in the Voronoi tessellation. By default, this warning is enabled.

`DelaunayTriangulation.total_variation`

— Function```
total_variation(c::AbstractParametricCurve) -> Float64
total_variation(c::AbstractParametricCurve, t₁, t₂) -> Float64
```

Returns the total variation of a curve `c`

, or the subcurve over `[t₁, t₂]`

with `0 ≤ t₁ ≤ t₂ ≤ 1`

, defined as the integral of the absolute curvature over this interval. (This is also known as the total absolute curvature.)

`DelaunayTriangulation.triangle_angles`

— Method`triangle_angles(p, q, r) -> (Number, Number, Number)`

Computes the angles of a triangle with vertices `p`

, `q`

, and `r`

. The formula for, say, the angle at `p`

is given by

\[\theta_1 = \arctan\left(\dfrac{2A}{\left(p - q\right)\cdot\left(p - r\right)}\right),\]

where `A`

is the area of the triangle. The angles are returned in sorted order.

`DelaunayTriangulation.triangle_area`

— Method`triangle_area(p, q, r) -> Number`

Computes the area of the triangle with coordinates `p`

, `q`

, `r`

.

`DelaunayTriangulation.triangle_area`

— Method`triangle_area(ℓ₁², ℓ₂², ℓ₃²) -> Number`

Compute the area of a triangle given the squares of its edge lengths. If there are precision issues that cause the area to be negative, then the area is set to zero.

See also `squared_triangle_area`

.

`DelaunayTriangulation.triangle_aspect_ratio`

— Method`triangle_aspect_ratio(p, q, r) -> Number`

Computes the aspect ratio of the triangle with coordinates `(p, q, r)`

.

`DelaunayTriangulation.triangle_aspect_ratio`

— Method`triangle_aspect_ratio(inradius::Number, circumradius::Number) -> Number`

Computes the aspect ratio of a triangle with inradius `inradius`

and circumradius `circumradius`

. The aspect ratio is given by

\[\tau = \dfrac{r_i}{r},\]

where $r_i$ is the inradius and $r$ is the circumradius.

`DelaunayTriangulation.triangle_centroid`

— Method`triangle_centroid(p, q, r) -> (Number, Number)`

Computes the centroid of a triangle with vertices `p`

, `q`

, and `r`

, given by

\[c = \dfrac{p + q + r}{3}.\]

`DelaunayTriangulation.triangle_circumcenter`

— Function`triangle_circumcenter(p, q, r, A=triangle_area(p, q, r)) -> (Number, Number)`

Computes the circumcenter of the triangle with coordinates `(p, q, r)`

. The circumcenter is given by

\[c_x = r_x + \dfrac{d_{11}d_{22} - d_{12}d_{21}}{4A}, \quad c_y = r_y + \dfrac{e_{11}e_{22} - e_{12}e_{21}}{4A},\]

where $d_{11} = \|p - r\|_2^2$, $d_{12} = p_y - r_y$, $d_{21} = \|q - r\|_2^2$, $d_{22} = q_y - r_y$, $e_{11} = p_x - r_x$ $e_{12} = d_{11}$, $e_{21} = q_x - r_x$, and $e_{22} = d_{21}$.

`DelaunayTriangulation.triangle_circumcenter`

— Method`triangle_circumcenter(tri::Triangulation, T) -> (Number, Number)`

Computes the circumcenter of the triangle `T`

in the triangulation `tri`

.

`DelaunayTriangulation.triangle_circumradius`

— Method`triangle_circumradius(A, ℓmin², ℓmed², ℓmax²) -> Number`

Computes the circumradius of a triangle with area `A`

and squared edge lengths `ℓmin² ≤ ℓmed² ≤ ℓmax²`

. The circumradius is given by

\[r = \dfrac{\ell_{\min}\ell_{\text{med}}\ell_{\max}}{4A}.\]

`DelaunayTriangulation.triangle_circumradius`

— Method`triangle_circumradius(p, q, r) -> Number`

Computes the circumradius of the triangle with coordinates `(p, q, r)`

.

`DelaunayTriangulation.triangle_edge_midpoints`

— Method`triangle_edge_midpoints(p, q, r) -> (Number, Number), (Number, Number), (Number, Number)`

Computes the midpoints of the edges of the triangle with coordinates `(p, q, r)`

.

`DelaunayTriangulation.triangle_edges`

— Function```
triangle_edges(T) -> NTuple{3, Edge}
triangle_edges(i, j, k) -> NTuple{3, Edge}
```

Get the edges of `T = (i, j, k)`

as a `Tuple`

, in particular

`((i, j), (j, k), (k, i)).`

**Examples**

```
julia> using DelaunayTriangulation
julia> T = (1, 2, 3);
julia> DelaunayTriangulation.triangle_edges(T)
((1, 2), (2, 3), (3, 1))
julia> DelaunayTriangulation.triangle_edges(1, 2, 3)
((1, 2), (2, 3), (3, 1))
```

`DelaunayTriangulation.triangle_inradius`

— Method`triangle_inradius(p, q, r) -> Number`

Computes the inradius of the triangle with coordinates `(p, q, r)`

.

`DelaunayTriangulation.triangle_inradius`

— Method`triangle_inradius(A, perimeter) -> Number`

Computes the inradius of a triangle with area `A`

and perimeter `perimeter`

. The inradius is given by

\[r_i = \dfrac{2A}{P},\]

where $P$ is the `perimeter`

.

`DelaunayTriangulation.triangle_lengths`

— Method`triangle_lengths(p, q, r) -> (Number, Number, Number)`

Computes the lengths of the edges of the triangle with coordinates `p`

, `q`

, `r`

. The lengths are returned in sorted order.

`DelaunayTriangulation.triangle_line_segment_intersection`

— Function```
triangle_line_segment_intersection(p, q, r, a, b) -> Certificate
triangle_line_segment_intersection(tri::Triangulation, i, j, k, u, v) -> Certificate
```

Classifies the intersection of the line segment `(a, b)`

(or the edge `(u, v)`

of `tri`

) with the triangle `(p, q, r)`

(or the triangle `(i, j, k)`

of `tri`

). The returned value is a `Certificate`

, which is one of:

`Inside`

:`(a, b)`

is entirely inside`(p, q, r)`

.`Single`

:`(a, b)`

has one endpoint inside`(p, q, r)`

, and the other is outside.`Outside`

:`(a, b)`

is entirely outside`(p, q, r)`

.`Touching`

:`(a, b)`

is on`(p, q, r)`

's boundary, but not in its interior.`Multiple`

:`(a, b)`

passes entirely through`(p, q, r)`

. This includes the case where a point is on the boundary of`(p, q, r)`

.

`DelaunayTriangulation.triangle_offcenter`

— Function`triangle_offcenter(p, q, r, c₁=triangle_circumcenter(p, q, r), β=1.0) -> (Number, Number)`

Computes the off-center of the triangle `(p, q, r)`

.

**Arguments**

`p`

,`q`

,`r`

: The coordinates of the triangle, given in counter-clockwise order.`c₁=triangle_circumcenter(p, q, r)`

: The circumcenter of the triangle.`β=1.0`

: The radius-edge ratio cutoff.

**Output**

`cx`

: The x-coordinate of the off-center.`cy`

: The y-coordinate of the off-center.

In the original this paper, the off-center is defined to instead be the circumcenter if it the triangle `pqc₁`

has radius-edge ratio less than `β`

. Here, we just let the off-center be the point `c`

so that `pqc`

has radius-edge ratio of exactly `β`

.

`DelaunayTriangulation.triangle_orientation`

— Function```
triangle_orientation(tri::Triangulation, i, j, k) -> Certificate
triangle_orientation(tri::Triangulation, T) -> Certificate
triangle_orientation(p, q, r) -> Certificate
```

Computes the orientation of the triangle `T = (i, j, k)`

with correspondig coordinates `(p, q, r)`

. The returned value is a `Certificate`

, which is one of:

`PositivelyOriented`

: The triangle is positively oriented.`Degenerate`

: The triangle is degenerate, meaning the coordinates are collinear.`NegativelyOriented`

: The triangle is negatively oriented.

`DelaunayTriangulation.triangle_perimeter`

— Method`triangle_perimeter(p, q, r) -> Number`

Computes the perimeter of the triangle with coordinates `(p, q, r)`

.

`DelaunayTriangulation.triangle_perimeter`

— Method`triangle_perimeter(ℓmin::Number, ℓmed::Number, ℓmax::Number) -> Number`

Computes the perimeter of a triangle with edge lengths `ℓmin ≤ ℓmed ≤ ℓmax`

. The perimeter is given by

\[P = \ell_{\min} + \ell_{\text{med}} + \ell_{\max}.\]

`DelaunayTriangulation.triangle_radius_edge_ratio`

— Method`triangle_radius_edge_ratio(p, q, r) -> Number`

Computes the radius-edge ratio of the triangle with coordinates `(p, q, r)`

.

`DelaunayTriangulation.triangle_radius_edge_ratio`

— Method`triangle_radius_edge_ratio(circumradius::Number, ℓmin::Number) -> Number`

Computes the radius-edge ratio of a triangle with circumradius `circumradius`

and minimum edge length `ℓmin`

, given by

\[\rho = \dfrac{r}{\ell_{\min}},\]

where $r$ is the circumradius and $\ell_{\min}$ is the shortest edge length.

`DelaunayTriangulation.triangle_sink`

— Function`triangle_sink(p, q, r, tri::Triangulation) -> (Number, Number)`

Computes the sink of each triangle in `tri`

. See this paper for more information.

**Extended help**

Sinks were introduced in this paper. For a given triangle `T`

, the sink of `T`

is defined as follows:

- If
`c`

, the circumcenter of`T`

, is in the interior of`T`

, then the sink of`T`

is`T`

. - If
`T`

is a boundary triangle, then the sink of`T`

is`T`

. - If neither 1 or 2, then the sink is defined as the sink of the triangle
`V`

, where`V`

is the triangle adjoining the edge of`T`

which intersects the line`mc`

, where`m`

is the centroid of`T`

.

In cases where the triangulation has holes, this definition can lead to loops. In such a case, we just pick one of the triangles in the loop as the sink triangle.

`DelaunayTriangulation.triangle_type`

— Method`triangle_type(tri::Triangulation) -> DataType`

Returns the type used for representing individual triangles in `tri`

.

`DelaunayTriangulation.triangle_type`

— Method`triangle_type(::InsertionEventHistory{T}) where {T} = T`

Returns the type of the triangles in `events`

, `T`

.

`DelaunayTriangulation.triangle_type`

— Method`triangle_type(::Type{T}) -> DataType`

Get the triangle type of `T`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> DelaunayTriangulation.triangle_type(Set{NTuple{3,Int64}})
Tuple{Int64, Int64, Int64}
julia> DelaunayTriangulation.triangle_type(Vector{NTuple{3,Int32}})
Tuple{Int32, Int32, Int32}
julia> DelaunayTriangulation.triangle_type(Vector{Vector{Int64}})
Vector{Int64} (alias for Array{Int64, 1})
```

`DelaunayTriangulation.triangle_type`

— Method`triangle_type(vorn::VoronoiTessellation) -> DataType`

Type used for representing individual triangles in the Voronoi tessellation.

`DelaunayTriangulation.triangle_vertices`

— Method`triangle_vertices(T) -> NTuple{3, Vertex}`

Returns the vertices of `T`

as a `Tuple`

.

**Examples**

```
julia> using DelaunayTriangulation
julia> triangle_vertices((1, 5, 17))
(1, 5, 17)
julia> triangle_vertices([5, 18, 23]) # -> tuple
(5, 18, 23)
```

`DelaunayTriangulation.triangles_type`

— Method`triangle_type(tri::Triangulation) -> DataType`

Returns the type used for representing collections of triangles in `tri`

.

`DelaunayTriangulation.triangulate`

— Method`triangulate(points; segments=nothing, boundary_nodes=nothing, kwargs...) -> Triangulation`

Computes the Delaunay triangulation of `points`

, and then the constrained Delaunay triangulation if any of `segments`

and `boundary_nodes`

are not `nothing`

.

**Arguments**

`points`

: The points to triangulate.

For curve-bounded domains, `points`

may get mutated to include the endpoints of the provided curves, and when inserting Steiner points to split segments or refine boundaries.

**Keyword Arguments**

`segments=nothing`

: The segments to include in the triangulation. If`nothing`

, then no segments are included.

When segments are outside of the domain, are if they are not entirely contained with the domain, you may run into issues - especially for curve-bounded domains. It is your responsibility to ensure that the segments are contained within the domain.

The `segments`

may get mutated in two ways: (1) Segments may get rotated so that `(i, j)`

becomes `(j, i)`

. (2) If there are segments that are collinear with other segments, then they may get split into chain of non-overlapping connecting segments (also see below). For curve-bounded domains, segments are also split so that no subsegment's diametral circle contains any other point.

Currently, segments that intersect in their interiors (this excludes segments that only intersect by sharing a vertex) cause problems for triangulating. While there is some support for collinear segments that lie on top of each other (they get split automatically), this is not the case for segments that intersect in their interiors. Moreover, this automatic splitting should not be heavily relied upon, and for curve-bounded domains you should not rely on it at all as it causes problems during the enrichment phase from `enrich_boundary!`

.

`boundary_nodes=nothing`

: The boundary nodes to include in the triangulation. If`nothing`

, then no boundary nodes are included, and the convex hull of`points`

remains as the triangulation. These boundary nodes should match the specification given in`check_args`

if a boundary is provided as a set of vertices, meaning the boundary is a piecewise linear curve. To specify a curve-bounded domain, you should follow the same specification, but use`AbstractParametricCurve`

s to fill out the vector, and any piecewise linear section should still be provided as a sequence of vertices.

While for standard domains with piecewise linear boundaries (or no boundaries) it is fine for points to be outside of the domain (they just get automatically deleted if needed), they may cause problems for curve-bounded domains. Please ensure that all your points are inside the curve-bounded domain if you are providing curves in `boundary_nodes`

.

For curve-bounded domains, the `boundary_nodes`

in the resulting `Triangulation`

will not be aliased with the input boundary nodes.

For curve-bounded domains, note that the triangulation produced from this function is really just an initial coarse discretisation of the true curved boundaries. You will need to refine further, via `refine!`

, to improve the discretisation, or increase `coarse_n`

below. See also `polygonise`

for a more direct approach to discretising a boundary (which might not give as high-quality meshes as you can obtain from `refine!`

though, note).

`weights=ZeroWeight()`

: The weights to use for the triangulation. By default, the triangulation is unweighted. The weights can also be provided as a vector, with the`i`

th weight referring to the`i`

th vertex, or more generally any object that defines`get_weight`

. The weights should be`Float64`

.

Weighted triangulations are not yet fully implemented due to certain bugs with the implementation.

`IntegerType=Int`

: The integer type to use for the triangulation. This is used for representing vertices.`EdgeType=isnothing(segments) ? NTuple{2,IntegerType} : (edge_type ∘ typeof)(segments)`

: The edge type to use for the triangulation.`TriangleType=NTuple{3,IntegerType}`

: The triangle type to use for the triangulation.`EdgesType=isnothing(segments) ? Set{EdgeType} : typeof(segments)`

: The type to use for storing the edges of the triangulation.`TrianglesType=Set{TriangleType}`

: The type to use for storing the triangles of the triangulation.`randomise=true`

: Whether to randomise the order in which the points are inserted into the triangulation. This is done using`get_insertion_order`

.`delete_ghosts=false`

: Whether to delete the ghost triangles after the triangulation is computed. This is done using`delete_ghost_triangles!`

.`delete_empty_features=true`

: Whether to delete empty features after the triangulation is computed. This is done using`clear_empty_features!`

.`try_last_inserted_point=true`

: Whether to try the last inserted point first when inserting points into the triangulation.`skip_points=()`

: The points to skip when inserting points into the triangulation. Note that, for curve-bounded domains,`skip_points`

is ignored when using`enrich_boundary!`

.`num_sample_rule=default_num_samples`

: A function mapping a number of points`n`

to a number of samples`m`

to use for sampling the initial points during the point location step of the algorithm within`jump_and_march`

.`rng::AbstractRNG=Random.default_rng()`

: The random number generator.`insertion_order::Vector=get_insertion_order(points, randomise, skip_points, IntegerType, rng)`

: The insertion order to use for inserting points into the triangulation. This is ignored if you are defining a curve-bounded domain.`recompute_representative_points=true`

: Whether to recompute the representative points after the triangulation is computed. This is done using`compute_representative_points!`

.`delete_holes=true`

: Whether to delete holes after the triangulation is computed. This is done using`delete_holes!`

.`check_arguments=true`

: Whether to check the arguments`points`

and`boundary_nodes`

are valid. This is done using`check_args`

.`polygonise_n=4096`

: Number of points to use for polygonising the boundary when considering the poylgon hierarchy for a curve-bounded domain using`polygonise`

. See`triangulate_curve_bounded`

.`coarse_n=0`

: Number of points to use for initialising a curve-bounded domain. See`triangulate_curve_bounded`

. (A value of`0`

means the number of points is chosen automatically until the diametral circles of all edges are empty.)`conform=false`

: If`true`

, then the triangulation will be enriched so that all segments are split until each segment's diametral circle contains no other points. This is done by treating the triangulation as a curve-bounded triangulation and using`enrich_boundary!`

.

**Outputs**

`tri::Triangulation`

: The triangulation.

`DelaunayTriangulation.triangulate_cavity_cdt!`

— Method`triangulate_cavity_cdt!(tri::Triangulation, V, marked_vertices; rng::AbstractRNG=Random.default_rng())`

Triangulates the cavity `V`

left behind when deleting triangles intersected in a triangulation by an edge, updating `tri`

to do so.

**Arguments**

`tri::Triangulation`

: The`Triangulation`

to update. This should be an empty triangulation.`V`

: The list of polygon vertices, given as a counter-clockwise list of vertices, defining the cavity.`tri_fan::Triangulation`

: The`Triangulation`

to use for the fan of triangles to be re-triangulated. This should be an empty triangulation.`marked_vertices`

: Cache for marking vertices to re-triangulate during the triangulation.`fan_triangles`

: A cache used for sorting and identifying triangles in a fan for retriangulation.

**Keyword Arguments**

`rng::AbstractRNG=Random.default_rng()`

: The random number generator to use or`setup_cavity_cdt`

.

**Outputs**

There is no output, but `tri`

is updated in-place.

`DelaunayTriangulation.triangulate_convex!`

— Method`triangulate_convex!(tri::Triangulation, S; rng::AbstractRNG=Random.default_rng())`

Triangulates the convex polygon `S`

in-place into `tri`

.

**Arguments**

`tri::Triangulation`

: The triangulation to be modified.`S`

: A convex polygon represented as a vector of vertices. The vertices should be given in counter-clockwise order, and must not be circular so that`S[begin] ≠ S[end]`

.

**Keyword Arguments**

`store_event_history=Val(false)`

: Whether to store the event history of the triangulation from triangulating the polygon.

**Outputs**

There is no output, as `tri`

is updated in-place. This function does not do any post-processing, e.g. deleting any ghost triangles. This is done by `triangulate_convex`

or `postprocess_triangulate_convex!`

.

`DelaunayTriangulation.triangulate_convex`

— Method`triangulate_convex(points, S; delete_ghosts=false, delete_empty_features=true, rng=Random.default_rng(), kwargs...) -> Triangulation`

Triangulates the convex polygon `S`

.

**Arguments**

`points`

: The point set corresponding to the vertices in`S`

.`S`

: A convex polygon represented as a vector of vertices. The vertices should be given in counter-clockwise order, and must not be circular so that`S[begin] ≠ S[end]`

.

**Keyword Arguments**

`delete_ghosts=false`

: If`true`

, the ghost triangles are deleted after triangulation.`delete_empty_features=true`

: If`true`

, the empty features are deleted after triangulation.`rng=Random.default_rng()`

: The random number generator used to shuffle the vertices of`S`

before triangulation.`kwargs...`

: Additional keyword arguments passed to`Triangulation`

.

While weighted triangulations are not yet supported from `triangulate`

directly, they are supported through this `triangulate_convex`

. In particular, you can use the `weights`

keyword argument to pass the weights of the vertices in `points`

.

**Output**

`tri::Triangulation`

: The triangulated polygon.

`DelaunayTriangulation.triangulate_curve_bounded`

— Method```
triangulate_curve_bounded(points::P;
segments=nothing,
boundary_nodes=nothing,
IntegerType::Type{I}=Int,
polygonise_n=4096,
coarse_n=0,
check_arguments=true,
delete_ghosts=false,
delete_empty_features=true,
recompute_representative_points=true,
rng::AbstractRNG=Random.default_rng(),
insertion_order=nothing,
kwargs...) where {P,I} -> Triangulation
```

Triangulates a curve-bounded domain defined by `(points, segments, boundary_nodes)`

. Please see `triangulate`

for a description of the arguments. The only differences are:

`insertion_order=nothing`

: This argument is ignored for curve-bounded domains.`polygonise_n=4096`

: For generating a high-resolution discretisation of a boundary initially for the construction of a`PolygonHierarchy`

, many points are needed. This number of points is defined by`polygonise_n`

, and must be a power of 2 (otherwise, the next highest power of 2 is used). See`polygonise`

.`coarse_n=0`

: This is the number of points to use for initialising a curve-bounded domain via`coarse_discretisation!`

. The default`coarse_n=0`

means the discretisation is performed until the maximum variation over any subcurve is less than`π/2`

.`skip_points`

: This is still used, but it is ignored during the enrichment phase (see`enrich_boundary!`

).

See also `BoundaryEnricher`

and `enrich_boundary!`

.

To refine the mesh further beyond its initial coarse discretisation, as produced from this function, please see `refine!`

.

`DelaunayTriangulation.triangulate_rectangle`

— Method`triangulate_rectangle(a, b, c, d, nx, ny; kwargs...) -> Triangulation`

Triangulates the rectangle `[a, b] × [c, d]`

.

**Arguments**

`a`

: The minimum`x`

-coordinate.`b`

: The maximum`x`

-coordinate.`c`

: The minimum`y`

-coordinate.`d`

: The maximum`y`

-coordinate.`nx`

: The number of points in the`x`

-direction.`ny`

: The number of points in the`y`

-direction.

**Keyword Arguments**

`single_boundary=false`

: If`true`

, then the boundary nodes are stored as a contiguous section. Otherwise, the boundary is split into four sections, in the order bottom, right, top, left.`delete_ghosts=false`

: If`true`

, then the ghost triangles are deleted. Otherwise, they are kept.`IntegerType::Type{I}=Int`

: The type of the vertices.`EdgeType::Type{E}=NTuple{2,IntegerType}`

: The type of the edges.`TriangleType::Type{V}=NTuple{3,IntegerType}`

: The type of the triangles.`EdgesType::Type{Es}=Set{EdgeType}`

: The type of the edges container.`TrianglesType::Type{Ts}=Set{TriangleType}`

: The type of the triangles container.

**Outputs**

`tri`

: The triangulation of the rectangle.

`DelaunayTriangulation.twice_differentiate`

— Function`twice_differentiate(c::AbstractParametricCurve, t) -> NTuple{2, Float64}`

Evaluates the second derivative of `c`

at `t`

.

`DelaunayTriangulation.unconstrained_triangulation!`

— Method`unconstrained_triangulation!(tri::Triangulation; kwargs...)`

Computes the unconstrained Delaunay triangulation of the points in `tri`

.

**Arguments**

`tri`

: The triang