DelaunayTriangulation.InvalidBoundingBox
— ConstantInvalidBoundingBox
A constant for representing an invalid rectangle, i.e. a rectangle with NaN
endpoints.
DelaunayTriangulation.InvalidBoundingInterval
— ConstantInvalidBoundingInterval
A constant for representing an invalid intervaBoundingInterval
, i.e. an interval with NaN
endpoints.
DelaunayTriangulation.AbstractBoundingShape
— Typeabstract type AbstractBoundingShape
Abstract type for representing a bounding box.
DelaunayTriangulation.AbstractEachEdge
— TypeAbstractEachEdge{E}
An abstract type for an iterator over edges in a triangulation.
DelaunayTriangulation.AbstractEachTriangle
— TypeAbstractEachTriangle{T}
An abstract type for an iterator over triangles in a triangulation.
DelaunayTriangulation.AbstractEachVertex
— TypeAbstractEachVertex{V}
An abstract type for an iterator over vertices in a triangulation.
DelaunayTriangulation.AbstractNode
— Typeabstract type AbstractNode end
Abstract type for representing a node in an R-tree.
DelaunayTriangulation.AbstractParametricCurve
— Typeabstract 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 definedtotal_variation
).- The struct must be callable so that
c(t)
, wherec
an instance of the struct, returns the associated value of the curve att
. - If the struct does not implement
point_position_relative_to_curve
, then the struct must implementget_closest_point
. Alternatively, rather than implementingget_closest_point
, the struct should have alookup_table
field as aVector{NTuple{2,Float64}}
, which returns values on the curve at a set of points, wherelookup_table[i]
is the value of the curve att = (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
— TypeAdjacent{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
— TypeAdjacent2Vertex{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
— TypeBSpline <: 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. Thei
th entry of the lookup table corresponds to thet
-valuei / (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 always0
and1
, respectively. Seeorientation_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
— Typemutable 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
— MethodBalancedBST{K}() where {K}
Constructs a new empty balanced binary search tree.
DelaunayTriangulation.BalancedBSTNode
— Typemutable 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
— TypeBezierCurve <: 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. Thei
th entry of the lookup table corresponds to thet
-valuei / (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 always0
and1
, respectively. Seeorientation_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
— TypeBoundaryEnricher{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 aTuple
, to the index of the parent curve inboundary_curves
.curve_index_map::Dict{I,I}
: A map from a curve index to the index of the curve inboundary_curves
.boundary_edge_map::B
: A map from a boundary node to the index of the curve inboundary_curves
that it belongs to. Seeconstruct_boundary_edge_map
.spatial_tree::BoundaryRTree{P}
: TheBoundaryRTree
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
— TypeBoundaryRTree{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
— TypeBoundingBox <: 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
— TypeBoundingInterval <: AbstractBoundingShape
Type for representing a bounding interval [a, b]
.
Fields
a::Float64
: The left endpoint.b::Float64
: The right endpoint.
DelaunayTriangulation.Branch
— Typemutable 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
— TypeBranchCache
Type for representing a cache of branch nodes.
DelaunayTriangulation.CatmullRomSpline
— TypeCatmullRomSpline <: 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. Thei
th entry of this vector corresponds to thet
-value associated with thei
th control point. With an alpha parameterα
, these values are given byknots[i+1] = knots[i] + dist(control_points[i], control_points[i+1])^α
, whereknots[1] = 0
, and the vector is the normalised by dividing byknots[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. Thei
th entry of the lookup table corresponds to thet
-valuei / (length(lookup_table) - 1)
.alpha::Float64
: The alpha parameter of the Catmull-Rom spline. This controls the type of the parametrisation, wherealpha = 0
corresponds to uniform parametrisation,alpha = 1/2
corresponds to centripetal parametrisation, andalpha = 1
corresponds to chordal parametrisation. Must be in[0, 1]
. For reasons similar to what we describe fortension
below, we only supportalpha = 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, withtension = 0
being the least tight, andtension = 1
leading to straight lines between the control points. Must be in[0, 1]
. You can not currently set this to anything except0.0
due to numerical issues with boundary refinement. (For example, equivariation splits are not possible iftension=1
since the curve is piecewise linear in that case, and fortension
very close to1
, 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 always0
and1
, respectively. Seeorientation_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
— TypeCatmullRomSplineSegment <: 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 ont³
.b::NTuple{2,Float64}
: The coefficient ont²
.c::NTuple{2,Float64}
: The coefficient ont
.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
— TypeCell{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
— TypeCellQueue{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
— TypeCircularArc <: 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 byend_angle - start_angle
, whereend_angle
is the angle atlast
, 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 forpoint_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
— TypeConvexHull{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 thatvertices[begin] == vertices[end]
.
Constructors
ConvexHull(points, vertices)
convex_hull(points; IntegerType=Int)
DelaunayTriangulation.DiametralBoundingBox
— TypeDiametralBoundingBox
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
— TypeEachGhostEdge{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
— TypeEachGhostTriangle{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
— TypeEachGhostVertex{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
— TypeEachSolidEdge{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
— TypeEachSolidTriangle{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
— TypeEachSolidVertex{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
— TypeEllipticalArc <: 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 fromcenter
, 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 byend_angle - start_angle
, whereend_angle
is the angle atlast
, 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
— TypeEnlargementValues
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
— TypeGraph{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
— TypeIndividualTriangleStatistics{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
— TypeInsertionEventHistory{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
— MethodInsertionEventHistory(tri::Triangulation) -> InsertionEventHistory
Initialises an InsertionEventHistory
for the triangulation tri
.
DelaunayTriangulation.Leaf
— Typemutable 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
— TypeLeafCache
Type for representing a cache of leaf nodes.
DelaunayTriangulation.LineSegment
— TypeLineSegment <: 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
— TypeMaxPriorityQueue{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
— TypeNodeCache{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
— TypePiecewiseLinear <: 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 boundarynodes should be a contiguous section). These are only used so that we can use this struct in [`anglebetween](@ref) easily. In particular, we need to allow for evaluating this curve at
t=0and at
t=1, and similarly for differentiating the curve at
t=0and at
t=1. For this, we have defined, letting
Lbe a
PiecewiseLinearcurve,
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
— TypePointLocationHistory{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 linepq
using to jump.collinear_point_indices::Vector{I}
: This field contains indices to segments incollinear_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 ofpq
.right_verices::Vector{I}
: Vertices from the visited triangles to the right ofpq
.
DelaunayTriangulation.Polygon
— TypePolygon{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 inpoints
. 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
— TypePolygonHierarchy{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
: ABitVector
of lengthn
wheren
is the number of polygons in the hierarchy. Thei
th entry istrue
if thei
th polygon is positively oriented, andfalse
otherwise.bounding_boxes::Vector{BoundingBox}
: AVector
ofBoundingBox
s of lengthn
wheren
is the number of polygons in the hierarchy. Thei
th entry is theBoundingBox
of thei
th polygon.trees::Dict{I,PolygonTree{I}}
: ADict
mapping the index of a polygon to itsPolygonTree
. The keys oftrees
are the roots of each individual tree, i.e. the outer-most polygons.reorder_cache::Vector{PolygonTree{I}}
: AVector 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
— Typemutable struct PolygonTree{I}
A tree structure used to define a polygon hierarchy.
Fields
parent::Union{Nothing,PolygonTree{I}}
: The parent of the tree. Ifnothing
, 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 thatindex
is inside of. The root has height0
.
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
— TypeQueue{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
— Typemutable 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 indetached_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 theTuple
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
— TypeRTreeIntersectionCache
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
: ABitVector
cache for keeping track of which indices innode_indices
need to be tested for intersections.
DelaunayTriangulation.RTreeIntersectionIterator
— TypeRTreeIntersectionIterator
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
— TypeRTreeIntersectionIteratorState
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
: ABitVector
cache for keeping track of which indices innode_indices
need to be tested for intersections.
DelaunayTriangulation.RefinementArguments
— TypeRefinementArguments{Q,C,H,I,E,T,R}
A struct for storing arguments for mesh refinement.
Fields
queue::Q
: TheRefinementQueue
.constraints::C
: TheRefinementConstraints
.events::H
: TheInsertionEventHistory
.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 insegment_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 forjump_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
— MethodRefinementArguments(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
— TypeRefinementConstraints{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 frommin_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 tonum_solid_vertices
, not the amount returned bynum_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 aTriangulation
and atriangle
as arguments, and returntrue
if thetriangle
violates the constraints andfalse
otherwise.
DelaunayTriangulation.RefinementQueue
— TypeRefinementQueue{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
— TypeRepresentativeCoordinates{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
— TypeShuffledPolygonLinkedList{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}
: Thenext
vertices, so thatnext[π[i]]
is the vertex afterS[π[i]]
.prev::Vector{I}
: Theprev
vertices, so thatprev[π[i]]
is the vertex beforeS[π[i]]
.shuffled_indices::Vector{I}
: The shuffled indices of the vertices, so thatS[π[i]]
is thei
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
— TypeSmallAngleComplex{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
— TypeSmallAngleComplexMember{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 is0
, 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
— TypeTriangulation{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
— MethodTriangulation(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 topoints
. 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 incheck_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 usingdelete_ghost_triangles!
.
Output
tri
: TheTriangulation
.
DelaunayTriangulation.Triangulation
— MethodTriangulation(points; kwargs...) -> Triangulation
Initialises an empty Triangulation
for triangulating points
. The keyword arguments kwargs...
match those of triangulate
.
DelaunayTriangulation.TriangulationCache
— TypeTriangulationCache{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 theweights
. 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 oftri
. This is needed forlock_convex_hull!
in case the convex hull also contains interior segments.surrounding_polygon::S
: The polygon surrounding the triangulation. This is needed fordelete_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
— TypeTriangulationStatistics{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. SeeIndividualTriangleStatistics
.
Constructors
To construct these statistics, use statistics
, which you call as statistics(tri::Triangulation)
.
DelaunayTriangulation.TwigCache
— TypeTwigCache
Type for representing a cache of twig nodes, i.e. branch nodes at level 2.
DelaunayTriangulation.VoronoiTessellation
— TypeVoronoiTessellation{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}
: ADict
that maps vertices of generators to coordinates. These are simply the points present in the triangulation. ADict
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 alsoget_polygon_coordinates
.)polygons::Dict{I,Vector{I}}
: ADict
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}
: ADict
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}
: ADict
mapping a triangle to its circumcenter index. The triangles are sorted such that the minimum vertex is last.unbounded_polygons::Set{I}
: ASet
of indices of the unbounded polygons.cocircular_circumcenters::S
: ASet
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}
: ASet
of indices of the polygons that are on the boundary of the tessellation. Only relevant for clipped tessellations, otherwise seeunbounded_polygons
.
DelaunayTriangulation.ZeroWeight
— TypeZeroWeight
Struct used for indicating that a triangulation has zero weights. The weights are Float64
.
Base.:∩
— Methodintersect(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.:∩
— Methodintersect(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.:∪
— Methodunion(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.:∪
— Methodunion(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!
— Methodappend!(complex::SmallAngleComplex, new_complex::SmallAngleComplex)
Appends the members of new_complex
onto the members of complex
.
Base.append!
— Methodappend!(node::AbstractNode, child)
Appends child
to node
's children. Also updates node
's bounding box.
Base.delete!
— Methoddelete!(tree::BalancedBST{K}, key::K) -> BalancedBST{K}
Deletes the node in tree
with key key
if it exists. Returns tree
.
Base.delete!
— Methoddelete!(tree::BoundaryRTree, i, j)
Deletes the bounding box of the diametral circle of the edge between i
and j
in tree
.
Base.delete!
— Methoddelete!(tree::RTree, id_bounding_box::DiametralBoundingBox)
Deletes id_bounding_box
from tree
.
Base.eltype
— Methodeltype(queue::Queue{T}) -> Type{T}
Returns the type of elements stored in q
.
Base.empty!
— Methodempty!(events::InsertionEventHistory)
Empties events
by emptying all of its fields.
Base.empty!
— Methodempty!(cache::TriangulationCache)
Empties the cache by emptying the triangulation stored in it.
Base.findfirst
— Methodfindfirst(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
— Methodfirst(queue::MaxPriorityQueue) -> Pair{K, V}
Returns the element with the highest priority in a queue
, without removing it from queue
.
Base.getindex
— Methodgetindex(queue::MaxPriorityQueue, key)
queue[key]
Returns the priority of the element with key key
in a queue
.
Base.getindex
— Methodgetindex(queue::RefinementQueue{T,E,F}, triangle::T) -> F
queue[triangle] -> F
Return the radius-edge ratio of triangle
in queue
.
Base.haskey
— Methodhaskey(tree::BalancedBST{K}, key::K) -> Bool
Returns true
if tree
has a node with key key
, false
otherwise.
Base.haskey
— Methodhaskey(queue::MaxPriorityQueue, key) -> Bool
Returns true
if the queue
has an element with key key
.
Base.haskey
— Methodhaskey(queue::RefinementQueue{T,E,F}, segment::E) -> Bool
Return true
if queue
has segment
or its reverse, and false
otherwise.
Base.haskey
— Methodhaskey(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
— Methodin(r1::BoundingBox, r2::BoundingBox) -> Bool
r1::BoundingBox ∈ r2::BoundingBox -> Bool
Tests whether r1
is in r2
.
Base.in
— Methodin(I::BoundingInterval, J::BoundingInterval) -> Bool
I::BoundingInterval ∈ J::BoundingInterval -> Bool
Tests whether the interval I
is in the interval J
.
Base.in
— Methodin(a::Float64, I::BoundingInterval) -> Bool
a::Float64 ∈ I::BoundingInterval -> Bool
Tests whether a
is in I
.
Base.in
— Methodin(p::NTuple{2,<:Number}, r::BoundingBox) -> Bool
p::NTuple{2,<:Number} ∈ r::BoundingBox -> Bool
Tests whether p
is in r
.
Base.insert!
— Methodinsert!(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!
— Methodinsert!(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!
— Methodinsert!(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
— Methodisempty(r::BoundingBox) -> Bool
Returns true
if r
is empty, i.e. if r.x
or r.y
is empty.
Base.isempty
— Methodisempty(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
— Methodisempty(queue::CellQueue) -> Bool
Returns true
if the queue
is empty, and false
otherwise.
Base.isempty
— Methodisempty(queue::MaxPriorityQueue) -> Bool
Returns true
if the queue
is empty.
Base.isempty
— Methodisempty(cache::NodeCache) -> Bool
Returns true
if cache
is empty.
Base.isempty
— Methodisempty(queue::Queue) -> Bool
Returns true
if the queue
is empty, false
otherwise.
Base.isempty
— Methodisempty(queue::RefinementQueue) -> Bool
Return true
if queue
has no segments or triangles, false
otherwise.
Base.iterate
— Methoditerate(itr::RTreeIntersectionIterator, state...)
Iterate over the next state of itr
to find more intersections with the bounding box in RTreeIntersectionIterator
.
Base.length
— Methodlength(I::BoundingInterval) -> Float64
Returns the length of the interval I
.
Base.length
— MethodBase.length(queue::MaxPriorityQueue) -> Int
Returns the number of elements in queue
.
Base.length
— Methodlength(cache::NodeCache) -> Int
Returns the number of nodes in cache
.
Base.length
— Methodlength(queue::Queue) -> Int
Returns the number of elements in the queue
.
Base.pop!
— Methodpop!(cache::NodeCache) -> Node
Removes and returns the last node in cache
.
Base.popfirst!
— Methodpopfirst!(queue::MaxPriorityQueue{K, V}) where {K, V} -> Pair{K, V}
Removes and returns the element with the highest priority from the queue
.
Base.popfirst!
— Methodpopfirst!(queue::Queue)
Removes the element from the front of the queue
and returns it.
Base.push!
— Methodpush!(tree::BalancedBST{K}, key::K)
Inserts key
into tree
if it is not already present.
Base.push!
— Methodpush!(queue::MaxPriorityQueue, pair)
Adds the key-value pair pair
to the queue
.
Base.push!
— Methodpush!(cache::NodeCache, node)
Base.push!
— Methodpush!(queue::Queue, item)
Adds item
to the end of the queue
.
Base.push!
— Methodpush!(complex::SmallAngleComplex, member::SmallAngleComplexMember)
Pushes member
onto the members of complex
.
Base.setindex!
— Methodsetindex!(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!
— MethodBassetindex!(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!
— Methodsetindex!(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!
— Methodsetindex!(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
: TheVoronoiTessellation
.set_of_boundary_nodes
: The set of boundary nodes in the underlying triangulation.points
: The underlying point set. This is adeepcopy
of the points of the underlying triangulation.rng
: The random number generator.
Keyword Arguments
kwargs...
: Extra keyword arguments passed toretriangulate
.
Outputs
vorn
: The updatedVoronoiTessellation
.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
: TheVoronoiTessellation
.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 thatpq
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._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
.
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._to_val
— Method_to_val(v) -> Val
Wraps v
in a Val
, or if v isa Val
simply returns v
.
DelaunayTriangulation.add_adjacent!
— Methodadd_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!
— Methodadd_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!
— Methodadd_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!
— Methodadd_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!
— Methodadd_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!
— Methodadd_all_boundary_polygons!(vorn::VoronoiTessellation, boundary_sites)
Add all of the boundary polygons to the Voronoi tessellation.
Arguments
vorn
: TheVoronoiTessellation
.boundary_sites
: A dictionary of boundary sites.
Outputs
There are no outputs, but the boundary polygons are added in-place.
DelaunayTriangulation.add_boundary_information!
— Methodadd_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!
— Methodadd_boundary_polygon!(vor::VoronoiTessellation, i)
Adds the index i
to the set of boundary polygons of vor
.
DelaunayTriangulation.add_child!
— Methodadd_child!(node::AbstractNode, child)
Adds child
to node
, i.e. appends child
to the children of node
via push!
.
DelaunayTriangulation.add_child!
— Methodadd_child!(tree::PolygonTree, child::PolygonTree)
Adds child
to tree
.
DelaunayTriangulation.add_edge!
— Methodadd_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!
— Methodadd_edge!(events::InsertionEventHistory, e)
Add the edge e
to the added_segments
of events
.
DelaunayTriangulation.add_edge!
— Methodadd_edge!(history::PointLocationHistory{T,E}, i, j)
Adds the edge (i, j)
to the collinear_segments
field of history
.
DelaunayTriangulation.add_edge!
— Methodadd_edge!(G::Graph, u, v)
Adds the edge (u, v)
to G
.
DelaunayTriangulation.add_edge_to_voronoi_polygon!
— Methodadd_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
: TheVoronoiTessellation
.i
: The polygon index.k
: The vertex to add.S
: The surrounding polygon ofi
. Seeget_surrounding_polygon
.m
: The index of the next vertex inS
.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 inS
after the inputk
.
DelaunayTriangulation.add_ghost_triangles!
— Methodadd_ghost_triangles!(tri::Triangulation)
Adds all the ghost triangles to tri
.
DelaunayTriangulation.add_index!
— Methodadd_index!(history::PointLocationHistory, i)
Adds the index i
to the collinear_point_indices
field of history
.
DelaunayTriangulation.add_intersection_points!
— Methodadd_intersection_points!(vorn::VoronoiTessellation, segment_intersections) -> Integer
Adds all of the segment_intersections
into the polygon vertices of vorn
.
Arguments
vorn
: TheVoronoiTessellation
.segment_intersections
: The intersection points fromfind_all_intersections
.
Outputs
n
: The number of polygon vertices before the intersections were added.
DelaunayTriangulation.add_left_vertex!
— Methodadd_left_vertex!(history::PointLocationHistory, i)
Adds the vertex i
to the left_vertices
field of history
.
DelaunayTriangulation.add_neighbour!
— Methodadd_neighbour!(tri::Triangulation, u, v...)
Adds the neighbours v...
to u
in the graph of tri
.
DelaunayTriangulation.add_neighbour!
— Methodadd_neighbour!(G::Graph, u, v...)
Adds the neighbours v...
to u
in G
.
DelaunayTriangulation.add_new_triangles!
— Methodadd_new_triangles!(tri_original::Triangulation, tris)
Adds the triangles from tris
to tri_original
.
DelaunayTriangulation.add_point!
— Methodadd_point!(c::RepresentativeCoordinates, p)
Treating c
as an arithmetic average, updates the coordinates of c
to include p
.
DelaunayTriangulation.add_point!
— Methodadd_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!
— Methodadd_point!(tri::Triangulation, new_point; kwargs...) -> Triangle
add_point!(tri::Triangulation, x, y; kwargs...) -> Triangle
Arguments
tri::Triangulation
: TheTriangulation
.new_point
: The point to be added to the triangulation. The second method uses(x, y)
to represent the new point instead. Ifnew_point
is an integer, then the point added isget_point(tri, new_point)
.
Keyword Arguments
point_indices=each_solid_vertex(tri)
: The indices of the points to be used in thejump_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 thejump_and_march
algorithm for selecting the initial point.try_points=()
: Additional points to try for selecting the initial point, in addition to them
sampled.rng::AbstractRNG=Random.default_rng()
: The random number generator to be used injump_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 injump_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 ifstore_event_history
is true, in which case it needs to be anInsertionEventHistory
object.concavity_protection=false
: Whether to use concavity protection for findingV
below. Seeconcavity_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 intoevent_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!
— Methodadd_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 withjump_and_march
at. Seeget_initial_search_point
.rng::AbstractRNG
: The random number generator to use.update_representative_point=true
: Iftrue
, then the representative point is updated. Seeupdate_centroid_after_addition!
.store_event_history=Val(false)
: Iftrue
, then the event history from the insertion is stored.event_history=nothing
: The event history to store the event history in. Should be anInsertionEventHistory
ifstore_event_history
istrue
, andfalse
otherwise.peek=Val(false)
: Whether to actually addnew_point
intotri
, or just record intoevent_history
all the changes that would occur from its insertion.
Output
V
: The triangle intri
containingnew_point
.
Extended help
This function works as follows:
- First, the triangle containing the new point,
V
, is found usingjump_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 intoadd_point_bowyer_watson_after_found_triangle
to add the point into the cavity. We then call intoadd_point_bowyer_watson_onto_segment
to make any changes necessary incase the triangulation is constrained andnew_point
lies on a segment, since the depth-first search of the triangles containingnew_point
in its circumcenter must be performed on each side of the segment thatnew_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!
— Methodadd_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
: TheTriangulation
.new_point::N
: The point to insert.V
: The triangle intri
containingnew_point
.q
: The point to insert.flag
: The position ofq
relative toV
. Seepoint_position_relative_to_triangle
.update_representative_point=true
: Iftrue
, then the representative point is updated. Seeupdate_centroid_after_addition!
.store_event_history=Val(false)
: Iftrue
, then the event history from the insertion is stored.event_history=nothing
: The event history to store the event history in. Should be anInsertionEventHistory
ifstore_event_history
istrue
, andfalse
otherwise.peek=Val(false)
: Whether to actually addnew_point
intotri
, or just record intoevent_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 ofV
, 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)
, meaningnew_point
is on one of the edges ofV
. 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 casenew_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)
, whereg
is the ghost vertex. This part of the function will fix this case. The need foris_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 ofV
thatnew_point
is on is not the boundary edge.
DelaunayTriangulation.add_point_cavity_cdt!
— Methodadd_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
: TheTriangulation
to update.u
: The vertex to add.v
: The vertex along the polygon that is next tou
.w
: The vertex along the polygon that is previous tou
.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!
— Methodadd_point_convex_triangulation!(tri::Triangulation, u, v, w, S)
Adds the point u
into the triangulation tri
.
Arguments
tri::Triangulation
: TheTriangulation
.u
: The vertex to add.v
: The vertex next tou
.w
: The vertex previous tou
.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 beO(1)
time. This is why we use aSet
type forS
. - The algorithm is recursive, recursively digging further through the polygon to find non-Delaunay edges to adjoins with
u
.
DelaunayTriangulation.add_polygon!
— Methodadd_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!
— Methodadd_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!
— Methodadd_right_vertex!(history::PointLocationHistory, j)
Adds the vertex j
to the right_vertices
field of history
.
DelaunayTriangulation.add_segment!
— Methodadd_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
: TheTriangulation
.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!
— Methodadd_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!
— Methodadd_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
: TheTriangulation
.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!
— Methodadd_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!
— Methodadd_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 edgeab
of the boundary.v
: The second vertex of the edge of the Voronoi polygon intersecting the edgeab
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!
— Methodadd_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!
— Functionadd_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!
— Methodadd_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!
— Methodadd_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!
— Methodadd_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!
— Methodadd_triangle!(events::InsertionEventHistory, T)
Add the triangle T
to the added_triangles
of events
.
DelaunayTriangulation.add_triangle!
— Methodadd_triangle!(history::PointLocationHistory, i, j, k)
Adds the triangle (i, j, k)
to the triangles
field of history
.
DelaunayTriangulation.add_triangle!
— Methodadd_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
: Iftrue
, then the boundary edges will not be updated. Otherwise,add_boundary_edges_single!
,add_boundary_edges_double!
, oradd_boundary_edges_triple!
will be called depending on the number of boundary edges in the triangle.update_ghost_edges=false
: Iftrue
, then the ghost edges will be updated. Otherwise, the ghost edges will not be updated. Will only be used ifprotect_boundary=false
.
Outputs
There are no outputs as tri
is updated in-place.
DelaunayTriangulation.add_unbounded_polygon!
— Methodadd_unbounded_polygon!(vor::VoronoiTessellation, i)
Adds the index i
to the set of unbounded polygons of vor
.
DelaunayTriangulation.add_vertex!
— Methodadd_vertex!(tri::Triangulation, u...)
Adds the vertices u...
into the graph of tri
.
DelaunayTriangulation.add_vertex!
— Methodadd_vertex!(G::Graph, u...)
Adds the vertices u...
to G
.
DelaunayTriangulation.add_voronoi_polygon!
— Methodadd_voronoi_polygon!(vorn::VoronoiTessellation, i) -> Vector
Add the Voronoi polygon for the point i
to the VoronoiTessellation
vorn
.
Arguments
vorn
: TheVoronoiTessellation
.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!
— Methodadd_weight!(weights, w)
Pushes the weight w
into weights
. The default definition for this is push!(weights, w)
.
DelaunayTriangulation.add_weight!
— Methodadd_weight!(tri::Triangulation, w)
Pushes the weight w
into the weights of tri
.
DelaunayTriangulation.adjust_θ
— Methodadjust_θ(θ₁, θ₂, 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
— Methodall_ghost_vertices(tri::Triangulation) -> KeySet
Returns the set of all ghost vertices in tri
.
DelaunayTriangulation.angle_between
— Methodangle_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
— Methodangle_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
— Methodangle_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
— Methodangle_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
— Functionarc_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!
— Methodassess_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
— Methodassess_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
: TheTriangulation
.args::RefinementArguments
: TheRefinementArguments
.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
— Methodbalanced_power_of_two_quarternary_split(ℓ) -> Float
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
— Methodbalanced_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
— Methodbounding_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
— Methodbounding_box(points) -> BoundingBox
Gets the bounding box for a set of points.
DelaunayTriangulation.bounding_box
— Methodbounding_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
— Methodbounding_box(p::NTuple, q::NTuple, r::NTuple) -> BoundingBox
Returns the bounding box of the points p
, q
and r
.
DelaunayTriangulation.bounding_box
— Methodbounding_box(center, radius) -> BoundingBox
Returns the bounding box of the circle (center, radius)
.
DelaunayTriangulation.brute_force_search
— Methodbrute_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
: TheTriangulation
.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 pointq
.
DelaunayTriangulation.brute_force_search_enclosing_circumcircle
— Methodbrute_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.build_triangulation_from_data!
— Methodbuild_triangulation_from_data!(tri::Triangulation, triangles, boundary_nodes, delete_ghosts)
Given an empty triangulation
, tri
, adds all the triangles
and boundary_nodes
into it. Use delete_ghosts=true
if you want to have all ghost triangles deleted afterwards.
DelaunayTriangulation.cache_node!
— Functioncache_node!(tree::RTree, node::AbstractNode)
Caches node
in into tree
's node caches.
DelaunayTriangulation.cache_node!
— Methodcache_node!(cache::NodeCache, node)
Caches node
in cache
if cache
is not full. Otherwise, does nothing.
DelaunayTriangulation.centroidal_smooth
— Methodcentroidal_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
: TheVoronoiTessellation
.
Keyword Arguments
maxiters=1000
: The maximum number of iterations.tol=default_displacement_tolerance(vorn)
: The displacement tolerance. Seedefault_displacement_tolerance
for the default.rng=Random.default_rng()
: The random number generator.kwargs...
: Extra keyword arguments passed toretriangulate
.
Outputs
vorn
: The updatedVoronoiTessellation
. 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
— Methodcheck_absolute_precision(x, y) -> Bool
Returns true
if abs(x - y)
is less than or equal to sqrt(eps(Float64))
.
DelaunayTriangulation.check_args
— Methodcheck_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
— Methodcheck_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 oftri
.vertex
is a ghost vertex oftri
.vertex
adjoins a segment oftri
.
DelaunayTriangulation.check_for_intersections_with_adjacent_boundary_edges
— Methodcheck_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
: TheTriangulation
.k
: The boundary vertex to start from.q
: The query point.ghost_vertex=𝒢
: The ghost vertex corresponding to the boundary thatk
resides on.
Outputs
direction_cert
: The direction ofq
relative to the vertexk
along the boundary, given as aCertificate
Left
,Right
, orOutside
. Ifis_outside(direction_cert)
, thenq
is not collinear with either of the adjacent boundary edges.q_pos_cert
: The position ofq
relative to the vertexk
along the boundary, given as aCertificate
Left
,Right
,On
,Outside
, orDegenerate
. This is similar todirection_cert
in that it will beOutside
wheneverdirection_cert
is, but this certificate can also beOn
to indicate that not only isq
in the direction given bydirection_cert
, but it is directly on the edge in that direction. Ifis_degnerate(q_pos_cert)
, thenq = get_point(tri, next_vertex)
.next_vertex
: The next vertex along the boundary in the direction ofq
, ork
ifq
is not collinear with either of the adjacent boundary edges.right_cert
: TheCertificate
for the position ofq
relative to the boundary edge right ofk
.left_cert
: TheCertificate
for the position ofq
relative to the boundary edge left ofk
.
DelaunayTriangulation.check_for_intersections_with_interior_edges_adjacent_to_boundary_vertex
— Methodcheck_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
: TheTriangulation
.k
: The boundary vertex to start from.q
: The query point.right_cert
: TheCertificate
for the position ofq
relative to the boundary edge right ofk
, coming fromcheck_for_intersections_with_adjacent_boundary_edges
.left_cert
: TheCertificate
for the position ofq
relative to the boundary edge left ofk
, coming fromcheck_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. Ifstore_history
, then this should be aPointLocationHistory
object.ghost_vertex=𝒢
: The ghost vertex corresponding to the boundary thatk
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 linepq
intersects the edgepᵢpⱼ
and(j, i, k)
is a positively oriented triangle so thatpᵢ
is left ofpq
andpⱼ
is right ofpq
.(i, j, None, Inside)
: The pointq
is inside the positively oriented triangle(i, j, k)
.(0, 0, None, Outside)
: The pointq
is outside of the triangulation.(i, j, On, Inside)
: The pointq
is on the edgepᵢpⱼ
, and thus inside the positively oriented triangle(i, j, k)
.(i, j, Right, Outside)
:The point
qis 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
— Methodcheck_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
: TheTriangulation
to split a triangle of.V
: The triangle that the Steiner point is in.T
: The triangle that the Steiner point is from.flag
: ACertificate
which isCert.On
if the Steiner point is on the boundary ofV
,Cert.Outside
if the Steiner point is outside ofV
, andCert.Inside
if the Steiner point is inside ofV
.c
: The Steiner point.
Output
c′
: The Steiner point to use instead ofc
, which isT
's centroid ifc
is not suitable.V′
: The triangle that the Steiner point is in, which isT
ifc
is not suitable.
DelaunayTriangulation.check_for_steiner_point_on_segment
— Methodcheck_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
: TheTriangulation
.V
: The triangle that the Steiner point was originally in prior tocheck_for_invisible_steiner_point
.V′
: The triangle that the Steiner point is in.new_point
: The vertex associated with the Steiner point.flag
: ACertificate
which isCert.On
if the Steiner point is on the boundary ofV
,Cert.Outside
if the Steiner point is outside ofV
, andCert.Inside
if the Steiner point is inside ofV
.
Output
onflag
: Whether the Steiner point is on a segment or not.
DelaunayTriangulation.check_precision
— Methodcheck_precision(x) -> Bool
Returns true
if abs(x)
is less than or equal to sqrt(eps(Float64))
.
DelaunayTriangulation.check_ratio_precision
— Methodcheck_ratio_precision(x, y) -> Bool
Returns true
if abs(x/y)
is bounded between 0.99
and 1.01
.
DelaunayTriangulation.check_relative_precision
— Methodcheck_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
— Methodcheck_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
— Methodcheck_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
— Methodcheck_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
— Methodchoose_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
— Functioncircular_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
— Methodclassify_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
: ACertificate
indicating the intersection type.cert_c
: ACertificate
indicating the position ofc
relative to the line through(a, b)
.cert_d
: ACertificate
indicating the position ofd
relative to the line through(a, b)
.p
: The intersection point ifcert
isCert.Single
orCert.Touching
, and(NaN, NaN)
otherwise.
DelaunayTriangulation.classify_intersections!
— Methodclassify_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 ofe
on the boundary.right_edge
: The edge to the right ofe
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!
— Methodclear_empty_features!(tri::Triangulation)
Clears all empty features from the triangulation tri
.
DelaunayTriangulation.clear_empty_keys!
— Methodclear_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!
— Methodclear_empty_vertices!(G::Graph)
Deletes all empty vertices from G
.
DelaunayTriangulation.clip_all_polygons!
— Methodclip_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
: TheVoronoiTessellation
.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
— Methodclip_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
: TheVoronoiTessellation
.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!
— Methodclip_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
: TheVoronoiTessellation
.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
— Methodclip_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 andclipped_polygon[begin] == clipped_polygon[end]
.
DelaunayTriangulation.clip_unbounded_polygon_to_bounding_box
— Methodclip_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!
— Functionclip_voronoi_tessellation!(vorn::VoronoiTessellation, is_convex=true)
Clip the Voronoi tessellation vorn
to the convex hull of the generators in vorn
.
Arguments
vorn
: TheVoronoiTessellation
.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!
— Methodclose_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
: TheVoronoiTessellation
.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!
— Methodcoarse_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!
— Methodcollapse_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
— Methodcompare_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 ofpts
corresponding to the distancecurrent_dist
.pts
: The point set.i
: The vertex to compare withcurrent_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 thei
th point ofpts
and(qx, qy)
andcurrent_dist
.current_idx
: The point ofpts
corresponding to the distancecurrent_dist
, which will be eitheri
orcurrent_idx
.
DelaunayTriangulation.compare_triangle_collections
— Methodcompare_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
— Methodcompare_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
— Methodcompareunorientededge_collections(E, F) -> Bool
Tests if the edge collections E
and F
are equal, ignoring edge orientation.
DelaunayTriangulation.compare_unoriented_edges
— Methodcompare_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!
— Functioncomplete_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
: TheTriangulation
.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 ifstore_event_history
is true, in which case it needs to be anInsertionEventHistory
object.
Outputs
There is no output, as tri
is updated in-place.
DelaunayTriangulation.complete_split_triangle_and_legalise!
— Methodcomplete_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
: TheTriangulation
.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
— Methodcompute_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!
— Methodcompute_centroid!(c::RepresentativeCoordinates, points)
Computes the centroid of points
and stores the result in c
.
DelaunayTriangulation.compute_concentric_shell_quarternary_split_position
— Methodcompute_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
— Methodcompute_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
— Methodcompute_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
— Methodcompute_height(node::Union{Nothing,BalancedBSTNode{K}}) -> Int8
Computes the height of the subtree rooted at node
.
DelaunayTriangulation.compute_representative_points!
— Methodcompute_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
: TheTriangulation
for which to compute the representative points.
Keyword Arguments
use_convex_hull=!has_boundary_nodes(tri)
: Iftrue
, 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 viapole_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
— Methodcompute_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
— Methodcompute_split_position(tri::Triangulation, args::RefinementArguments, e) -> NTuple{2, Float}
Computes the position to split a segment e
of tri
at in split_subsegment!
.
Arguments
tri::Triangulation
: TheTriangulation
to split a segment of.args::RefinementArguments
: TheRefinementArguments
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 bysegment_vertices_adjoin_other_segments_at_acute_angle
, then the point is returned so thate
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 ofe
, computed usingcompute_concentric_shell_quarternary_split_position
. - If
e
is a subsegment and the segment adjoins one other segment at an acute angle, as determined bysegment_vertices_adjoin_other_segments_at_acute_angle
, then the point is returned so thate
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 ofe
, computed usingcompute_concentric_shell_ternary_split_position
. - Otherwise, the midpoint is returned.
DelaunayTriangulation.concavity_protection_check
— Methodconcavity_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
: TheTriangulation
.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 befalse
ifconcavity_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!
— Methodconnect_circumcenters!(B, ci)
Add the circumcenter index ci
to the array B
.
DelaunayTriangulation.connect_segments!
— Methodconnect_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!
— Methodconstrained_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
: TheTriangulation
.segments
: The interior segments to add to the triangulation.boundary_nodes
: The boundary nodes to add to the triangulation.full_polygon_hierarchy
: ThePolygonHierarchy
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. Seedelete_holes!
.
Outputs
new_tri
: The new triangulation, now containingsegments
in theinterior_segments
field andboundary_nodes
in theboundary_nodes
field, and with the updatedPolygonHierarchy
. See alsoremake_triangulation_with_constraints
andreplace_ghost_vertex_information
.
DelaunayTriangulation.construct_boundary_edge_map
— Methodconstruct_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!
— Methodconstruct_curve_index_map!(enricher::BoundaryEnricher)
Constructs the curve index map for enricher
, modifying the curve index map field in-place.
DelaunayTriangulation.construct_edge
— Functionconstruct_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
— Methodconstruct_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
— Methodconstruct_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!
— Methodconstruct_parent_map!(enricher::BoundaryEnricher)
Constructs the parent map for enricher
, modifying the parent map field in-place.
DelaunayTriangulation.construct_polygon_hierarchy
— Methodconstruct_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 fromconvert_boundary_curves!
.boundary_curves
: The boundary curves. These should be the output fromconvert_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 inpolygonise
.
DelaunayTriangulation.construct_polygon_hierarchy
— Methodconstruct_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
— Methodconstruct_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
— Methodconstruct_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
— Methodconstruct_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
— Methodconstruct_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!
— Methodconstruct_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
— Functionconstruct_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
— Methodcontains_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
— Functioncontains_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
— Methodcontains_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
— Functioncontains_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
— Methodcontains_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 ofT
that is intri
, or simplyT
ifT
is not intri
.flag
:true
ifT
is intri
, andfalse
otherwise.
DelaunayTriangulation.contains_unoriented_edge
— Methodcontains_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!
— Methodconvert_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
fromto_boundary_curves
. boundary_nodes
is replaced with a set of initial boundary nodes (fromget_skeleton
). These nodes come from evaluating each boundary curve att = 0
andt = 1
. In the case of a piecewise linear boundary, the vertices are copied directly. Note that not all control points of aCatmullRomSpline
(whichis_interpolating
) will be added - only those att = 0
andt = 1
.- The
points
are modified to include the new boundary nodes. If a point is already inpoints
, 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 withboundary_nodes
.boundary_nodes
: The modified boundary nodes.
DelaunayTriangulation.convert_boundary_points_to_indices
— Functionconvert_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
: Thex
andy
-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 asexisting_points
but with the boundary points appended to it.
DelaunayTriangulation.convert_certificate
— Methodconvert_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
— Methodconvert_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
— Methodconvert_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
— Methodconvert_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!
— Methodconvex_hull!(tri::Triangulation; reconstruct=has_boundary_nodes(tri))
Updates the convex_hull
field of tri
to match the current triangulation.
Arguments
tri::Triangulation
: TheTriangulation
.
Keyword Arguments
reconstruct=has_boundary_nodes(tri)
: Iftrue
, then the convex hull is reconstructed from scratch, usingconvex_hull
on the points. Otherwise, computes the convex hull using the ghost triangles oftri
. If there are no ghost triangles butreconstruct=true
, then the convex hull is reconstructed from scratch.
DelaunayTriangulation.convex_hull!
— Methodconvex_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
— Methodconvex_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
: TheConvexHull
.
DelaunayTriangulation.curvature
— Methodcurvature(c::AbstractParametricCurve, t) -> Float64
Returns the curvature of the [AbstractParametricCurve
] c
at t
.
DelaunayTriangulation.decrement_num_elements!
— Methoddecrement_num_elements!(tree::RTree)
Decrements the number of elements in tree
by 1.
DelaunayTriangulation.default_displacement_tolerance
— Methoddefault_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
: TheVoronoiTessellation
.
Outputs
tol
: The default displacement tolerance.
DelaunayTriangulation.default_num_samples
— Methoddefault_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!
— Methoddelete_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!
— Methoddelete_adjacent!(tri::Triangulation, uv)
delete_adjacent!(tri::Triangulation, u, v)
Deletes the key (u, v)
from the adjacency map of tri
.
DelaunayTriangulation.delete_adjacent!
— Methoddelete_adjacent!(vor::VoronoiTessellation, ij)
delete_adjacent!(vor::VoronoiTessellation, i, j)
Deletes the edge (i, j)
from the adjacency map of vor
.
DelaunayTriangulation.delete_adjacent2vertex!
— Methoddelete_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!
— Methoddelete_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!
— Methoddelete_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!
— Methoddelete_adjacent2vertex!(tri::Triangulation, w)
Deletes the key w
from the Adjacent2Vertex
map of tri
.
DelaunayTriangulation.delete_all_exterior_triangles!
— Methoddelete_all_exterior_triangles!(tri::Triangulation, triangles)
Deletes all the triangles in the set triangles
from the triangulation tri
.
DelaunayTriangulation.delete_boundary_node!
— Methoddelete_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!
— Methoddelete_boundary_node!(tri::Triangulation, pos)
Deletes the boundary node at the specified position pos
in tri
.
Arguments
tri::Triangulation
: TheTriangulation
.pos
: The position to delete the node at, given as aTuple
so thatdelete_boundary_node!(tri, pos)
is the same asdeleteat!(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!
— Methoddelete_child!(tree::PolygonTree, child::PolygonTree)
Deletes child
from tree
.
DelaunayTriangulation.delete_edge!
— Methoddelete_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!
— Methoddelete_edge!(boundary_enricher::BoundaryEnricher, i, j)
Deletes the edge (i, j)
in boundary_enricher
.
DelaunayTriangulation.delete_edge!
— Methoddelete_edge!(events::InsertionEventHistory, e)
Add the edge e
to the deleted_segments
of events
.
DelaunayTriangulation.delete_edge!
— Methoddelete_edge!(G::Graph, u, v)
Deletes the edge (u, v)
from G
.
DelaunayTriangulation.delete_free_vertices_around_subsegment!
— Methoddelete_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
: TheTriangulation
.args::RefinementArguments
: TheRefinementArguments
.e
: The segment.
Output
The free vertices are deleted from tri
in-place.
DelaunayTriangulation.delete_from_edges!
— Methoddelete_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!
— Methoddelete_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!
— Methoddelete_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!
— Methoddelete_ghost_vertices_from_graph!(tri::Triangulation)
Deletes all ghost vertices from the graph of tri
.
DelaunayTriangulation.delete_ghost_vertices_from_graph!
— Methoddelete_ghost_vertices!(G::Graph)
Deletes all ghost vertices from G
.
DelaunayTriangulation.delete_holes!
— Methoddelete_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!
— Methoddelete_intersected_triangles!(tri, triangles)
Deletes the triangles in triangles
from tri
.
DelaunayTriangulation.delete_neighbour!
— Methoddelete_neighbour!(tri::Triangulation, u, v...)
Deletes the neighbours v...
from u
in the graph of tri
.
DelaunayTriangulation.delete_neighbour!
— Methoddelete_neighbour!(G::Graph, u, v...)
Deletes the neighbours v...
from u
in G
.
DelaunayTriangulation.delete_node!
— Methoddelete_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!
— Methoddelete_point!(c::RepresentativeCoordinates, p)
Treating c
as an arithmetic average, updates the coordinates of c
to exclude p
.
DelaunayTriangulation.delete_point!
— Methoddelete_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 ifstore_event_history
is true, in which case it needs to be anInsertionEventHistory
object.rng::AbstractRNG=Random.default_rng()
: The random number generator to use for the triangulation.
DelaunayTriangulation.delete_polygon_adjacent!
— Methoddelete_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!
— Methoddelete_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
: TheTriangulation
.u
,v
: The vertices of the segment(u, v)
that was inserted in order to define the polygonV = list.S
.rng::AbstractRNG
: The random number generator to use.
Outputs
There is no output, but list
is updated in-place.
DelaunayTriangulation.delete_tree!
— Methoddelete_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!
— Functiondelete_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!
— Methoddelete_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!
— Methoddelete_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!
— Methoddelete_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!
— Methoddelete_triangle!(events::InsertionEventHistory, T)
Add the triangle T
to the deleted_triangles
of events
.
DelaunayTriangulation.delete_triangle!
— Methoddelete_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
: Iftrue
, then the boundary edges will not be updated. Otherwise,delete_boundary_edges_single!
,delete_boundary_edges_double!
, ordelete_boundary_edges_triple!
will be called depending on the number of boundary edges in the triangle.update_ghost_edges=false
: Iftrue
, then the ghost edges will be updated. Otherwise, the ghost edges will not be updated. Will only be used ifprotect_boundary=false
.
Outputs
There are no outputs as tri
is updated in-place.
DelaunayTriangulation.delete_unbounded_polygon!
— Methoddelete_unbounded_polygon!(vor::VoronoiTessellation, i)
Deletes the index i
from the set of unbounded polygons of vor
.
DelaunayTriangulation.delete_unoriented_edge!
— Methoddelete_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!
— Methoddelete_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!
— Methoddelete_vertex!(tri::Triangulation, u...)
Deletes the vertices u...
from the graph of tri
.
DelaunayTriangulation.delete_vertex!
— Methoddelete_vertex!(G::Graph, u...)
Deletes the vertices u...
from G
.
DelaunayTriangulation.delete_vertices_in_random_order!
— Methoddelete_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
: TheTriangulation
.rng::AbstractRNG
: The random number generator used to shuffle the vertices ofS
.
Outputs
There is no output, as list
is modified in-place.
DelaunayTriangulation.dequeue_and_process!
— Methoddequeue_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
: TheVoronoiTessellation
.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 ofleft_edge
with other edges.right_edge_intersectors
: The intersection points ofright_edge
with other edges.current_edge_intersectors
: The intersection points ofcurrent_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 inedges_to_process
usingenqueue_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 frompolygon_edge_queue
usingprocess_polygon!
. This function checks for intersections of theedge
with thepolygon
. - 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 withedge
, or with the edge left ofedge
, or to the edge right ofedge
. - 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!
— Methoddetach!(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
— Methoddiametral_circle(p, q) -> (NTuple{2,Float64}, Float64)
Returns the circle with diameter pq
.
DelaunayTriangulation.differentiate
— Functiondifferentiate(c::AbstractParametricCurve, t) -> NTuple{2, Float64}
Evaluates the derivative of c
at t
.
DelaunayTriangulation.dig_cavity!
— Methoddig_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
: TheTriangulation
.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 ofr
relative toV
. Seepoint_position_relative_to_triangle
.V
: The triangle intri
containingr
.store_event_history=Val(false)
: Iftrue
, then the event history from the insertion is stored.event_history=nothing
: The event history to store the event history in. Should be anInsertionEventHistory
ifstore_event_history
istrue
, andfalse
otherwise.peek=Val(false)
: Whether to actually addnew_point
intotri
, or just record intoevent_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, ℓ)
fromtri
and then calldig_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)
intotri
to connectr
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 ofV
might imply that we are going to add a degenerate triangle(r, i, j)
intotri
, and so this needs to be avoided. So, we check ifis_on(flag) && contains_segment(tri, i, j)
and, if the edge thatr
is on is(i, j)
, we add the triangle(r, i, j)
. Otherwise, we do nothing.
DelaunayTriangulation.dist
— Methoddist(p, q) -> Number
Assuming p
and q
are two-dimensional, computes the Euclidean distance between p
and q
.
DelaunayTriangulation.dist
— Methoddist(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, thenp
is inside the triangulation.δ < 0
: If the returned distance is negative, thenp
is outside the triangulation.δ = 0
: If the returned distance is zero, thenp
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
— Methoddist_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
— Methoddistance_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
— Methoddistance_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
— Methodeach_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
— Methodeach_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
— Methodeach_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
— Methodeach_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
— Methodeach_boundary_edge(tri::Triangulation) -> KeySet
Returns an iterator over the boundary edges of tri
, in no specific order.
DelaunayTriangulation.each_boundary_node
— Methodeach_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
— Functioneach_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
— Methodeach_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
— Methodeach_boundary_polygon(vorn::VoronoiTessellation) -> KeySet
Returns an iterator over the boundary polygon indices of vorn
.
DelaunayTriangulation.each_ghost_edge
— Methodeach_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
— Methodeach_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
— Methodeach_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
— Functioneach_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
— Methodeach_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
— Functioneach_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
— Methodeach_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
— Methodeach_polygon(vor::VoronoiTessellation) -> ValueIterator
Returns an iterator over each set of polygon vertices of vor
.
DelaunayTriangulation.each_polygon_index
— Methodeach_polygon_index(vor::VoronoiTessellation) -> KeySet
Returns an iterator over the polygon indices of vor
.
DelaunayTriangulation.each_polygon_vertex
— Methodeach_polygon_vertex(vor::VoronoiTessellation) -> UnitRange
Returns an iterator over each polygon point index of vor
.
DelaunayTriangulation.each_segment
— Methodeach_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
— Methodeach_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
— Methodeach_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
— Methodeach_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
— Functioneach_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
— Methodeach_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
— Methodeach_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
— Methodedge_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
— Functionedge_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
— Methodedge_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
— Methodedge_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
— Methodedge_type(tri::Triangulation) -> DataType
Returns the type used for representing individual edges in tri
.
DelaunayTriangulation.edge_type
— Methodedge_type(vorn::VoronoiTessellation) -> DataType
Type used for representing individual edges in the Voronoi tessellation.
DelaunayTriangulation.edge_vertices
— Methodedge_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
— Methodedges_are_disjoint(e, e′) -> Bool
Returns true
if e
and e′
have any shared vertex, and false
otherwise.
DelaunayTriangulation.edges_type
— Methodedges_type(tri::Triangulation) -> DataType
Returns the type used for representing collections of edges in tri
.
DelaunayTriangulation.empty_representative_points!
— Methodempty_representative_points!(tri::Triangulation)
Empties the Dict
of representative points of tri
.
DelaunayTriangulation.empty_unconstrained_triangulation!
— Methodempty_unconstrained_triangulation!(tri::Triangulation)
Empties the triangulation tri
by emptying its fields. Only works for unconstrained triangulaions.
DelaunayTriangulation.encroaches_upon
— Methodencroaches_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!
— Methodenqueue_all!(queue::Queue, data)
Adds all data
to the end of the queue
.
DelaunayTriangulation.enqueue_all_bad_triangles!
— Methodenqueue_all_bad_triangles!(args::RefinementArguments, tri::Triangulation)
Enqueues all bad triangles in the triangulation into args.queue
.
DelaunayTriangulation.enqueue_all_encroached_segments!
— Methodenqueue_all_encroached_segments!(args::RefinementArguments, tri::Triangulation)
Enqueues all encroached segments in the triangulation into args.queue
.
DelaunayTriangulation.enqueue_new_edge!
— Methodenqueue_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
: TheVoronoiTessellation
.e
: The edge to be processed.
Outputs
There are no outputs, as polygon_edge_queue
is modified in-place.
DelaunayTriangulation.enqueue_newly_encroached_segments!
— Methodenqueue_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
: TheRefinementArguments
for the refinement.tri::Triangulation
: TheTriangulation
to enqueue newly encroached segments of.
Output
any_encroached
: Whether any segments were newly encroached upon.
DelaunayTriangulation.enrich_boundary!
— Methodenrich_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
— Methodeval_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
— Methodeval_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
— Methodeval_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
— Methodeval_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
— Methodeval_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
— Functionexpand(box::BoundingBox, perc=0.10) -> BoundingBox
Expands the bounding box box
by a factor perc
in each direction.
DelaunayTriangulation.expand_bounds!
— Functionexpand_bounds!(hierarchy::PolygonHierarchy, perc=0.10) -> PolygonHierarchy
Expands the bounding boxes of hierarchy
by a factor of perc
in each direction.
DelaunayTriangulation.extend_segments!
— Methodextend_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
— Functionexterior_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
: TheTriangulation
.k
: The exterior boundary vertex to start from.q
: The query point.ghost_vertex=𝒢
: The ghost vertex corresponding to the boundary thatk
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!
— Methodfinalise!(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
— Methodfind_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
: TheVoronoiTessellation
.
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 frompolygon_edge_queue
and process it viadequeue_and_process!
. - We repeat step 2 until
polygon_edge_queue
andedges_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!
— Methodfind_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
: TheTriangulation
.seed
: The seed vertex to start spreading from.all_bn
: All the boundary nodes in the triangulation, obtained fromget_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
— Methodfind_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
— Methodfind_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
: TheTriangulation
.points_to_process
: The set of points that are in the exterior faces of the triangulationtri
, obtained fromfind_all_points_to_delete
.
Outputs
triangles_to_delete
: The set of triangles that are in the exterior faces of the triangulationtri
.
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 vertexv
, the triangles adjoining it, given byget_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
— Methodfind_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
— Methodfind_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
— Methodfind_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
— Methodfind_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
— Methodfind_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
— Methodfind_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
— Methodfind_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
— Methodfind_tree(hierarchy::PolygonHierarchy, points, boundary_nodes, p) -> Union{Nothing,PolygonTree}
Finds a tree in hierarchy
containing p
.
Arguments
hierarchy::PolygonHierarchy
: ThePolygonHierarchy
to search.points
: The point set.boundary_nodes
: The boundary nodes.p
: The point to test the trees ofhierarchy
against.
Output
nothing
ifp
is not inside any tree inhierarchy
, and thePolygonTree
containingp
otherwise.
DelaunayTriangulation.find_tree
— Methodfind_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
: ThePolygonHierarchy
to search.points
: The point set.boundary_nodes
: The boundary nodes.tree::PolygonTree
: ThePolygonTree
to search, assumingp
is insidetree
.p
: The point to test the children oftree
against.
Output
tree
ifp
is insidetree
but none of its children, and a child containingp
otherwise.
DelaunayTriangulation.fix_down!
— Methodfix_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!
— Methodfix_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
: TheTriangulation
.segment
: The segment that was arranged.e
: The arranged segment fromoptimise_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!
— Methodfix_edges_after_deletion!(tri::Triangulation, S)
Ensures that the edges in S
surrounding a deleted vertex of tri
are correctly updated.
DelaunayTriangulation.fix_segments!
— Methodfix_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!
— Methodfix_up!(queue::MaxPriorityQueue, k)
Fixes the queue
after increasing the value of one of its elements by percolating upwards.
DelaunayTriangulation.flip_edge!
— Methodflip_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
: TheTriangulation
.i
: The first vertex of the edge to flip.j
: The second vertex of the edge to flip.k
: The vertexk = 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 ifstore_event_history
is true, in which case it needs to be anInsertionEventHistory
object. This storage is done usingstore_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_all_boundary_nodes(tri::Triangulation) -> Set{Vertex}
Returns the set of all boundary vertices in tri
, in no specific order.
DelaunayTriangulation.get_all_segments
— Methodget_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
— Methodget_all_stat(stats::TriangulationStatistics, stat::Symbol) -> Vector
Returns a vector of the statistic stat
for each triangle in stats
.
DelaunayTriangulation.get_angles
— Methodget_angles(stats::TriangulationStatistics, T)
Returns the angles field from the individual triangle statistics for the triangle T
in the TriangulationStatistics
stats
.
DelaunayTriangulation.get_apex
— Methodget_apex(complex::SmallAngleComplex{I}) where {I} -> I
Returns the apex of complex
.
DelaunayTriangulation.get_area
— Methodget_area(r::BoundingBox) -> Float64
Returns the area of r
, i.e. hspan(r) * vspan(r)
.
DelaunayTriangulation.get_area
— Methodget_area(stats::TriangulationStatistics, T)
Returns the area field from the individual triangle statistics for the triangle T
in the TriangulationStatistics
stats
.
DelaunayTriangulation.get_area
— Methodget_area(stats::TriangulationStatistics)
Returns the area field from the TriangulationStatistics
stats
.
DelaunayTriangulation.get_area
— Methodget_area(tri::Triangulation) -> Number
Returns the area of tri
.
DelaunayTriangulation.get_area
— Methodget_area(vor::VoronoiTessellation, i) -> Number
Gets the area of the i
th Voronoi polygon.
DelaunayTriangulation.get_aspect_ratio
— Methodget_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
— Methodget_bl_corner(r::BoundingBox) -> NTuple{2,Float64}
Returns the bottom-left corner of r
.
DelaunayTriangulation.get_boundary_chain
— Methodget_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
— Methodget_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
— Methodget_boundary_curves(boundary_enricher::BoundaryEnricher{P,B,C}) -> C
Returns the boundary curves associated with boundary_enricher
.
DelaunayTriangulation.get_boundary_curves
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_boundary_enricher(tri::Triangulation) -> BoundaryEnricher
Returns the BoundaryEnricher
of tri
. If the domain is not curve-bounded, this is nothing
.
DelaunayTriangulation.get_boundary_nodes
— Functionget_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)
: Ifboundary_nodes
has multiple curves, this returns them
th curve. Ifboundary_nodes
has multiple sections, this returns them
th section. Otherwise, this returns them
th boundary node.get_boundary_nodes(boundary_nodes, m, n)
: Ifboundary_nodes
has multiple curves, this returns then
th section of them
th curve. Otherwise, ifboundary_nodes
has multiple sections, this returns then
th boundary node of them
th section.get_boundary_nodes(boundary_nodes, (m, n))
: This is equivalent toget_boundary_nodes(boundary_nodes, m, n)
.get_boundary_nodes(boundary_nodes::A, ::A)
: This just returnsboundary_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
— Methodget_boundary_nodes(boundary_enricher::BoundaryEnricher{P,B}) -> B
Returns the boundary nodes associated with boundary_enricher
.
DelaunayTriangulation.get_boundary_nodes
— Methodget_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)
: Iftri
has multiple curves, this returns them
th curve. Iftri
has multiple sections, this returns them
th section. Otherwise, this returns them
th boundary node.get_boundary_nodes(tri, m, n)
: Iftri
has multiple curves, this returns then
th section of them
th curve. Otherwise, iftri
has multiple sections, this returns then
th boundary node of them
th section.get_boundary_nodes(tri, (m, n))
: This is equivalent toget_boundary_nodes(tri, m, n)
.get_boundary_nodes(tri::A, ::A)
: This just returnsboundary_nodes
.
DelaunayTriangulation.get_boundary_nodes
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_bounding_box(node::AbstractNode) -> BoundingBox
Returns the bounding box of node
.
DelaunayTriangulation.get_bounding_box
— Methodget_bounding_box(id_bounding_box::DiametralBoundingBox) -> BoundingBox
Returns the bounding box of id_bounding_box
.
DelaunayTriangulation.get_bounding_box
— Methodget_bounding_box(hierarchy::PolygonHierarchy, index) -> BoundingBox
Returns the bounding box of the index
th polygon in hierarchy
.
DelaunayTriangulation.get_bounding_box
— Methodget_bounding_box(tree::RTree) -> BoundingBox
Returns the bounding box of tree
.
DelaunayTriangulation.get_bounding_boxes
— Methodget_bounding_boxes(hierarchy::PolygonHierarchy) -> Vector{BoundingBox}
Returns the bounding boxes of hierarchy
.
DelaunayTriangulation.get_branch_cache
— Methodget_branch_cache(tree::RTree) -> BranchCache
Returns the branch cache of tree
.
DelaunayTriangulation.get_cache
— Methodget_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
— Methodget_centroid(stats::TriangulationStatistics, T)
Returns the centroid field from the individual triangle statistics for the triangle T
in the TriangulationStatistics
stats
.
DelaunayTriangulation.get_centroid
— Methodget_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
— Methodget_child(node::AbstractNode, i::Integer) -> AbstractNode
Returns the i
th child of node
.
DelaunayTriangulation.get_child_type
— Methodget_child_type(node::AbstractNode) -> Union{Type{Leaf}, Type{Branch}}
Returns the type of the children of node
.
DelaunayTriangulation.get_children
— Methodget_children(node::AbstractNode) -> Vector
Returns the children of node
.
DelaunayTriangulation.get_children
— Methodget_children(tree::PolygonTree) -> Set{PolygonTree}
Returns the children of tree
.
DelaunayTriangulation.get_circle_intersection
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
: TheVoronoiTessellation
.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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_count(node::Union{Nothing, BalancedBSTNode}) -> Int32
Returns the count of node
. If the node
is nothing
, returns 0
.
DelaunayTriangulation.get_count
— Methodget_count(tree::BalancedBST{K}) -> Int32
DelaunayTriangulation.get_curve_index
— Functionget_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
— Methodget_curve_index(tri::Triangulation, ℓ) -> Integer
Returns the curve index corresponding to the ghost vertex ℓ
in tri
.
DelaunayTriangulation.get_curve_index_map
— Methodget_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
— Methodget_detached_cache(tree::RTree) -> Vector{Union{Branch,Leaf{Branch}}}
Returns the detached cache of tree
.
DelaunayTriangulation.get_distance_to_plane
— Methodget_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" getdistancetowitnessplane(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
— Methodget_edge(id_bounding_box::DiametralBoundingBox) -> NTuple{2,Int}
Returns the generator edge of id_bounding_box
.
DelaunayTriangulation.get_edge_midpoints
— Methodget_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
— Methodget_edges(graph::Graph) -> Set{NTuple{2, Vertex}}
Returns the set of edges in graph
.
DelaunayTriangulation.get_edges
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_exterior_curve_indices(hierarchy::PolygonHierarchy) -> KeySet
Returns the indices of the exterior curves of hierarchy
.
DelaunayTriangulation.get_exterior_curve_indices
— Methodget_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
— Methodget_fan_triangles(cache::TriangulationCache) -> Triangles
Returns the triangles in a fan stored in cache
.
DelaunayTriangulation.get_fill_factor
— Methodget_fill_factor(tree::RTree) -> Float64
Returns the fill factor of tree
.
DelaunayTriangulation.get_free_cache
— Methodget_free_cache(tree::RTree) -> BitVector
Returns the free cache of tree
.
DelaunayTriangulation.get_generator
— Methodget_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
— Methodget_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
— Functionget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_graph(tri::Triangulation) -> Graph
Returns the Graph
of the triangulation tri
. This is an undirected graph.
DelaunayTriangulation.get_height
— Methodget_height(node::Union{Nothing, BalancedBSTNode}) -> Int8
Returns the height of node
. If the node
is nothing
, returns 0
.
DelaunayTriangulation.get_height
— Methodget_height(tree::PolygonTree) -> Int
Returns the height of tree
.
DelaunayTriangulation.get_height
— Methodget_height(tree::RTree) -> Int
Returns the height of tree
.
DelaunayTriangulation.get_index
— Methodget_index(tree::PolygonTree{I}) -> I
Returns the index of tree
.
DelaunayTriangulation.get_individual_statistics
— Methodget_individual_statistics(stats::TriangulationStatistics)
Returns the individual_statistics field from the TriangulationStatistics
stats
.
DelaunayTriangulation.get_init_for_steiner_point
— Methodget_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
— Methodget_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. Seeget_insertion_order
.num_sample_rule::F
: The rule to use to determine the number of points to sample. Seedefault_num_samples
for the default.rng::AbstractRNG
: The random number generator to use.try_last_inserted_point
: Iftrue
, then the last inserted point is also considered as the start point.
Output
initial_search_point
: The vertex to start the point location withjump_and_march
at.
DelaunayTriangulation.get_initial_triangle
— Functionget_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. Seeget_insertion_order
.itr=0
: To avoid issues with degenerate triangles and infinite loops, this counts the number of timesinsertion_order
had to be shifted usingcircshift!
to find an initial non-degenerate triangle.
Output
initial_triangle
: The initial triangle.
DelaunayTriangulation.get_inradius
— Methodget_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
— Methodget_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
: Iftrue
, 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
— Methodget_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
— Methodget_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
— Methodget_intersection_cache(tree::RTree) -> NTuple{2,RTreeIntersectionCache}
Returns the intersection cache of tree
.
DelaunayTriangulation.get_intersections
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_inverse(c::AbstractParametricCurve, p) -> Float64
Given a point p
on c
, returns the t
-value such that c(t) ≈ p
.
DelaunayTriangulation.get_inverse
— Methodget_inverse(enricher::BoundaryEnricher, curve_index, q) -> Float64
Returns the inverse of the curve_index
th curve at q
.
DelaunayTriangulation.get_key
— Methodget_key(node::BalancedBSTNode{K}) -> K
Returns the key associated with node
.
DelaunayTriangulation.get_largest_angle
— Methodget_largest_angle(stats::TriangulationStatistics)
Returns the largest_angle field from the TriangulationStatistics
stats
.
DelaunayTriangulation.get_largest_area
— Methodget_largest_area(stats::TriangulationStatistics)
Returns the largest_area field from the TriangulationStatistics
stats
.
DelaunayTriangulation.get_largest_radius_edge_ratio
— Methodget_largest_radius_edge_ratio(stats::TriangulationStatistics)
Returns the largestradiusedge_ratio field from the TriangulationStatistics
stats
.
DelaunayTriangulation.get_lattice_boundary
— Methodget_lattice_boundary(nx, ny, sub2ind, single_boundary, IntegerType)
Returns the boundary nodes defining a lattice.
Arguments
nx
: The number ofx
points in the lattice.ny
: The number ofy
points in the lattice.sub2ind
: The map returned fromget_lattice_triangles
.single_boundary
: Iftrue
, 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.IntegerType
: The type used for representing vertices.
Outputs
boundary_nodes
: The boundary nodes, returned according tosingle_boundary
as described above.
DelaunayTriangulation.get_lattice_points
— Methodget_lattice_points(a, b, c, d, nx, ny, sub2ind)
Returns the points on a lattice [a, b] × [c, d]
.
Arguments
a
: The minimumx
-coordinate.b
: The maximumx
-coordinate.c
: The minimumy
-coordinate.d
: The maximumy
-coordinate.nx
: The number of points in thex
-direction.ny
: The number of points in they
-direction.sub2ind
: The map returned fromget_lattice_triangles
.
Outputs
points
: The points on the lattice, wherepoints[sub2ind[CartesianIndex(i, j)]]
is the point at thei
thx
point and thej
thy
point,
DelaunayTriangulation.get_lattice_triangles
— Methodget_lattice_triangles(nx, ny, Ts, V)
Computes the triangles defining a lattice with nx
and ny
points in the x
- and y
-directions, respectively.
Arguments
nx
: The number ofx
points in the lattice.ny
: The number ofy
points in the lattice.Ts
: The type to use for representing a collection of triangles.V
: The type to use for representing an individual triangle.
Outputs
T
: The collection of triangles.sub2ind
: A map that takes cartesian indices(i, j)
into the associated linear index along the lattice. SeeLinearIndices
.
DelaunayTriangulation.get_leaf_cache
— Methodget_leaf_cache(tree::RTree) -> LeafCache
Returns the leaf cache of tree
.
DelaunayTriangulation.get_left
— Methodget_left(node::BalancedBSTNode) -> Union{Nothing, BalancedBSTNode}
Returns the left child of node
. If the node
is nothing
, returns nothing
.
DelaunayTriangulation.get_left_boundary_node
— Methodget_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
: TheTriangulation
.k
: The boundary vertex.ghost_vertex
: The ghost vertex associated with the boundary section thatk
is on.
Outputs
ℓ
: The vertex left ofk
on the boundary.
DelaunayTriangulation.get_lengths
— Methodget_lengths(stats::TriangulationStatistics, T)
Returns the lengths field from the individual triangle statistics for the triangle T
in the TriangulationStatistics
stats
.
DelaunayTriangulation.get_level
— Functionget_level(node::AbstractNode) -> Int
Returns the level of node
. If node
is a leaf, returns 1
.
DelaunayTriangulation.get_lifted_point
— Methodget_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
— Methodget_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
— Methodget_marked_vertices(cache::TriangulationCache) -> Vector{Vertex}
Returns the marked vertices stored in cache
.
DelaunayTriangulation.get_maximum_angle
— Methodget_maximum_angle(stats::TriangulationStatistics, T) -> Float64
Returns the maximum angle of T
from stats
.
DelaunayTriangulation.get_median_angle
— Methodget_median_angle(stats::TriangulationStatistics, T) -> Float64
Returns the median angle of T
from stats
.
DelaunayTriangulation.get_members
— Methodget_members(complex::SmallAngleComplex{I}) where {I} -> Vector{SmallAngleComplexMember{I}}
Returns the members of complex
.
DelaunayTriangulation.get_min_nodes
— Methodget_min_nodes(tree::RTree) -> Int
Returns the minimum number of nodes that a node in tree
can have.
DelaunayTriangulation.get_minimum_angle
— Methodget_minimum_angle(stats::TriangulationStatistics, T) -> Float64
Returns the minimum angle of T
from stats
.
DelaunayTriangulation.get_minimum_edge_length
— Methodget_minimum_edge_length(complex::SmallAngleComplex, points) -> Float64
Returns the minimum edge length in complex
with respect to points
.
DelaunayTriangulation.get_nearest_neighbour
— Functionget_nearest_neighbour(tri_or_vor, q; kwargs...)
Get the index of the nearest neighbour of q
in tri_or_vor
.
Arguments
tri_or_vor
: ATriangulation
orVoronoiTessellation
.q
: The point to be located.
Keyword Arguments
kwargs...
: Keyword arguments passed tojump_and_march
.
Output
i
: The index of the nearest neighbour. This is a point of the triangulation iftri_or_vor
is aTriangulation
or of a generator iftri_or_vor
is aVoronoiTessellation
.
DelaunayTriangulation.get_need_tests
— Methodget_need_tests(cache::RTreeIntersectionCache) -> BitVector
Returns the need_tests
cache of tree
.
DelaunayTriangulation.get_neighbouring_boundary_edges
— Methodget_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 triangulatione
: The boundary edge.
Outputs
left_e
: The left edge.right_e
: The right edge.
DelaunayTriangulation.get_neighbouring_boundary_edges
— Methodget_neighbouring_boundary_edges(vorn::VoronoiTessellation, e) -> (Edge, Edge)
Given a boundary edge e
, returns the edges left and right of e
.
DelaunayTriangulation.get_neighbours
— Methodget_neighbours(G::Graph, u) -> Set{Vertex}
Returns the set of neighbours of u
in G
.
DelaunayTriangulation.get_neighbours
— Methodget_neighbours(graph::Graph) -> Dict{Vertex, Set{Vertex}}
Returns the neighbours
map of graph
.
DelaunayTriangulation.get_neighbours
— Methodget_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
— Methodget_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
— Methodget_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
: TheVoronoiTessellation
.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 innew_vertices
.
DelaunayTriangulation.get_next_cell!
— Methodget_next_cell!(queue::CellQueue)
Returns the next cell in the queue.
DelaunayTriangulation.get_next_child
— Methodget_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
— Methodget_next_edge(member::SmallAngleComplexMember{I}) where {I} -> I
Returns the next edge of member
.
DelaunayTriangulation.get_next_triangle_for_voronoi_polygon
— Methodget_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
: TheVoronoiTessellation
.i
: The polygon index.k
: The vertex to add.S
: The surrounding polygon ofi
. Seeget_surrounding_polygon
.m
: The index of the next vertex inS
.
Outputs
ci
: The index for the circumcenter of the next triangle.k
: The next vertex inS
after the inputk
.
DelaunayTriangulation.get_node_indices
— Methodget_node_indices(cache::RTreeIntersectionCache) -> Vector{Int}
Returns the node indices of cache
.
DelaunayTriangulation.get_offcenter
— Methodget_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
— Methodget_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
— Methodget_parent(node::AbstractNode) -> Union{Branch, Nothing}
Returns the parent of node
.
DelaunayTriangulation.get_parent
— Methodget_parent(node::BalancedBSTNode) -> Union{Nothing, BalancedBSTNode}
Returns the parent of node
. If the node
is nothing
, returns nothing
.
DelaunayTriangulation.get_parent
— Methodget_parent(tree::PolygonTree) -> Union{Nothing,PolygonTree}
Returns the parent of tree
.
DelaunayTriangulation.get_parent
— Methodget_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
— Methodget_parent_curve(member::SmallAngleComplexMember{I}) where {I} -> I
Returns the parent curve of member
.
DelaunayTriangulation.get_parent_map
— Methodget_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
— Methodget_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
— Methodget_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
— Functionget_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
— Methodget_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
— Methodget_points(convex_hull::ConvexHull) -> Points
Returns the underlying point set of convex_hull
.
DelaunayTriangulation.get_points
— Methodget_points(boundary_enricher::BoundaryEnricher{P}) -> P
Returns the point set associated with boundary_enricher
.
DelaunayTriangulation.get_points
— Methodget_points(tri::Triangulation) -> Points
Return the points of the triangulation. Note that this may include points not yet in tri
.
DelaunayTriangulation.get_polygon
— Methodget_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
— Functionget_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
: TheVoronoiTessellation
.i
: The index of the polygon.bounding_box=nothing
: The bounding box to clip the polygon to. Ifnothing
, then the polygon is not clipped. If the polygon is unbounded, thenbounding_box
must be provided.
Outputs
coords
: The coordinates of the polygon. This is a circular vector.
DelaunayTriangulation.get_polygon_hierarchy
— Methodget_polygon_hierarchy(boundary_enricher::BoundaryEnricher{P,B,C,I}) -> PolygonHierarchy{I}
Returns the polygon hierarchy associated with boundary_enricher
.
DelaunayTriangulation.get_polygon_hierarchy
— Methodget_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
— Methodget_polygon_orientation(hierarchy::PolygonHierarchy, index) -> Bool
Returns the polygon orientation of the index
th polygon in hierarchy
.
DelaunayTriangulation.get_polygon_orientations
— Methodget_polygon_orientations(hierarchy::PolygonHierarchy) -> BitVector
Returns the polygon orientations of hierarchy
.
DelaunayTriangulation.get_polygon_point
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_queue(boundary_enricher::BoundaryEnricher{P,B,C,I}) -> Queue{I}
Returns the queue associated with boundary_enricher
.
DelaunayTriangulation.get_radius_edge_ratio
— Methodget_radius_edge_ratio(stats::TriangulationStatistics, T)
Returns the radiusedgeratio field from the individual triangle statistics for the triangle T
in the TriangulationStatistics
stats
.
DelaunayTriangulation.get_reorder_cache
— Methodget_reorder_cache(hierarchy::PolygonHierarchy) -> Vector{PolygonTree{I}}
Returns the reorder cache of hierarchy
.
DelaunayTriangulation.get_representative_point_coordinates
— Methodget_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
— Methodget_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
— Methodget_right(node::BalancedBSTNode) -> Union{Nothing, BalancedBSTNode}
Returns the right child of node
. If the node
is nothing
, returns nothing
.
DelaunayTriangulation.get_right_boundary_node
— Methodget_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
: TheTriangulation
.k
: The boundary vertex.ghost_vertex
: The ghost vertex associated with the boundary section thatk
is on.
Outputs
r
: The vertex right ofk
on the boundary.
DelaunayTriangulation.get_root
— Methodget_root(tree::BalancedBST{K}) -> Union{Nothing,BalancedBSTNode{K}}
Returns the root of tree
. If tree
is empty, returns nothing
.
DelaunayTriangulation.get_root
— Methodget_root(tree::RTree) -> Union{Branch,Leaf{Branch}}
Returns the root of tree
.
DelaunayTriangulation.get_section_index
— Functionget_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
— Methodget_section_index(tri::Triangulation, ℓ) -> Integer
Returns the section index corresponding to the ghost vertex ℓ
in tri
.
DelaunayTriangulation.get_segment
— Methodget_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
— Methodget_segments(boundary_enricher::BoundaryEnricher{P,B,C,I,BM,S}) -> S
Returns the segments associated with boundary_enricher
.
DelaunayTriangulation.get_shared_vertex
— Methodget_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
— Methodget_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
— Methodget_size_limit(cache::NodeCache) -> Int
Returns the size limit of cache
.
DelaunayTriangulation.get_size_limit
— Methodget_size_limit(tree::RTree) -> Int
Returns the size limit of tree
.
DelaunayTriangulation.get_skeleton
— Methodget_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
— Functionget_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
— Methodget_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
— Methodget_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
— Methodget_smallest_angle(stats::TriangulationStatistics)
Returns the smallest_angle field from the TriangulationStatistics
stats
.
DelaunayTriangulation.get_smallest_area
— Methodget_smallest_area(stats::TriangulationStatistics)
Returns the smallest_area field from the TriangulationStatistics
stats
.
DelaunayTriangulation.get_smallest_radius_edge_ratio
— Methodget_smallest_radius_edge_ratio(stats::TriangulationStatistics)
Returns the smallestradiusedge_ratio field from the TriangulationStatistics
stats
.
DelaunayTriangulation.get_spatial_tree
— Methodget_spatial_tree(boundary_enricher::BoundaryEnricher{P,B,C,I}) -> RTree
Returns the spatial tree associated with boundary_enricher
.
DelaunayTriangulation.get_state
— Methodget_state(state::RTreeIntersectionIteratorState) -> DiametralBoundingBox
Returns the current element in state
.
DelaunayTriangulation.get_steepest_descent_direction
— Methodget_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
— Methodget_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
: TheTriangulation
to split a triangle of.args::RefinementArguments
: TheRefinementArguments
for the refinement.T
: The triangle to split.
Output
precision_flag
: ACertificate
which isCert.PrecisionFailure
if the Steiner point could not be computed due to precision issues, andCert.None
otherwise.c
: The Steiner point. Ifis_precision_failure(precision_flag)
, then this is just an arbitrary point ofT
to ensure type stability.
DelaunayTriangulation.get_surrounding_polygon
— Methodget_surrounding_polygon(cache::TriangulationCache) -> Vector{Vertex}
Returns the polygon surrounding the triangulation stored in cache
.
DelaunayTriangulation.get_surrounding_polygon
— Methodget_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, meaningS[begin] ≠ S[end]
. In caseu
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
— Methodget_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
— Methodget_tr_corner(r::BoundingBox) -> NTuple{2,Float64}
Returns the top-right corner of r
.
DelaunayTriangulation.get_tree
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_triangulation(cache::TriangulationCache) -> Triangulation
Returns the Triangulation
stored in cache
.
DelaunayTriangulation.get_triangulation
— Methodget_triangulation(vorn::VoronoiTessellation) -> Triangulation
Gets the underlying triangulation of the Voronoi tessellation vorn
.
DelaunayTriangulation.get_triangulation_2
— Methodget_triangulation_2(cache::TriangulationCache) -> Triangulation
Returns the second Triangulation
stored in cache
.
DelaunayTriangulation.get_triplet
— Methodget_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
— Methodget_twig_cache(tree::RTree) -> TwigCache
Returns the twig cache of tree
.
DelaunayTriangulation.get_unbounded_polygon_coordinates
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_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
— Methodget_vertices(graph::Graph) -> Set{Vertex}
Returns the set of vertices in graph
.
DelaunayTriangulation.get_vertices
— Methodget_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
— Methodget_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
— Methodget_weight(tri::Triangulation, i) -> Number
Gets the i
th weight from tri
.
DelaunayTriangulation.get_weighted_nearest_neighbour
— Functionget_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
— Methodget_weights(tri::Triangulation) -> Weights
Return the weights of the triangulation. These are the weights of the vertices of the triangulation.
DelaunayTriangulation.geti
— Methodgeti(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
— Methodgetj(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
— Methodgetk(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
— Methodgetn(c::RepresentativeCoordinates) -> Integer
Returns the number of points represented by c
.
DelaunayTriangulation.getpoint
— Functiongetpoint(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
— Methodgetx(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
— Methodgetx(c::Cell) -> Number
Returns the x-coordinate of c
.
DelaunayTriangulation.getx
— Methodgetx(c::RepresentativeCoordinates) -> Number
Returns the x-coordinate of c
.
DelaunayTriangulation.getxy
— Methodgetxy(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
— Methodgety(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
— Methodgety(c::Cell) -> Number
Returns the y-coordinate of c
.
DelaunayTriangulation.gety
— Methodgety(c::RepresentativeCoordinates) -> Number
Returns the y-coordinate of c
.
DelaunayTriangulation.grow_polygon_outside_of_box
— Methodgrow_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
: TheVoronoiTessellation
.i
: The index of the polygon. The polygon must be unbounded.bounding_box
: The bounding box to clip the polygon to. See alsopolygon_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
— Methodhas_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
— Methodhas_boundary_nodes(tri::Triangulation) -> Bool
Returns true
if tri
has boundary nodes, and false
otherwise.
DelaunayTriangulation.has_children
— Methodhas_children(node::AbstractNode) -> Bool
Returns true
if node
has children.
DelaunayTriangulation.has_children
— Methodhas_children(queue::MaxPriorityQueue, k) -> Bool
Returns true
if the element at index k
has children in the queue
.
DelaunayTriangulation.has_children
— Methodhas_children(tree::PolygonTree) -> Bool
Returns true
if tree
has children, and false
otherwise.
DelaunayTriangulation.has_ghost_triangles
— Methodhas_ghost_triangles(tri::Triangulation) -> Bool
Returns true
if tri
has ghost triangles, and false
otherwise.
DelaunayTriangulation.has_ghost_vertices
— Methodhas_ghost_vertices(G::Graph) -> Bool
Returns true
if G
has ghost vertices, and false
otherwise.
DelaunayTriangulation.has_ghost_vertices
— Methodhas_ghost_vertices(tri::Triangulation) -> Bool
Returns true
if tri
has ghost vertices, and false
otherwise.
DelaunayTriangulation.has_left
— Methodhas_left(node::BalancedBSTNode) -> Bool
Returns true
if node
has a left child, false
otherwise.
DelaunayTriangulation.has_lookup_table
— Methodhas_lookup_table(c::AbstractParametricCurve) -> Bool
Returns true
if c
has a lookup table, and false
otherwise.
DelaunayTriangulation.has_max_angle_constraint
— Methodhas_max_angle_constraint(constraints::RefinementConstraints) -> Bool
Return true
if constraints
has a maximum angle constraint, false
otherwise.
DelaunayTriangulation.has_multiple_curves
— Functionhas_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
— Methodhas_multiple_curves(tri::Triangulation) -> Bool
Returns true
if tri
has multiple boundary curves, and false
otherwise.
DelaunayTriangulation.has_multiple_intersections
— Methodhas_multiple_intersections(cert::Certificate) -> Bool
Returns true
if cert
is Multiple
, and false
otherwise. Synonymous with is_multiple
.
DelaunayTriangulation.has_multiple_sections
— Functionhas_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
— Methodhas_multiple_sections(tri::Triangulation) -> Bool
Returns true
if tri
has multiple boundary sections, and false
otherwise.
DelaunayTriangulation.has_no_intersections
— Methodhas_no_intersections(cert::Certificate) -> Bool
Returns true
if cert
is None
, and false
otherwise. Synonymous with is_none
.
DelaunayTriangulation.has_one_intersection
— Methodhas_one_intersection(cert::Certificate) -> Bool
Returns true
if cert
is Single
, and false
otherwise. Synonymous with is_single
.
DelaunayTriangulation.has_parent
— Methodhas_parent(node::AbstractNode) -> Bool
Returns true
if node
has a parent.
DelaunayTriangulation.has_parent
— Methodhas_parent(node::BalancedBSTNode) -> Bool
Returns true
if node
has a parent, false
otherwise.
DelaunayTriangulation.has_parent
— Methodhas_parent(tree::PolygonTree) -> Bool
Returns true
if tree
has a parent, and false
otherwise.
DelaunayTriangulation.has_right
— Methodhas_right(node::BalancedBSTNode) -> Bool
Returns true
if node
has a right child, false
otherwise.
DelaunayTriangulation.has_root
— Methodhas_root(tree::BalancedBST{K}) -> Bool
Returns true
if tree
has a root, false
otherwise.
DelaunayTriangulation.has_segment_changes
— Methodhas_triangle_changes(events::InsertionEventHistory) -> Bool
Returns true
if there are any changes to the segments in events
, and false
otherwise.
DelaunayTriangulation.has_segments
— Methodhas_segments(boundary_enricher::BoundaryEnricher -> Bool
Returns true
if boundary_enricher
has interior segments, and false
otherwise.
DelaunayTriangulation.has_segments
— Methodhas_segments(queue::RefinementQueue) -> Bool
Return true
if queue
has any segments, false
otherwise.
DelaunayTriangulation.has_triangles
— Methodhas_triangles(queue::RefinementQueue) -> Bool
Return true
if queue
has any triangles, false
otherwise.
DelaunayTriangulation.has_vertex
— Methodhas_vertex(G::Graph, u) -> Bool
Returns true
if u
is a vertex in G
, and false
otherwise.
DelaunayTriangulation.has_vertex
— Methodhas_vertex(tri::Triangulation, u) -> Bool
Returns true
if u
is a vertex in tri
, and false
otherwise.
DelaunayTriangulation.hchildren
— Methodhchildren(k) -> Tuple{Int, Int}
Returns the indices of the children of the element at index k
in a heap.
DelaunayTriangulation.hleft
— Methodhleft(k) -> Int
Returns the index of the left child of the element at index k
in a heap.
DelaunayTriangulation.horizontal_inflection_points
— Methodhorizontal_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 oft
-values to use for seeding Newton's method. In particular, Newton's method is run for each initial value inLinRange(0, 1, steps)
.iters=50
: The number of iterations to run Newton's method for.tol=1e-5
: The tolerance to use foruniquetol
. Also used for deciding whether a root is a valid root, i.e. ifabs(x''(t)) > tol
for a found roott
, thent
is not a valid root and is rejected.
Output
t
: All inflection points, given in sorted order.
DelaunayTriangulation.horizontal_turning_points
— Methodhorizontal_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 oft
-values to use for seeding Newton's method. In particular, Newton's method is run for each initial value inLinRange(0, 1, steps)
.iters=50
: The number of iterations to run Newton's method for.tol=1e-5
: The tolerance to use foruniquetol
. Also used for deciding whether a root is a valid root, i.e. ifabs(x'(t)) > tol
for a found roott
, thent
is not a valid root and is rejected.
Output
t
: All turning points, given in sorted order.
DelaunayTriangulation.hparent
— Methodhparent(k) -> Int
Returns the index of the parent of the element at index k
in a heap.
DelaunayTriangulation.hright
— Methodhright(k) -> Int
Returns the index of the right child of the element at index k
in a heap.
DelaunayTriangulation.hspan
— Methodhspan(r::BoundingBox) -> Float64
Returns the horizontal span of r
, i.e. length(r.x)
.
DelaunayTriangulation.incircle_predicate
— Methodincircle_predicate(a, b, c, p) -> Integer
Returns ExactPredicates.incircle(a, b, c, p)
, in particular we return:
1
: Ifp
is inside the circle defined by(a, b, c)
.0
: Ifp
is on the circle defined by(a, b, c)
.-1
: Ifp
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!
— Methodincrease_depth!(tree::PolygonTree)
Increases the height of tree
and all of its children by 1
.
DelaunayTriangulation.increment_num_elements!
— Methodincrement_num_elements!(tree::RTree)
Increments the number of elements in tree
by 1.
DelaunayTriangulation.inflection_points
— Methodinflection_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 oft
-values to use for seeding Newton's method. In particular, Newton's method is run for each initial value inLinRange(0, 1, steps)
.iters=50
: The number of iterations to run Newton's method for.tol=1e-5
: The tolerance to use foruniquetol
. Also used for deciding whether a root is a valid root, i.e. ifabs(κ(t)) > tol
for a found roott
, thent
is not a valid root and is rejected.
DelaunayTriangulation.initial
— Methodinitial(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!
— Methodinitialise_bowyer_watson!(tri::Triangulation, insertion_order) -> Triangulation
Initialises the Bowyer-Watson algorithm.
Arguments
tri
: The triangulation.insertion_order
: The insertion order of the points. Seeget_insertion_order
.
Output
tri
is updated in place to contain the initial triangle from which the Bowyer-Watson algorithm starts.
DelaunayTriangulation.initialise_clipping_arrays
— Methodinitialise_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
: TheVoronoiTessellation
.
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
— Methodinitialise_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
: TheTriangulation
.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. Ifstore_history
, then this should be aPointLocationHistory
object.ghost_vertex
: The ghost vertex corresponding to the boundary thatk
resides on.concavity_protection
: Whether to use concavity protection. Seeconcavity_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, returningV
.V
: Either a triangle that can returned ifreturn_flag = true
, or some triangle that is used for type stability for this return value.p
: The point corresponding to the vertexk
, or it may beq
if the algorithm is going to be restarted orreturn_flag = true
.i
: The first vertex of the triangle adjoiningk
to start from, ork
if the algorithm is going to be restarted orreturn_flag = true
.j
: The second vertex of the triangle adjoiningk
to start from, ork
if the algorithm is going to be restarted orreturn_flag = true
.pᵢ
: The point corresponding to the vertexi
, or it may beq
if the algorithm is going to be restarted orreturn_flag = true
.pⱼ
: The point corresponding to the vertexj
, or it may beq
if the algorithm is going to be restarted orreturn_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 thatq
is collinear with one of the boundary edges, then we usesearch_down_adjacent_boundary_edges
to find where to start, noting that we can return immediately ifq
is found to be on an adjacent boundary edge. Otherwise,exterior_jump_and_march
can then be used to find the ghost triangle containingq
; ifconcavity_protection = true
, thenconcavity_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 usingcheck_for_intersections_with_interior_edges_adjacent_to_boundary_vertex
, returning early ifq
is found to be inside one of the neighbouring triangles. If the linepq
, wherep = 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 useexterior_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
— Methodinitialise_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
: TheTriangulation
.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. Ifstore_history
, then this should be aPointLocationHistory
object.rng
: The random number generator to use.
Outputs
restart_flag
: Whether the algorithm needs to be restarted.p
: The point corresponding to the vertexk
.i
: The first vertex of the triangle adjoiningk
to start from.j
: The second vertex of the triangle adjoiningk
to start from.pᵢ
: The point corresponding to the vertexi
.pⱼ
: The point corresponding to the vertexj
.
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
— Methodinitialise_voronoi_tessellation(tri::Triangulation) -> VoronoiTessellation
Initialise a VoronoiTessellation
from the triangulation tri
.
Arguments
tri
: TheTriangulation
.
Output
vorn
: TheVoronoiTessellation
. 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
— Methodinorder(tree::BalancedBST{K}) -> Vector{K}
Returns the inorder traversal of tree
.
DelaunayTriangulation.insert_boundary_node!
— Methodinsert_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!
— Methodinsert_boundary_node!(tri::Triangulation, pos, node)
Inserts a boundary node into tri
at the specified position.
Arguments
tri::Triangulation
: TheTriangulation
.pos
: The position to insert the node at, given as aTuple
so thatinsert_boundary_node!(tri, pos, node)
is the same asinsert!(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!
— Methodinsert_cell!(queue::CellQueue, cell::Cell)
Inserts a cell
into the queue
.
DelaunayTriangulation.insert_detached!
— Methodinsert_detached!(tree::RTree, detached)
Given the detached
nodes from collapse_after_deletion!
, inserts them back into tree
.
DelaunayTriangulation.insert_node!
— Methodinsert_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
— Methodinteger_type(tri::Triangulation) -> DataType
Returns the type used for representing vertices in tri
.
DelaunayTriangulation.integer_type
— Methodinteger_type(vorn::VoronoiTessellation) -> DataType
Type used for representing indices in the Voronoi tessellation.
DelaunayTriangulation.intersection_of_edge_and_bisector_ray
— Methodintersection_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
: ACertificate
indicating the position ofc
relative to the line through(a, b)
.p
: The intersection point (which is the midpoint) ifc
intersects the edge,(NaN, NaN)
otherwise.
DelaunayTriangulation.intersection_of_ray_with_bounding_box
— Methodintersection_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
— Methodis_above(cert::Certificate) -> Bool
Returns true
if cert
is Above
, and false
otherwise.
DelaunayTriangulation.is_acute
— Methodis_acute(cert::Certificate) -> Bool
Returns true
if cert
is Acute
, and false
otherwise.
DelaunayTriangulation.is_below
— Methodis_below(cert::Certificate) -> Bool
Returns true
if cert
is Below
, and false
otherwise.
DelaunayTriangulation.is_boundary_edge
— Methodis_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
— Methodis_boundary_node(tri::Triangulation, i) -> (Bool, Vertex)
Tests if the vertex i
is a boundary node of tri
.
Arguments
tri::Triangulation
: TheTriangulation
.i
: The vertex to test.
Outputs
flag
:true
ifi
is a boundary node, andfalse
otherwise.g
: Either the ghost vertex corresponding with the section thati
lives on ifflag
is true, or 0 otherwise.
DelaunayTriangulation.is_boundary_triangle
— Methodis_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
— Methodis_circular(A) -> Bool
Tests if A
is circular, meaning that A[begin] == A[end]
.
DelaunayTriangulation.is_closer
— Methodis_closer(cert::Certificate) -> Bool
Returns true
if cert
is Closer
, and false
otherwise.
DelaunayTriangulation.is_collinear
— Methodis_collinear(cert::Certificate) -> Bool
Returns true
if cert
is Collinear
, and false
otherwise.
DelaunayTriangulation.is_constrained
— Methodis_constrained(tri::Triangulation) -> Bool
Returns true
if tri
has constrained edges (segments), and false
otherwise.
DelaunayTriangulation.is_curve_bounded
— Functionis_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
— Methodis_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
— Methodis_degenerate(cert::Certificate) -> Bool
Returns true
if cert
is Degenerate
, and false
otherwise.
DelaunayTriangulation.is_disjoint
— Methodis_disjoint(tri::Triangulation) -> Bool
Returns true
if tri
has disjoint exterior boundary curves, and false
otherwise.
DelaunayTriangulation.is_encroached
— Methodis_encroached(tri::Triangulation, args::RefinementArguments, edge) -> Bool
Determines if a segment edge
of tri
is encroached upon.
See also encroaches_upon
.
DelaunayTriangulation.is_encroachmentfailure
— Methodis_encroachmentfailure(cert::Certificate) -> Bool
Returns true
if cert
is EncroachmentFailure
, and false
otherwise.
DelaunayTriangulation.is_equidistant
— Methodis_equidistant(cert::Certificate) -> Bool
Returns true
if cert
is Equidistant
, and false
otherwise.
DelaunayTriangulation.is_exterior_boundary_node
— Methodis_exterior_boundary_node(tri::Triangulation, i) -> Bool
Tests if the vertex i
is an exterior boundary node of tri
.
DelaunayTriangulation.is_exterior_curve
— Methodis_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
— Methodis_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
— Methodis_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
— Methodis_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
— Methodis_failedinsertion(cert::Certificate) -> Bool
Returns true
if cert
is FailedInsertion
, and false
otherwise.
DelaunayTriangulation.is_finite_segment
— Methodis_finite_segment(u, v) -> Bool
Returns true
if the segment (u, v)
is finite, and false
otherwise.
DelaunayTriangulation.is_first_ghost_vertex
— Methodis_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 incell
.
Outputs
flag
:true
ifi
is the first ghost vertex incell
, andfalse
otherwise.
DelaunayTriangulation.is_free
— Methodis_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
— Methodis_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
— Methodis_full(cache::NodeCache) -> Bool
Returns true
if cache
is full, i.e. if length(cache) ≥ get_size_limit(cache)
.
DelaunayTriangulation.is_further
— Methodis_further(cert::Certificate) -> Bool
Returns true
if cert
is Further
, and false
otherwise.
DelaunayTriangulation.is_ghost_edge
— Methodis_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
— Methodis_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
— Methodis_ghost_vertex(i) -> Bool
Tests if i
is a ghost vertex, meaning i ≤ -1
.
DelaunayTriangulation.is_illegal
— Methodis_illegal(cert::Certificate) -> Bool
Returns true
if cert
is Illegal
, and false
otherwise.
DelaunayTriangulation.is_in_tree
— Methodis_in_tree(hierarchy::PolygonHierarchy, points, boundary_nodes, tree::PolygonTree, p) -> Bool
Tests if the point p
is inside tree
.
Arguments
hierarchy::PolygonHierarchy
: ThePolygonHierarchy
containingtree
.points
: The point set.boundary_nodes
: The boundary nodes.tree::PolygonTree
: ThePolygonTree
to testp
against.p
: The point to test.
Output
true
ifp
is insidetree
, andfalse
otherwise.
DelaunayTriangulation.is_inside
— Methodis_inside(cert::Certificate) -> Bool
Returns true
if cert
is Inside
, and false
otherwise.
DelaunayTriangulation.is_interior_curve
— Methodis_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
— Methodis_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
— Methodis_interpolating(c::AbstractParametricCurve) -> Bool
Returns true
if c
goes through all its control points, and false
otherwise.
DelaunayTriangulation.is_invisible
— Methodis_invisible(cert::Certificate) -> Bool
Returns true
if cert
is Invisible
, and false
otherwise.
DelaunayTriangulation.is_last_ghost_vertex
— Methodis_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 incell
.
Outputs
flag
:true
ifi
is the last ghost vertex incell
, andfalse
otherwise.
DelaunayTriangulation.is_left
— Methodis_left(cert::Certificate) -> Bool
Returns true
if cert
is Left
, and false
otherwise.
DelaunayTriangulation.is_legal
— Functionis_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
— Methodis_legal(cert::Certificate) -> Bool
Returns true
if cert
is Legal
, and false
otherwise.
DelaunayTriangulation.is_midpoint_split
— Methodis_midpoint_split(args::RefinementArguments, u) -> Bool
Returns true
if u
is a midpoint of an encroached segment, and false
otherwise.
DelaunayTriangulation.is_multiple
— Methodis_multiple(cert::Certificate) -> Bool
Returns true
if cert
is Multiple
, and false
otherwise.
DelaunayTriangulation.is_negatively_oriented
— Methodis_negatively_oriented(cert::Certificate) -> Bool
Returns true
if cert
is NegativelyOriented
, and false
otherwise.
DelaunayTriangulation.is_negativelyoriented
— Methodis_negativelyoriented(cert::Certificate) -> Bool
Returns true
if cert
is NegativelyOriented
, and false
otherwise.
DelaunayTriangulation.is_none
— Methodis_none(cert::Certificate) -> Bool
Returns true
if cert
is None
, and false
otherwise.
DelaunayTriangulation.is_obtuse
— Methodis_obtuse(cert::Certificate) -> Bool
Returns true
if cert
is Obtuse
, and false
otherwise.
DelaunayTriangulation.is_offcenter_split
— Methodis_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
— Methodis_on(cert::Certificate) -> Bool
Returns true
if cert
is On
, and false
otherwise.
DelaunayTriangulation.is_outside
— Methodis_outside(cert::Certificate) -> Bool
Returns true
if cert
is Outside
, and false
otherwise.
DelaunayTriangulation.is_piecewise_linear
— Methodis_piecewise_linear(c::AbstractParametricCurve) -> Bool
Returns true
if c
is PiecewiseLinear
, and false
otherwise.
DelaunayTriangulation.is_piecewise_linear
— Methodis_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
— Methodis_positively_oriented(cert::Certificate) -> Bool
Returns true
if cert
is PositivelyOriented
, and false
otherwise.
DelaunayTriangulation.is_positively_oriented
— Methodis_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
— Methodis_positivelyoriented(cert::Certificate) -> Bool
Returns true
if cert
is PositivelyOriented
, and false
otherwise.
DelaunayTriangulation.is_precisionfailure
— Methodis_precisionfailure(cert::Certificate) -> Bool
Returns true
if cert
is PrecisionFailure
, and false
otherwise.
DelaunayTriangulation.is_ray_going_in
— Methodis_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
— Methodis_ray_going_out(u, v) -> Bool
Returns true
if the ray (u, v)
is going out to infinity, and false
otherwise.
DelaunayTriangulation.is_right
— Methodis_right(cert::Certificate) -> Bool
Returns true
if cert
is Right
, and false
otherwise.
DelaunayTriangulation.is_root
— Methodis_root(k) -> Bool
Returns true
if the element at index k
is the root of a heap.
DelaunayTriangulation.is_root
— Methodis_root(node::AbstractNode, tree::RTree) -> Bool
Returns true
if node
is the root of tree
.
DelaunayTriangulation.is_segment
— Methodis_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
— Methodis_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
— Methodis_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
— Methodis_single(cert::Certificate) -> Bool
Returns true
if cert
is Single
, and false
otherwise.
DelaunayTriangulation.is_small_angle_complex_apex
— Methodis_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
— Methodis_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, andfalse
otherwise.apex
: If the edge is a member of a small angle complex, thenapex
is the apex of the complex. Otherwise,apex
is0
.complex_id
: If the edge is a member of a small angle complex, thencomplex_id
is the index of the complex in the list of complexes associated withapex
. Otherwise,complex_id
is0
.member_id
: If the edge is a member of a small angle complex, thenmember_id
is the index of the member in the list of members associated withcomplex_id
. Otherwise,member_id
is0
.
DelaunayTriangulation.is_submerged
— Functionis_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
— Methodis_subsegment(args::RefinementArguments, u, v) -> Bool
Returns true
if the edge (u, v)
is a subsegment, and false
otherwise.
DelaunayTriangulation.is_successfulinsertion
— Methodis_successfulinsertion(cert::Certificate) -> Bool
Returns true
if cert
is SuccessfulInsertion
, and false
otherwise.
DelaunayTriangulation.is_touching
— Methodis_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
— Methodis_touching(cert::Certificate) -> Bool
Returns true
if cert
is Touching
, and false
otherwise.
DelaunayTriangulation.is_triangle_nestled
— Methodis_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
: TheTriangulation
.T
: The triangle.idx
: The index of the smallest edge of the triangle, so that1
meansuv
is the smallest edge,2
meansvw
is the smallest edge, and3
meanswu
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
— Methodis_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
: TheTriangulation
.args
: TheRefinementArguments
.u, v, w
: The vertices of the triangle.smallest_idx
: The index of the smallest edge of the triangle, so that1
meansuv
is the smallest edge,2
meansvw
is the smallest edge, and3
meanswu
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
— Functionis_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
— Methodis_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
: TheTriangulation
.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
: Whetherjᵢ
is closer to the line thanjᵢ₋₁
andjᵢ₊₁
.
DelaunayTriangulation.is_visible
— Methodis_visible(cert::Certificate) -> Bool
Returns true
if cert
is Visible
, and false
otherwise.
DelaunayTriangulation.is_weighted
— Methodis_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
— Methodis_weighted(tri::Triangulation) -> Bool
Returns true
if tri
is weighted, and false
otherwise.
DelaunayTriangulation.iterated_neighbourhood
— Methoditerated_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
— Methodjump_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
: TheTriangulation
.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 them
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. Seeselect_initial_point
.store_history=Val(false)
: Whether to store the history of the algorithm.history=nothing
: The history of the algorithm. Ifstore_history
, then this should be aPointLocationHistory
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 withrestart_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. Seeconcavity_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 containingq
, with type given bytriangle_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, andtrue
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, usinginitialise_jump_and_march_boundary_vertex
orinitialise_jump_and_march_interior_vertex
respectively. - From the initial triangle
(i, j, k)
chosen, we then check ifq
is one ofpᵢ
,pⱼ
, andp = pₖ
and then return according tojump_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 putpᵢ
andpⱼ
to the left and right of the linepq
, respectively, this means that we step until the trianglepᵢpⱼq
is no longer positively oriented. So, while the triangle is positively oriented, we step according tojump_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 containingq
and return the triangle.
DelaunayTriangulation.jump_and_march_across_triangle
— Methodjump_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
: TheTriangulation
.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. Ifstore_history
, then this should be aPointLocationHistory
object.maxiters
: The maximum number of iterations to perform before restarting the algorithm withrestart_jump_and_march
.cur_iter
: The current iteration of the algorithm.concavity_protection
: Whether to use concavity protection. Seeconcavity_protection_check
. This is only needed if your triangulation is not convex.arrangement
: ACertificate
defining the orientation of the trianglepᵢ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 vertexoriginal_k
.i
: The first vertex of the triangle adjoiningk
to step from.j
: The second vertex of the triangle adjoiningk
to step from.pᵢ
: The point corresponding to the vertexi
.pⱼ
: The point corresponding to the vertexj
.
Outputs
restart_flag
: Whether the algorithm needs to be restarted.return_flag
: Whether the algorithm can return immediately, returningV
.reinitialise_flag
: Whether the algorithm needs to be reinitialised at a new vertexk
. (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
: ACertificate
defining the orientation of the trianglepᵢpⱼq
with the updated values ofi
andj
.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 vertexi
.pⱼ
: The point corresponding to the vertexj
.i
: The first vertex of the triangle adjoiningk
to step from.j
: The second vertex of the triangle adjoiningk
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. Ifk
is an exterior ghost vertex, then this means that we are stepping outside of the triangulation. Thus, we useexterior_jump_and_march
to find whereq
is, starting from thelast_changed
vertex. Ifconcavity_protection = true
, thenconcavity_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 sinceq
should not be outside of the triangulation, and so we return withreinitialise_flag = true
.Now we consider the case where
k
is not an exterior ghost vertex. We move forward by updating the value ofk
so thatk = get_adjacent(tri, i, j)
, and then consider wherepₖ
is relative to the linepq
.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, settingrestart_flag = true
ifcur_iters ≥ maxiters
.
DelaunayTriangulation.jump_and_march_degenerate_arrangement
— Methodjump_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
: TheTriangulation
.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. Ifstore_history
, then this should be aPointLocationHistory
object.pᵢ
: The point corresponding to the vertexi
.pⱼ
: The point corresponding to the vertexj
.i
: The first vertex of the triangle adjoiningk
to step from.j
: The second vertex of the triangle adjoiningk
to step from.
Outputs
Bool
: Whether the algorithm needs to be restarted.
DelaunayTriangulation.jump_and_march_return_on_vertex
— Methodjump_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
: TheTriangulation
.q
: The query point.k
: The vertexk
that the algorithm started from.p
: The point corresponding to the vertexk
.pᵢ
: The point corresponding to the vertexi
.pⱼ
: The point corresponding to the vertexj
.i
: The first vertex of the triangle adjoiningk
to start from.j
: The second vertex of the triangle adjoiningk
to start from.
Outputs
restart_flag
: Whether the algorithm needs to be restarted.return_flag
: Whether the algorithm can return immediately, returningV
.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
— Methodkeep_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
— Methodkeep_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!
— Functionlegalise_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
: TheTriangulation
.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 ifstore_event_history
is true, in which case it needs to be anInsertionEventHistory
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!
— Functionlegalise_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
: TheTriangulation
.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 ifstore_event_history
is true, in which case it needs to be anInsertionEventHistory
object.
Outputs
There is no output, as tri
is updated in-place.
DelaunayTriangulation.legalise_split_triangle!
— Methodlegalise_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
: TheTriangulation
.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
— Methodlexicographic_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
— Methodliang_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
— Functionline_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
— Functionlocate_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
: TheTriangulation
.e
: The edge going through the triangulation.rotate=Val(true)
: Whether to rotate the edge so that the minimum degree vertex ofe
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 withe
.left_vertices
: The vertices of the intersected triangles that are left ofe
.right_vertices
: The vertices of the intersected triangles that are right ofe
.
DelaunayTriangulation.locate_steiner_point
— Methodlocate_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
: TheTriangulation
to split a triangle of.args::RefinementArguments
: TheRefinementArguments
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
: ACertificate
which isCert.On
if the Steiner point is on the boundary ofV
,Cert.Outside
if the Steiner point is outside ofV
, andCert.Inside
if the Steiner point is inside ofV
.
DelaunayTriangulation.lock_convex_hull!
— Methodlock_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
— Methodmake_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
— Methodmap_curve_index(boundary_enricher::BoundaryEnricher, curve_index) -> Integer
Returns the curve index in boundary_enricher
associated with curve_index
.
DelaunayTriangulation.map_ghost_vertex
— Methodmap_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
— Methodmarked_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
— Methodmaximum_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 minimumx
-coordinate of the box.b
: The maximumx
-coordinate of the box.c
: The minimumy
-coordinate of the box.d
: The maximumy
-coordinate of the box.p
: The point.
Outputs
dist
: The maximum squared distance fromp
to the box.
DelaunayTriangulation.mean_points
— Functionmean_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
— Methodmeet_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!
— Methodmerge_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
— Methodmerge_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
: TheTriangulation
.ghost_vertex_map
: The ghost vertex map to use.
Outputs
all_segments
: The set of edges that merge all the boundary nodes intri
as well as its interior segments into a single collection, with type equal to that ofget_interior_segments(tri)
's.
DelaunayTriangulation.midpoint
— Methodmidpoint(r::BoundingBox) -> NTuple{2,Float64}
Returns the center of r
.
DelaunayTriangulation.midpoint
— Methodmidpoint(I::BoundingInterval) -> Float64
Returns the midpoint of I
.
DelaunayTriangulation.midpoint
— Methodmidpoint(p, q) -> Number or NTuple{2, Number}
Assuming p
and q
are either both numbers are both 2-vectors, computes their average.
DelaunayTriangulation.midpoint
— Methodmidpoint(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
— Methodmin_med_max(a, b, c) -> (Number, Number, Number)
Returns the arguments in sorted order.
DelaunayTriangulation.minimise_enlargement
— Methodminimise_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!
— Methodmove_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 adeepcopy
of the points of the underlying triangulation.vorn
: TheVoronoiTessellation
.generator
: The generator to move.
Outputs
dist
: The distance moved.
DelaunayTriangulation.new_representative_point!
— Methodnew_representative_point!(tri::Triangulation, curve_index)
Creates a new representative point for the curve_index
th curve in tri
.
DelaunayTriangulation.nextindex_circular
— Methodnextindex_circular(C, i) -> Integer
Returns the next index after i
in the circular vector C
.
DelaunayTriangulation.norm
— Methodnorm(p) -> Number
Assuming p
is two-dimensional, computes the Euclidean norm of p
.
DelaunayTriangulation.norm_sqr
— Methodnorm_sqr(p) -> Number
Assuming p
is two-dimensional, computes the square of the Euclidean norm of p
.
DelaunayTriangulation.num_boundary_edges
— Methodnum_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
— Methodnum_boundary_segments(stats::TriangulationStatistics)
Returns the numboundarysegments field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_children
— Methodnum_children(node::AbstractNode) -> Int
Returns the number of children of node
.
DelaunayTriangulation.num_children
— Methodhas_children(tree::PolygonTree) -> Bool
Returns true
if tree
has children, and false
otherwise.
DelaunayTriangulation.num_convex_hull_vertices
— Methodnum_convex_hull_vertices(stats::TriangulationStatistics)
Returns the numconvexhull_vertices field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_curves
— Methodnum_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
— Methodnum_curves(tri::Triangulation) -> Integer
Returns the number of curves in tri
.
DelaunayTriangulation.num_edges
— Methodnum_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
— Methodnum_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
— Methodnum_edges(history::PointLocationHistory) -> Integer
Returns the number of edges in history.collinear_segments
.
DelaunayTriangulation.num_edges
— Methodnum_edges(stats::TriangulationStatistics)
Returns the num_edges field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_edges
— Methodnum_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
— Methodnum_elements(tree::RTree) -> Int
Returns the number of elements in tree
.
DelaunayTriangulation.num_exterior_curves
— Methodnum_exterior_curves(tri::Triangulation) -> Integer
Returns the number of exterior curves in tri
.
DelaunayTriangulation.num_generators
— Methodnum_generators(vor::VoronoiTessellation) -> Integer
Returns the number of generators in the Voronoi tessellation vor
.
DelaunayTriangulation.num_ghost_edges
— Methodnum_ghost_edges(stats::TriangulationStatistics)
Returns the numghostedges field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_ghost_edges
— Methodnum_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
— Methodnum_ghost_triangles(stats::TriangulationStatistics)
Returns the numghosttriangles field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_ghost_triangles
— Methodnum_ghost_triangles(tri::Triangulation) -> Integer
Returns the number of ghost triangles in tri
.
DelaunayTriangulation.num_ghost_vertices
— Methodnum_ghost_vertices(stats::TriangulationStatistics)
Returns the numghostvertices field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_ghost_vertices
— Methodnum_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
— Methodnum_interior_segments(stats::TriangulationStatistics)
Returns the numinteriorsegments field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_neighbours
— Methodnum_neighbours(G::Graph, u) -> Integer
Returns the number of neighbours of u
in G
.
DelaunayTriangulation.num_neighbours
— Methodnum_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
— Functionnum_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
— Methodnum_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
— Methodnum_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
— Methodnum_polygons(vor::VoronoiTessellation) -> Integer
Returns the number of polygons in the Voronoi tessellation vor
.
DelaunayTriangulation.num_sections
— Methodnum_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
— Methodnum_sections(tri::Triangulation) -> Integer
Assuming tri
only has one curve, returns the number of sections in tri
.
DelaunayTriangulation.num_segments
— Methodnum_segments(stats::TriangulationStatistics)
Returns the num_segments field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_solid_edges
— Methodnum_solid_edges(stats::TriangulationStatistics)
Returns the numsolidedges field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_solid_edges
— Methodnum_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
— Methodnum_solid_triangles(stats::TriangulationStatistics)
Returns the numsolidtriangles field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_solid_triangles
— Methodnum_solid_triangles(tri::Triangulation) -> Integer
Returns the number of solid triangles in tri
.
DelaunayTriangulation.num_solid_vertices
— Methodnum_solid_vertices(stats::TriangulationStatistics)
Returns the numsolidvertices field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_solid_vertices
— Methodnum_solid_vertices(tri::Triangulation) -> Integer
Returns the number of solid vertices in tri
.
See also num_ghost_vertices
and num_vertices
.
DelaunayTriangulation.num_triangles
— Methodnum_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
— Methodnum_triangles(stats::TriangulationStatistics)
Returns the num_triangles field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_triangles
— Methodnum_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
— Methodnum_vertices(G::Graph) -> Integer
Returns the number of vertices in G
.
DelaunayTriangulation.num_vertices
— Methodnum_vertices(stats::TriangulationStatistics)
Returns the num_vertices field from the TriangulationStatistics` stats
.
DelaunayTriangulation.num_vertices
— Methodnum_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
— Functionnumber_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
— Methodnumber_type(tri::Triangulation) -> DataType
Returns the type used for representing individual coordinates in tri
.
DelaunayTriangulation.number_type
— Methodnumber_type(vorn::VoronoiTessellation) -> DataType
Type used for representing individual coordinates in the Voronoi tessellation.
DelaunayTriangulation.opposite_angle
— Methodopposite_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
— Methodopposite_signs(x, y) -> Bool
From ExactPredicates.jl, returns true
if x
and y
have opposite signs, and false
otherwise.
DelaunayTriangulation.optimise_edge_order
— Methodoptimise_edge_order(tri::Triangulation, segment) -> Edge
Optimises the orientation of segment
for inserting it into the triangulation.
Arguments
tri::Triangulation
: TheTriangulation
.segment
: The segment to arrange.
Outputs
e
: Ifsegment
is a boundary edge, thene = segment
, Otherwise,e = sort_edge_by_degree(tri, segment)
so thatinitial(e)
has the smaller degree of the two vertices.
DelaunayTriangulation.orient_predicate
— Methodorient_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
— Methodorient_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
— Methodorientation_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 functionx(t)
κ(t; y) = 0
, whereκ(t; y)
is the curvature of the component functiony(t)
κ(t) = 0
, whereκ
is the curvature ofc(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
: TheAbstractParametricCurve
.
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 twot
-values are the same.
Output
markers::Vector{Float64}
: Thet
-values of the orientation markers ofb
. The returned vector is sorted, and also includes the endpoints0
and1
; anyt
-values outside of[0, 1]
are discarded, and multiplicity of anyt
is not considered (so thet
-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!
— Methodoverflow_insert!(node, child, tree) -> Bool
Inserts child
into node
in tree
when node
is full. Returns true
.
DelaunayTriangulation.parallelorder_predicate
— Methodparallelorder_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)
thanp
.0
:p
andq
are equidistant from the line(a, b)
.-1
:p
is closer to the line(a, b)
thanq
.
DelaunayTriangulation.partition_members
— Methodpartition_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
— Functionpoint_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
andq
are the same distance fromℓ
.
DelaunayTriangulation.point_position_on_line_segment
— Functionpoint_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 betweena
andb
.Degenerate
: Eitherp == a
orp == 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
— Methodpoint_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
— Functionpoint_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 ofT
.On
:ℓ
is on the circumcircle ofT
.Inside
:ℓ
is inside the circumcircle ofT
.
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
— Methodpoint_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 ofc
.Right
:p
is to the right ofc
.On
:p
is onc
.
DelaunayTriangulation.point_position_relative_to_curve
— Methodpoint_position_relative_to_curve(enricher::BoundaryEnricher, curve_index, p) -> Certificate
Returns a Certificate
which is
Left
: Ifp
is to the left of thecurve_index
th curve.Right
: Ifp
is to the right of thecurve_index
th curve.On
: Ifp
is on thecurve_index
th curve.
DelaunayTriangulation.point_position_relative_to_curve
— Methodpoint_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 ofL
.Right
:p
is to the right ofL
.On
:p
is onL
.
See also point_position_relative_to_line
.
DelaunayTriangulation.point_position_relative_to_diametral_circle
— Methodpoint_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
— Functionpoint_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
— Functionpoint_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
— Methodpoint_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 witha
andb
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
— Functionpoint_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
— Methodpoint_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 ofT
.On
:ℓ
is on the witness plane ofT
.Below
:ℓ
is below the witness plane ofT
.
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
— Methodpoints_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
— Methodpole_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 isone(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
— Functionpolygon_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
— Functionpolygon_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
: Iftrue
, then the bounding box will also include the polygon vertices. Otherwise, only the generators are included.
Output
xmin
: Given byxmin′ - unbounded_extension_factor * (xmin′ - xmin′)
, wherexmin′
is the original minimumx
-coordinate of the computed bounding box and similarly forxmax′
.xmax
: Given byxmax′ + unbounded_extension_factor * (xmax′ - xmax′)
, wherexmax′
is the original maximumx
-coordinate of the computed bounding box and similarly forxmin′
.ymin
: Given byymin′ - unbounded_extension_factor * (ymin′ - ymin′)
, whereymin′
is the original minimumy
-coordinate of the computed bounding box and similarly forymax′
.ymax
: Given byymax′ + unbounded_extension_factor * (ymax′ - ymax′)
, whereymax′
is the original maximumy
-coordinate of the computed bounding box and similarly forymin′
.
DelaunayTriangulation.polygon_features
— Methodpolygon_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
— Methodpolygon_features(vor::VoronoiTessellation, i) -> (Number, NTuple{2, Number})
Gets the area and centroid of the polygon with index i
in vor
.
DelaunayTriangulation.polygonise
— Methodpolygonise(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 withnew_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!
— Methodpop_child!(node::AbstractNode)
Removes the last child of node
via pop!
.
DelaunayTriangulation.pop_point!
— Functionpop_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!
— Methodpop_point!(tri::Triangulation)
Pops the last point from the points of tri
.
DelaunayTriangulation.popfirst_segment!
— Methodpopfirst_segment!(queue::RefinementQueue) -> Edge
Dequeue the next segment from queue
, returning the segment and its squared length.
DelaunayTriangulation.popfirst_triangle!
— Methodpopfirst_triangle!(queue::RefinementQueue) -> (Triangle, Number)
Dequeue the next triangle from queue
, returning the triangle and its radius-edge ratio.
DelaunayTriangulation.postprocess_triangulate!
— Methodpostprocess_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!
ifdelete_ghosts
istrue
. - Clearing empty features using
clear_empty_features!
ifdelete_empty_features
istrue
. - Recomputing the representative points using
compute_representative_points!
ifrecompute_representative_points
istrue
.
DelaunayTriangulation.postprocess_triangulate_convex!
— Methodpostprocess_triangulate_convex!(tri::Triangulation, S; delete_ghosts, delete_empty_features)
Postprocesses the completed triangulation tri
of the convex polygon S
.
Arguments
tri::Triangulation
: TheTriangulation
.S
: The vertices of the convex polygon, as intriangulate_convex
.
Keyword Arguments
delete_ghosts=false
: Iftrue
, the ghost triangles are deleted after triangulation.delete_empty_features=true
: Iftrue
, 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 toS
. - 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
— Methodprepare_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
: TheVoronoiTessellation
.i
: The vertex.
Outputs
S
: The surrounding polygon ofi
. Seeget_surrounding_polygon
.B
: The buffer for the circumcenters. This is an emptyVector{I}
, whereI = integer_type(tri)
.
DelaunayTriangulation.prepare_initial_edge
— Functionprepare_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
: TheTriangulation
.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 toi
.pⱼ
: The point corresponding toj
.line_cert_i
: TheCertificate
forpᵢ
's position relative to the oriented linepq
.line_cert_j
: TheCertificate
forpⱼ
's position relative to the oriented linepq
.
DelaunayTriangulation.prepare_vertex_linked_list
— Methodprepare_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
: AShuffledPolygonLinkedList
. Inlist
,prev[begin]
,prev[end]
,next[begin]
, andnext[end]
are all0
as areshuffled_indices[begin]
andshuffled_indices[end]
. Moreover,shuffled_indices
will not have been shuffled yet.
DelaunayTriangulation.previndex_circular
— Methodprevindex_circular(C, i) -> Integer
Returns the previous index before i
in the circular vector C
.
DelaunayTriangulation.process_collinear_segments!
— Methodprocess_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!
— Methodprocess_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
: TheVoronoiTessellation
.current_incident_polygon
: The index of the current polygon being processed.left_edge_intersectors
: The intersection points ofleft_edge
with other edges.right_edge_intersectors
: The intersection points ofright_edge
with other edges.current_edge_intersectors
: The intersection points ofcurrent_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 considerleft_edge
andright_edge
individually. - The procedure for each edge is the same, so here we just describe the
left_edge
. If there are any intersectors with theleft_edge
, and neither of(left_edge, current_incident_polygon)
or(reverse_edge(left_edge), current_incident_polygon)
have already been processed (i.e., inprocessed_pairs
), then we enqueue(left_edge, i)
and(left_edge, j)
intopolygon_edge_queue
, wherei
andj
are the vertices ofleft_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
, whereall_indices
are the vertices ofleft_edge
,right_edge
, andcurrent_edge
. If this is true, and if the shared vertex ofcurrent_edge
andleft_edge
is equal tocurrent_incident_polygon
, then we need to add the point generator ofcurrent_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
andright_edge
have been processed as above, we need to then consider all ofleft_edge
,right_edge
, andcurrent_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 thecurrent_edge
. For each edgeuv
in thecurrent_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!
— Methodprocess_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
: TheVoronoiTessellation
.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 fromu
tov
.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 ofe
on the boundary.right_edge
: The edge to the right ofe
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 edgesleft_edge
andright_edge
that neighbour it viaget_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 useprocess_ray_intersection!
andprocess_ray_intersection_with_other_edges!
to process the intersection of the ray with the boundary edges. The functionprocess_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 ofe
,left_edge
, andright_edge
to check for all intersections. - The function is done once each of the polygon edges has been considered.
DelaunayTriangulation.process_ray_intersection!
— Methodprocess_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
: TheVoronoiTessellation
.u
: The index of the siteu
, given as a ghost vertex for the associated ghost triangle.v
: The index of the sitev
.incident_polygon
: The index of the Voronoi polygon of the siteu
that is incident to the ray emanating from the circumcenter of the sitev
.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!
— Methodprocess_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
: TheVoronoiTessellation
.u
: The index of the ghost site.v
: The index of the siteu
is going to.e
: The edge on the boundary being considered.left_edge
: The edge to the left ofe
on the boundary.right_edge
: The edge to the right ofe
on the boundary.r
: The coordinates of the intersection of the ray fromu
tov
with some edge. Ifany(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 fromu
tov
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 fromu
tov
.
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!
— Methodprocess_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!
— Methodprocess_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
: TheVoronoiTessellation
.u
: The index of the siteu
.v
: The index of the sitev
.e
: The edgee
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!
— Methodprotect_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!
— Functionpush_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!
— Methodpush_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!
— Methodpush_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
— Functionrandom_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!
— Methodrefine!(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
: TheTriangulation
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 tonum_solid_vertices
, not the amount returned bynum_points
.seditious_angle=20.0
: The angle at which a triangle is considered seditious, in degrees. Seeis_triangle_seditious
.custom_constraint=(tri, T) -> false
: A custom constraint function that takes aTriangulation
and a triangle, and returnstrue
if the triangle should be refined andfalse
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 ifuse_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 forjump_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!
— Methodrefine_itr!(tri::Triangulation, args::RefinementArguments)
Performs a single iteration of the refinement algorithm.
Arguments
tri::Triangulation
: TheTriangulation
to refine.args::RefinementArguments
: TheRefinementArguments
for the refinement.
Output
The triangulation is refined in-place.
DelaunayTriangulation.remake_triangulation_with_constraints
— Methodremake_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 containingboundary_nodes
in theboundary_nodes
field andsegments
in theinterior_segments
field.
DelaunayTriangulation.reorder_hierarchy!
— Methodreorder_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
: ThePolygonHierarchy
to addnew_tree
to.points
: The point set.boundary_nodes
: The boundary nodes.new_tree::PolygonTree
: ThePolygonTree
to add tohierarchy
.
DelaunayTriangulation.reorder_subtree!
— Methodreorder_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
: ThePolygonHierarchy
to addnew_tree
to.points
: The point set.boundary_nodes
: The boundary nodes.tree::PolygonTree
: ThePolygonTree
to addnew_tree
to.new_tree::PolygonTree
: ThePolygonTree
to add tohierarchy
andtree
.
DelaunayTriangulation.reorient_edge
— Methodreorient_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!
— Methodreplace!(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
— Methodreplace_boundary_triangle_with_ghost_triangle(tri::Triangulation, V) -> Triangle
Given a boundary triangle V
of tri
, returns the adjacent ghost triangle. Note that for triangles in a corner of a domain, like a lattice triangulation, there are two choices of ghost triangle.
DelaunayTriangulation.replace_ghost_triangle_with_boundary_triangle
— Methodreplace_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
— Methodreplace_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 containingghost_vertex_map
in theghost_vertex_map
field andghost_vertex_ranges
in theghost_vertex_ranges
field.
DelaunayTriangulation.replace_next_edge!
— Methodreplace_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!
— Methodreplace_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
— Methodreplace_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!
— Methodreset!(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!
— Methodreset!(c::RepresentativeCoordinates)
Resets the coordinates of c
to zero.
DelaunayTriangulation.reset_representative_points!
— Methodreset_representative_points!(tri::Triangulation)
Resets each representative point of tri
to the origin.
DelaunayTriangulation.restart_jump_and_march
— Methodrestart_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
: TheTriangulation
.q
: The query point.store_history
: Whether to store the history of the algorithm.history
: The history of the algorithm. Ifstore_history
, then this should be aPointLocationHistory
object.rng
: The random number generator to use.maxiters
: The maximum number of iterations to perform before restarting the algorithm withrestart_jump_and_march
.cur_iter
: The current iteration of the algorithm.concavity_protection
: Whether to use concavity protection. Seeconcavity_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 containingq
.
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
— Methodretriangulate(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 simplyget_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 totriangulate
. Other keyword arguments, likesegments
andboundary_nodes
, are automatically passed from the fields oftri
, but may be overridden by passing the corresponding keyword arguments.
DelaunayTriangulation.retriangulate_fan!
— Methodretriangulate_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
— Methodreverse_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!
— Methodrotate_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!
— Methodrotate_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
— Methodrotate_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
— Methodsameside_predicate(a, b, p) -> Integer
Returns ExactPredicates.sameside(p, a, b)
where all three points are collinear, in particular we return:
1
:a
andb
are on the same side ofp
on the line.0
:a == p
orb == p
.-1
:a
andb
are on different sides ofp
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
— Methodsearch_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
: TheTriangulation
.k
: The boundary vertex to start from.q
: The query point.direction_cert
: The direction ofq
relative to the vertexk
along the boundary, defined fromcheck_for_intersections_with_adjacent_boundary_edges
.q_pos_cert
: The position ofq
relative to the vertexk
along the boundary, defined fromcheck_for_intersections_with_adjacent_boundary_edges
.next_vertex
: The next vertex along the boundary in the direction ofq
, defined fromcheck_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. Ifstore_history
, then this should be aPointLocationHistory
object.ghost_vertex=𝒢
: The ghost vertex corresponding to the boundary thatk
resides on.
Outputs
return_flag
: Whether to return, or throw an exception.q_pos_cert
: ACertificate
that isOn
ifq
is on the edge(u, v)
, andOutside
ifq
is outside of the triangulation.u
: Ifis_on(q_pos_cert)
, this is the first vertex of a positively oriented triangle thatq
is on, so thatq
is on the edge(u, v)
. Otherwise,(u, v, w)
is a ghost triangle close toq
.v
: Ifis_on(q_pos_cert)
, this is the second vertex of a positively oriented triangle thatq
is on, so thatq
is on the edge(u, v)
. Otherwise,(u, v, w)
is a ghost triangle close toq
.w
: Ifis_on(q_pos_cert)
, this is the third vertex of a positively oriented triangle thatq
is on, so thatq
is on the edge(u, v)
andw = get_adjacent(tri, u, v)
. Otherwise,(u, v, w)
is a ghost triangle close toq
.
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
— Methodsegment_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
— Methodsegment_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
: TheTriangulation
.e
: The segment.
Output
num_adjoin
: The number of vertices ofe
that adjoin other segments at an acute angle.adjoin_vert
: The vertex ofe
that adjoins another segment at an acute angle ifnum_adjoin == 1
, and∅
otherwise.
DelaunayTriangulation.select_initial_point
— Functionselect_initial_point(tri::Triangulation, q; kwargs...) -> Vertex
Selects the initial point for jump_and_march
to start from.
Arguments
tri::Triangulation
: TheTriangulation
.q
: The query point. Can be either a point or a vertex - if it is a vertex, the corresponding pointget_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 toq
out of those queried.
DelaunayTriangulation.select_initial_triangle_interior_vertex
— Methodselect_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
: TheTriangulation
.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. Ifstore_history
, then this should be aPointLocationHistory
object.rng::AbstractRNG=Random.default_rng()
: The random number generator to use.
Outputs
p
: The point corresponding tok
.i
: The initial vertex of the triangle.j
: The terminal vertex of the triangle.pᵢ
: The point corresponding toi
.pⱼ
: The point corresponding toj
.
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
— Functionselect_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
: TheTriangulation
.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 toi
.pⱼ
: The point corresponding toj
.
DelaunayTriangulation.select_random_vertex
— Methodselect_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
: TheTriangulation
.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
— Methodselect_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
— Methodself_eval(f, args...)
Evaluates f(args...)
.
DelaunayTriangulation.set_bounding_box!
— Methodset_bounding_box!(node::AbstractNode, bounding_box::BoundingBox)
Sets the bounding box of node
to be bounding_box
.
DelaunayTriangulation.set_bounding_box!
— Methodset_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!
— Methodset_child!(parent_node::AbstractNode, child_node, i::Integer)
Sets the i
th child of parent_node
to be child_node
.
DelaunayTriangulation.set_count!
— Methodset_count!(tree::BalancedBST{K}, count::Int32)
Sets the count of tree
to count
.
DelaunayTriangulation.set_count!
— Methodset_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!
— Methodset_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!
— Methodset_height!(tree::PolygonTree, height::Int)
Sets the height of tree
to height
.
DelaunayTriangulation.set_key!
— Methodset_key!(node::BalancedBSTNode{K}, key::K)
Sets the key associated with node
to key
.
DelaunayTriangulation.set_left!
— Methodset_left!(node::BalancedBSTNode, left::Union{Nothing, BalancedBSTNode})
Sets the left child of node
to left
.
DelaunayTriangulation.set_level!
— Methodset_level!(branch::Branch, level::Integer)
Sets the level of branch
to be level
.
DelaunayTriangulation.set_orientation!
— Methodset_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!
— Methodset_parent!(child_node::AbstractNode, parent_node::AbstractNode)
Sets the parent of child_node
to be parent_node
.
DelaunayTriangulation.set_parent!
— Methodset_parent!(node::BalancedBSTNode, parent::Union{Nothing, BalancedBSTNode})
Sets the parent of node
to parent
.
DelaunayTriangulation.set_parent!
— Methodset_parent!(boundary_enricher::BoundaryEnricher, i, j, k)
Sets the parent of the edge (i, j)
in boundary_enricher
to k
.
DelaunayTriangulation.set_parent!
— Methodset_parent!(tree::PolygonTree, parent::PolygonTree)
Sets the parent of tree
to parent
.
DelaunayTriangulation.set_point!
— Functionset_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!
— Methodset_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!
— Methodset_right!(node::BalancedBSTNode, right::Union{Nothing, BalancedBSTNode})
Sets the right child of node
to right
.
DelaunayTriangulation.set_root!
— Methodset_root!(tree::BalancedBST{K}, root::Union{Nothing,BalancedBSTNode{K}})
Sets the root of tree
to root
.
DelaunayTriangulation.set_root!
— Methodset_root!(tree::RTree, node::AbstractNode)
Sets the root of tree
to be node
.
DelaunayTriangulation.set_tree!
— Methodset_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
— Methodsetup_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
: TheTriangulation
.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!
— Methodsort_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
— Methodsort_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!
— Methodsort_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!
— Methodsort_members!(complex::SmallAngleComplex, points)
Sorts the members of complex
in a counter-clockwise order around the apex of complex
.
DelaunayTriangulation.sort_triangle
— Functionsort_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
— Methodsort_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!
— Methodspawn_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!
— Methodspawn_leaf!(tree::RTree, bounding_box::BoundingBox) -> Leaf{Branch}
Returns a new leaf node with bounding box bounding_box
from tree
.
DelaunayTriangulation.spawn_node!
— Methodspawn_node!(cache::NodeCache{Node}) where {Node} -> Node
Returns a node from cache
. If cache
is empty, returns a new node.
DelaunayTriangulation.spawn_node!
— Methodspawn_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!
— Methodsplit!(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!
— Methodsplit_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!
— Functionsplit_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!
— Methodsplit_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!
— Methodsplit_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!
— Methodsplit_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!
— Methodsplit_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!
— Functionsplit_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
: TheTriangulation
.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 ifstore_event_history
is true, in which case it needs to be anInsertionEventHistory
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!
— Functionsplit_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!
— Methodsplit_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!
— Functionsplit_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!
— Methodsplit_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
— Methodsplit_seeds(node::AbstractNode) -> NTuple{2, Int}
Returns the indices of two children in node
used to initiate the split in split!
.
DelaunayTriangulation.split_segment!
— Methodsplit_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
: TheTriangulation
.segments
: The underlying set of segments. This isget_interior_segments(tri)
iftri
is aTriangulation
.segment
: The segment to split.collinear_segments
: The segments that are collinear withsegment
.
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!
— Methodsplit_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!
— Methodsplit_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!
— Methodsplit_triangle!(tri::Triangulation, args::RefinementArguments, T) -> Certificate
Splits a bad triangle T
of tri
to improve its quality.
Arguments
tri::Triangulation
: TheTriangulation
to split a triangle of.args::RefinementArguments
: TheRefinementArguments
for the refinement.T
: The triangle to split.
Output
cert
: ACertificate
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!
— Methodsplit_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
: TheTriangulation
.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
— Methodsquared_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
— Methodsquared_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.
All coordinates are converted into Float64, but the returned area is converted back into the original precision.
DelaunayTriangulation.squared_triangle_area
— Methodsquared_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
— Methodsquared_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
— Methodsquared_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
— Methodsquared_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
— Methodstatistics(tri::Triangulation) -> TriangulationStatistics
Returns a TriangulationStatistics
object containing statistics about the triangulation tri
.
DelaunayTriangulation.swap!
— Methodswap!(queue::MaxPriorityQueue, i, j)
Swaps the elements at indices i
and j
in queue
.
DelaunayTriangulation.swap_permutation!
— Methodswap_permutation!(list::ShuffledPolygonLinkedList, i, j)
Reorders the permutation list.shuffled_indices
of the linked list
, swapping πᵢ
and πⱼ
where πₖ = list.shuffled_indices[k]
.
DelaunayTriangulation.terminal
— Methodterminal(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
— Methodtest_intersection(node::AbstractNode, itr::RTreeIntersectionIterator) -> QueryResult
Tests whether node
intersects with the bounding box in itr
, returning a QueryResult
.
DelaunayTriangulation.test_visibility
— Methodtest_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
: Ifk
is not visible from(i, j)
.Visible
: Ifk
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
— Methodtest_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
: TheTriangulation
.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 towardsattractor
, i.e. ifp
is a point on the edge, thenp .+ shift .* (attractor - p)
is the point used to test visibility rather thanp
itself.
Outputs
cert
: ACertificate
. This will beVisible
ifi
is visible from(u, v)
, andInvisible
otherwise.
DelaunayTriangulation.test_visibility
— Methodtest_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
: TheTriangulation
.1
: The point from which we are testing visibility.i
: The vertex we are testing visibility of.
Outputs
cert
: ACertificate
. This will beVisible
ifi
is visible fromq
, andInvisible
otherwise.
DelaunayTriangulation.thrice_differentiate
— Functionthrice_differentiate(c::AbstractParametricCurve, t) -> NTuple{2, Float64}
Evaluates the third derivative of c
at t
.
DelaunayTriangulation.to_boundary_curves
— Methodto_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!
— Methodtoggle_inf_warn!()
Toggle the warning for infinite circumcenters in the Voronoi tessellation. By default, this warning is enabled.
DelaunayTriangulation.total_variation
— Functiontotal_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
— Methodtriangle_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
— Methodtriangle_area(p, q, r) -> Number
Computes the area of the triangle with coordinates p
, q
, r
.
All coordinates are converted into Float64, but the returned area is converted back into the original precision.
DelaunayTriangulation.triangle_area
— Methodtriangle_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
— Methodtriangle_aspect_ratio(p, q, r) -> Number
Computes the aspect ratio of the triangle with coordinates (p, q, r)
.
DelaunayTriangulation.triangle_aspect_ratio
— Methodtriangle_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
— Methodtriangle_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
— Functiontriangle_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}$.
All coordinates are converted into Float64, but the returned area is converted back into the original precision.
DelaunayTriangulation.triangle_circumcenter
— Methodtriangle_circumcenter(tri::Triangulation, T) -> (Number, Number)
Computes the circumcenter of the triangle T
in the triangulation tri
.
DelaunayTriangulation.triangle_circumradius
— Methodtriangle_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
— Methodtriangle_circumradius(p, q, r) -> Number
Computes the circumradius of the triangle with coordinates (p, q, r)
.
DelaunayTriangulation.triangle_edge_midpoints
— Methodtriangle_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
— Functiontriangle_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
— Methodtriangle_inradius(p, q, r) -> Number
Computes the inradius of the triangle with coordinates (p, q, r)
.
DelaunayTriangulation.triangle_inradius
— Methodtriangle_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
— Methodtriangle_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
— Functiontriangle_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
— Functiontriangle_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
— Functiontriangle_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
— Methodtriangle_perimeter(p, q, r) -> Number
Computes the perimeter of the triangle with coordinates (p, q, r)
.
DelaunayTriangulation.triangle_perimeter
— Methodtriangle_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
— Methodtriangle_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
— Methodtriangle_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
— Functiontriangle_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 ofT
, is in the interior ofT
, then the sink ofT
isT
. - If
T
is a boundary triangle, then the sink ofT
isT
. - If neither 1 or 2, then the sink is defined as the sink of the triangle
V
, whereV
is the triangle adjoining the edge ofT
which intersects the linemc
, wherem
is the centroid ofT
.
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
— Methodtriangle_type(tri::Triangulation) -> DataType
Returns the type used for representing individual triangles in tri
.
DelaunayTriangulation.triangle_type
— Methodtriangle_type(::InsertionEventHistory{T}) where {T} = T
Returns the type of the triangles in events
, T
.
DelaunayTriangulation.triangle_type
— Methodtriangle_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
— Methodtriangle_type(vorn::VoronoiTessellation) -> DataType
Type used for representing individual triangles in the Voronoi tessellation.
DelaunayTriangulation.triangle_vertices
— Methodtriangle_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
— Methodtriangle_type(tri::Triangulation) -> DataType
Returns the type used for representing collections of triangles in tri
.
DelaunayTriangulation.triangulate
— Methodtriangulate(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.
If your points are defined using non-Float64
coordinates, you may run into precision issues that lead to problems with robustness. The consequences of this could be potentially catastrophic, leading to infinite loops for example. If you do encounter such issues, consider converting your coordinates to Float64
.
Keyword Arguments
segments=nothing
: The segments to include in the triangulation. Ifnothing
, 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. Ifnothing
, then no boundary nodes are included, and the convex hull ofpoints
remains as the triangulation. These boundary nodes should match the specification given incheck_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 useAbstractParametricCurve
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 thei
th weight referring to thei
th vertex, or more generally any object that definesget_weight
. The weights should beFloat64
.
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 usingget_insertion_order
.delete_ghosts=false
: Whether to delete the ghost triangles after the triangulation is computed. This is done usingdelete_ghost_triangles!
.delete_empty_features=true
: Whether to delete empty features after the triangulation is computed. This is done usingclear_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 usingenrich_boundary!
.num_sample_rule=default_num_samples
: A function mapping a number of pointsn
to a number of samplesm
to use for sampling the initial points during the point location step of the algorithm withinjump_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 usingcompute_representative_points!
.delete_holes=true
: Whether to delete holes after the triangulation is computed. This is done usingdelete_holes!
.check_arguments=true
: Whether to check the argumentspoints
andboundary_nodes
are valid. This is done usingcheck_args
.polygonise_n=4096
: Number of points to use for polygonising the boundary when considering the poylgon hierarchy for a curve-bounded domain usingpolygonise
. Seetriangulate_curve_bounded
.coarse_n=0
: Number of points to use for initialising a curve-bounded domain. Seetriangulate_curve_bounded
. (A value of0
means the number of points is chosen automatically until the diametral circles of all edges are empty.)conform=false
: Iftrue
, 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 usingenrich_boundary!
.
Outputs
tri::Triangulation
: The triangulation.
DelaunayTriangulation.triangulate_cavity_cdt!
— Methodtriangulate_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
: TheTriangulation
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
: TheTriangulation
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 orsetup_cavity_cdt
.
Outputs
There is no output, but tri
is updated in-place.
DelaunayTriangulation.triangulate_convex!
— Methodtriangulate_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 thatS[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
— Methodtriangulate_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 inS
.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 thatS[begin] ≠ S[end]
.
Keyword Arguments
delete_ghosts=false
: Iftrue
, the ghost triangles are deleted after triangulation.delete_empty_features=true
: Iftrue
, the empty features are deleted after triangulation.rng=Random.default_rng()
: The random number generator used to shuffle the vertices ofS
before triangulation.kwargs...
: Additional keyword arguments passed toTriangulation
.
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
— Methodtriangulate_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 aPolygonHierarchy
, many points are needed. This number of points is defined bypolygonise_n
, and must be a power of 2 (otherwise, the next highest power of 2 is used). Seepolygonise
.coarse_n=0
: This is the number of points to use for initialising a curve-bounded domain viacoarse_discretisation!
. The defaultcoarse_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 (seeenrich_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
— Methodtriangulate_rectangle(a, b, c, d, nx, ny; kwargs...) -> Triangulation
Triangulates the rectangle [a, b] × [c, d]
.
Arguments
a
: The minimumx
-coordinate.b
: The maximumx
-coordinate.c
: The minimumy
-coordinate.d
: The maximumy
-coordinate.nx
: The number of points in thex
-direction.ny
: The number of points in they
-direction.
Keyword Arguments
single_boundary=false
: Iftrue
, 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
: Iftrue
, 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
— Functiontwice_differentiate(c::AbstractParametricCurve, t) -> NTuple{2, Float64}
Evaluates the second derivative of c
at t
.
DelaunayTriangulation.unconstrained_triangulation!
— Methodunconstrained_triangulation!(tri::Triangulation; kwargs...)
Computes the unconstrained Delaunay triangulation of the points in tri
.
Arguments
tri
: The triangulation.
Keyword Arguments
randomise=true
: Iftrue
, then the insertion order is randomised. Otherwise, the insertion order is the same as the order of the points.skip_points=()
: The vertices to skip.num_sample_rule::M=default_num_samples
: The rule to use to determine the number of points to sample. Seedefault_num_samples
for the default.rng::AbstractRNG=Random.default_rng()
: The random number generator to use.insertion_order=get_insertion_order(tri, randomise, skip_points, rng)
: The insertion order of the points. Seeget_insertion_order
.
Outputs
There is no output, but tri
is updated in-place.
DelaunayTriangulation.undo_boundary_segment_changes!
— Methodundo_boundary_segment_changes!(tri::Triangulation, events::InsertionEventHistory)
Undoes any changes to the boundary segments in tri
that were made after an insertion event, as recorded in events
, assuming the inserted vertex is num_points(tri)
.
DelaunayTriangulation.undo_insertion!
— Functionundo_insertion!(tri::Triangulation, events::InsertionEventHistory, pop=Val(true))
Undoes the insertion of the most recent vertex into tri
, assuming that its insertion history has been recorded into events
and the vertex is num_points(tri)
.
If you do not want to delete the latest vertex from the triangulation, set pop
to Val(false)
.
DelaunayTriangulation.undo_segment_changes!
— Methodundo_segment_changes!(tri::Triangulation, events::InsertionEventHistory)
Undoes any changes to the segments in tri
that were made after an insertion event, as recorded in events
.
DelaunayTriangulation.uniquetol
— Methoduniquetol(A::Vector{Float64}; tol=1e-12) -> Vector{Float64}
Returns the unique elements of A
up to tolerance tol
. We say that two values x
and y
are within tolerance if abs(u - v) ≤ M*tol
, where M = maximum(abs.(A))
. It is assumed that A
is sorted - this is NOT checked.
DelaunayTriangulation.unlock_convex_hull!
— Methodunlock_convex_hull!(tri::Triangulation; reconstruct=false)
Unlocks the convex hull of the constrained triangulation tri
so that it is now treated as an unconstrained triangulation, assuming that it was locked using lock_convex_hull!
. If reconstruct = true
, then the convex hull of tri
will be reconstructed from the boundary nodes of tri
. This is useful if, for example, you have split some of the boundary edges during mesh refinement.
DelaunayTriangulation.unoriented_edge_exists
— Methodunoriented_edge_exists(tri::Triangulation, ij) -> Bool
unoriented_edge_exists(tri::Triangulation, i, j) -> Bool
Tests if the unoriented edge (i, j)
is in tri
, returning true
if so and false
otherwise.
DelaunayTriangulation.update_bounding_box!
— Methodupdate_bounding_box!(node, idx, original_bounding_box, tree)
Updates the bounding box of node
to be the union of its children's bounding boxes. If node
has a parent, updates the bounding box of the parent as well if needed.
DelaunayTriangulation.update_bounding_box!
— Methodupdate_bounding_box!(node)
Updates the bounding box of node
to be the union of its children's bounding boxes.
DelaunayTriangulation.update_centroid_after_addition!
— Methodupdate_centroid_after_addition!(tri::Triangulation, curve_index, p)
Updates the centroid of the curve_index
th curve in tri
after the addition of the point p
.
DelaunayTriangulation.update_centroid_after_deletion!
— Methodupdate_centroid_after_deletion!(tri::Triangulation, curve_index, p)
Updates the centroid of the curve_index
th curve in tri
after the deletion of the point p
.
DelaunayTriangulation.update_enlargement
— Methodupdate_enlargement(values::EnlargementValues, child, idx) -> EnlargementValues
Compare the enlargement state in values
with child
and return the updated values
if necessary.
DelaunayTriangulation.update_parent_map!
— Methodupdate_parent_map!(boundary_enricher::BoundaryEnricher, i, j, k)
Replaces the edge (i, j)
in boundary_enricher
with the edges (i, k)
and (k, j)
in the parent map.
DelaunayTriangulation.vertical_inflection_points
— Methodvertical_inflection_points(c::AbstractParametricCurve; steps=200, iters = 50, tol = 1e-5) -> Vector{Float64}
Returns points t
such that y''(t) = 0
and 0 ≤ t ≤ 1
, where y''
is the second derivative of the y
-coordinate of c
. This function uses Newton's method to find the roots of y''
. Note that these are only technically inflection points if y'''(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 vertical inflection points of.
Keyword Arguments
steps=200
: The number oft
-values to use for seeding Newton's method. In particular, Newton's method is run for each initial value inLinRange(0, 1, steps)
.iters=50
: The number of iterations to run Newton's method for.tol=1e-5
: The tolerance to use foruniquetol
. Also used for deciding whether a root is a valid root, i.e. ifabs(y''(t)) > tol
for a found roott
, thent
is not a valid root and is rejected.
Output
t
: All inflection points, given in sorted order.
DelaunayTriangulation.vertical_turning_points
— Methodvertical_turning_points(c::AbstractParametricCurve; steps=200, iters = 50, tol = 1e-5) -> Vector{Float64}
Returns points t
such that y'(t) = 0
and 0 ≤ t ≤ 1
, where y'
is the derivative of the y
-coordinate of c
. This function uses Newton's method to find the roots of y'
.
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 vertical turning points of.
Keyword Arguments
steps=200
: The number oft
-values to use for seeding Newton's method. In particular, Newton's method is run for each initial value inLinRange(0, 1, steps)
.iters=50
: The number of iterations to run Newton's method for.tol=1e-5
: The tolerance to use foruniquetol
. Also used for deciding whether a root is a valid root, i.e. ifabs(y'(t)) > tol
for a found roott
, thent
is not a valid root and is rejected.
Output
t
: All turning points, given in sorted order.
DelaunayTriangulation.violates_custom_constraint
— Methodviolates_custom_constraint(constraints::RefinementConstraints{F}, tri::Triangulation, T) where {F} -> Bool
Return true
if T
violates the custom constraint in constraints
, false
otherwise.
DelaunayTriangulation.voronoi
— Methodvoronoi(tri::Triangulation; clip=false, smooth=false, kwargs...) -> VoronoiTessellation
Computes the Voronoi tessellation dual to a triangulation.
Arguments
tri
: The triangulation.
Keyword Arguments
clip=false
: Iftrue
, then the Voronoi tessellation is clipped to the convex hull of the triangulation. Otherwise, the Voronoi tessellation is unbounded.smooth=false
: Iftrue
, then the Voronoi tessellation is smoothed into a centroidal tessellation. Otherwise, the Voronoi tessellation is not smoothed. Must haveclip=true
ifsmooth=true
.
Output
vorn
: TheVoronoiTessellation
.
DelaunayTriangulation.vspan
— Methodvspan(r::BoundingBox) -> Float64
Returns the vertical span of r
, i.e. length(r.y)
.
DelaunayTriangulation.QueryResult
— ModuleQueryResult
An enum type for representing the result of an intersection query, with instances:
Contains
: The bounding box contains the element.Intersects
: The bounding box intersects the element.Outside
: The bounding box is outside the element.
DelaunayTriangulation.Certificate
— ModuleCertificate
This is an Enum
that defines certificates returned from predicates. The instances, and associated certifiers, are:
Inside
:is_inside
Degenerate
:is_degenerate
Outside
:is_outside
On
:is_on
Left
:is_left
Right
:is_right
PositivelyOriented
:is_positively_oriented
NegativelyOriented
:is_negatively_oriented
Collinear
:is_collinear
None
:is_none
orhas_no_intersections
Single
:is_single
orhas_one_intersection
Multiple
:is_multiple
orhas_multiple_intersections
Touching
:is_touching
Legal
:is_legal
Illegal
:is_illegal
Closer
:is_closer
Further
:is_further
Equidistant
:is_equidistant
Obtuse
:is_obtuse
Acute
:is_acute
SuccessfulInsertion
:is_successful_insertion
FailedInsertion
:is_failed_insertion
PrecisionFailure
:is_precision_failure
EncroachmentFailure
:is_encroachment_failure
Above
:is_above
Below
:is_below
Visible
:is_visible
Invisible
:is_invisible