- Fix issue with clipping Voronoi tessellation dual to a single right-angled triangle. See #207
- Define
reverse
forAbstractParametricCurve
s, making it easier to reverse the orientation of a curve. See #195. - Fixed an issue with
LineSegment
not returning the exact endpoints att=1
, which can be problematic when joining boundary nodes. This has been fixed. See #195. - Introduced
is_linear
to fix issues with boundary enrichment of domains withLineSegment
s. In particular,LineSegment
s are no longer enriched. See #195. orientation_markers
now usesuniquetol
instead ofunique
for the final set of markers (it already did it for the intermediate markers). See #195.- For large
Tuple
s, functions likeeval_fnc_at_het_tuple_two_elements
are problematic and allocate more than their non-type-stable counterparts. To get around this, forTuple
s of lengthN > 32
, the non-type-stable version is used. See #195. - Fixed issue with
use_barriers
when a ghost edge is selected at random during point location. See #196. - Introduced the (currently internal) function
get_positive_curve_indices
for finding curves with positive orientation in aTriangulation
. See #196. is_exterior_curve
,is_interior_curve
,num_exterior_curves
, andis_disjoint
are now defined based onget_positive_curve_indices
rather thanget_exterior_curve_indices
. See #196.- PrecompileTools.jl is now used. See #200.
- Introduced the (currently internal) function
get_positive_curve_indices
for finding curves with positive orientation in aTriangulation
. #196. PointLocationHistory
was not marked as public. This has been fixed. See #198.- Fixed an issue with missing docstrings and duplicate docstrings in the documentation. See #198.
copy
anddeepcopy
are now correctly implemented forPolygonTree
s andPolygonHierarchy
s. See #199- Implemented
copy
anddeepcopy
forTriangulation
andVoronoiTessellation
. See #201. - Fixed a bug with
Triangulation
spolygon_hierarchy
not being correctly aliased with thepolygon_hierarchy
from theBoundaryEnricher
, and similarly for theboundary_edge_map
. See #201. - Implemented
==
forVoronoiTessellation
. See #201.
- Introduced the ability to reconstruct unconstrained triangulations from an existing set of points and triangles using
Triangulation(points, triangles)
. See #192
- Updated to AdaptivePredicates.jl v1.2, now allowing caches to be passed to the predicates involving
incircle
andorient3
. These are only useful when using theAdaptiveKernel()
kernel. Outside of triangulating, these caches are not passed by default, but can be provided. The functionsget_incircle_cache
andget_orient3_cache
can be used for this purpose on a triangulation (without a triangulation, refer to AdaptivePredicate.jl'sincircleadapt_cache
andorient3adapt_cache
). See #185.
- Fix an issue with a weighted triangulation where the lifted points' convex hull was entirely coplanar. See #184
This release finally introduces weighted triangulations and power diagrams, and also allows for users to provide a generic convex polygon to for clipping a Voronoi tessellation instead of only the convex hull.
- Weighted triangulations have now been implemented, as have power diagrams. The weights are also no longer restricted to
Float64
type. See #180. intersection_of_edge_and_bisector_ray
now accepts aproject
keyword argument. See #180.get_weight(w, i)
now returns, wheni
is not an integer, eitheri[3]
if it represents a point in space or0
. See #180.- Define
project_onto_line(p, q, r)
for projecting a pointr
onto the line defined byp
andq
. See #180. - Fixed a bug with clipping Voronoi tessellations in cases where there are no intersections of any Voronoi polygon with the convex hull. See #180.
voronoi
now accepts an optionalclip_polygon
keyword argument, defaulting tonothing
(corresponding to the convex hull), allowing for a convex clip polygon to be used instead of the convex hull. Theclip_polygon
should be aTuple
of the form(points, boundary_nodes)
where theboundary_nodes
give vertices ofpoints
adhering to the usual convention. Note that this could be used as an alternative to looping overget_polygon_coordinates
for clipping to a rectangle. See #180.centroidal_smooth
now acceptsclip_points
andclip_vertices
as keyword arguments, defaulting tonothing
(corresponding to the convex hull), to accommodate the newclip_polygon
keyword argument invoronoi
. See #180.has_multiple_curves
,has_multiple_sections
, andnum_boundary_edges
now have methods forTuple
s of integers. A bug was also fixed withnumber_type
of aTuple
ofTuple
s of coordinates returning theTuple
type instead of the coordinate type. See #180.
- Warnings are now thrown when you try and triangulate point sets not in the plane. The
is_planar
function has been introduced for this. See #178.
- Fixed a bug with curve-bounded refinement with custom edge(s) structs. See #175.
sort_triangle
is now public. See #174.
- Clarified type stability of
triangulate
in docstring, and notes about field access and public API. See #171.
- Fixed issue on nightly with symbols being marked as both public and exported. See #168.
There are a lot of changes in this release, most of them irrelevant for the user. The most important change is the following:
- We now support a choice between fast, exact, and adaptive predicates via
FastKernel()
,ExactKernel()
, andAdaptiveKernel()
, respectively. The default is nowAdaptiveKernel()
. Moreover, triangle areas are now computed using the adaptiveorient
predicate to be more robust. See #165.
Previously, ExactPredicates.jl was used everywhere, which can be slow and not necessary for certain point sets. The FastKernel()
option
has no exact or adaptive arithmetic and so should be used with caution. The documentation discusses these choices in more detail.
To actually configure the choice of predicate, you can e.g. in triangulate
use the predicates
keyword argument and pass one of
DelaunayTriangulation.FastKernel()
, DelaunayTriangulation.ExactKernel()
, or DelaunayTriangulation.AdaptiveKernel()
. If you are computing a predicate manually, then the predicate is instead passed as the first argument.
Some other changes:
- Added
DelauanyTriangulation.validate_triangulation
for validating triangulations. See #131. - Fixed a bug with the currently unused
orient(p, q, r, s)
predicate. See #131. - Added private functions
getz
,_getz
,getxyz
, and_getxyz
. See #131. jump_and_march
has now been renamed tofind_triangle
. For compatibility,jump_and_march
still works and is simply an alias offind_triangle
. See #133.- Mutable structs now use
const
on fields that aren't changed. For compatibility with older versions, this is implemented using a macro that is a no-op where this is not supported. See #140. - We now use the
public
word to define public functions. This is only included on Julia versions v1.11 and above. See #140. - We now test on the pre-release. See #140.
- The module
DelaunayTriangulation
now has a docstring. See #140. - The
.md
files for tutorials and applications in the docs have been properly updated to match their literate counterparts. See #140. - We now use a workflow to enforce changes to
NEWS.md
for any PRs. See #140. - Improved the error message for an incorrect orientation. See #144.
- Added a CONTRIBUTING.md file and issue templates. See #160.
- Added
is_point2
andis_point3
to detect if a given input is a point. This allows vector coordinates to be passed toconvert_boundary_points_to_indices
. See #161. - Removed an allocation from
add_vertex!
. See #163. - Fixed an issue with the user-supplied
rng
not being passed tolock_convex_hull!
.
- Disabled
deepcopy
onPolygonTree
s and made it a no-op. See #129.
Nothing breaking. Main changes:
- Fixes some issue with type instabilities
- Adds
construct_polygon_hierarchy
to the public API list (it was already intended to be there) - All computations are now in the provided precision except for the triangle area and circumcenter which are done in
Float64
. A warning is given when a non-Float64 precision is given. - Closes #118
- Redesigns the
Polygon
struct to have anis_circular
field, avoiding the need forviews
- Completely refactors
validate_triangulation
. Still only lives in the test files though. Maybe one day it can live inside the package itself incase users somehow have a use for it.. - Clean up the runtests.jl file, and make sure that the README/docs are fully tested
- Use Aqua and fix ambiguities
- Remove accidental piracy of
minimum(::Nothing)
- Remove CI spam from method redefinitions
- Fix some issues with doc images and some typos
- Fix #109
- Removed some old function definitions that were no longer needed anymore following the new Makie release.
In addition to the changes below, note that many bugs have been fixed. Feel free to make any issues or PRs if you encounter any problems.
- Triangulation and refinement of curve-bounded domains has now been added.
- The
Triangulation
struct has some more fields. One of these isweights
, although this is not to be used just yet; it is possible to computed weighted Delaunay triangulations of convex polygons, but not for general domains currently. - Where reasonable, default methods for the geometric primitive interfaces have now been added. For example,
getx
now has the default definitiongetx(p) = p[1]
. - You can now use
each_boundary_edge
to iterate over the boundary edges (in no specific order), rather than having to usekeys(get_boundary_edge_map(tri))
as you had to before 1.0. - The documentation has had a complete overhaul.
- The
retriangulate
function has now been added, allowing for the retriangulation of a givenTriangulation
. - The function
dist
can now be used for computing the distance between a point and the triangulation, rather than having to usedistance_to_polygon
. - You can now use
find_polygon
to find what polygon in a provided boundary of aTriangulation
contains a given point. - Mesh refinement now, by default, defaults to the diametral lens definition of encroachment rather than the diametral circle definition. You can toggle this behaviour using the
use_lens
keyword inrefine!
. - Now whenever encroached edges are split during mesh refinement, all free vertices inside that edge's diametral circle will be deleted prior to splitting.
Please note that a lot of these changes that follow are only technically breaking, because I failed to properly specify what the public API was for this package (this has now been corrected in v1.0 and onwards).
- All references to constrained edges are now referred to as segments. For example, the field
constrained_edges
is nowinterior_segments
, andall_constrained_edges
is nowall_segments
. The same goes for the associated getters. - The keyword
edges
intriangulate
is nowsegments
. lock_convex_hull!
will now delete frominterior_segments
field any edges it encounters along the convex hull during locking.add_edge!
is nowadd_segment!
.triangulate_convex
no longer accepts therecompute_centers
keyword.RefinementTargets
is nowRefinementConstraints
.maxiters
is no longer a valid keyword argument ofrefine!
. Instead, you should just passmax_points
appropriately. With this change, the default formax_points
is no longertypemax(Int)
but is insteadmax(1000, num_solid_vertices(tri))^2
.refine!
no longer returnsstatistics(tri)
. It now only returnstri
. If you want the statistics, just usestatistics(tri)
afterwards.refine!
no longer acceptsmax_radius_edge_ratio
. Instead, you must providemin_angle
. (Internally, it is stillmax_radius_edge_ratio
that gets primarily used, butmin_angle
is more interpretable for a user.)lock_convex_hull
is no longer a keyword of argument ofrefine!
- if it has to be locked, it will be automatically.edge_indices
has been removed and is nowedge_vertices
.indices
has been removed and is nowtriangle_vertices
.initialise_edges
andinitialise_triangles
have been removed. Just use the types instead, e.g.initialise_edges(::Type{S})
is now justS()
.is_empty
has been removed. Just useisempty
.compare_unoriented_edge
is nowcompare_unoriented_edges
.initial
andterminal
are no longer exported.edge_vertices
is more appropriate for this.geti
,getj
,getk
are no longer exported.triangle_vertices
is more appropriate for this.each_point
andeach_point_index
are no longer exported. You are encougared to rely oneach_solid_vertex
instead. Just note thateach_solid_vertex
is not an ordered iterator.num_points
is no longer exported. You are encouraged to instead usenum_solid_vertices
.remove_duplicate_triangles
has been removed. Just usesort_triangles
andunique!
.- I used to refer to distinct parts of a boundary as
segments
. This is misleading, since it's the first name that I use for constrained edges. So, I now use the termsections
. For example,has_multiple_segments
is nowhas_multiple_sections
. has_multiple_sections
can no longer be used on the ghost vertex map.getboundarynodes
has been removed. Just use and extendget_boundary_nodes
instead.BoundaryIndex
is nowGhostVertex
. Similar references toboundary_index
have been changed toghost_vertex
.boundary_map
is nowghost_vertex_map
.boundary_index_ranges
is nowghost_vertex_ranges
.integer_type
is removed (exceptforTriangulation
s).number_type
should be used for this.- Previously,
get_boundary_index
(now calledget_ghost_vertex
) errored if neither of the three arguments was a ghost vertex. Now, if none of the arguments is a ghost vertex, the function returnsk
. Similarly for the two-argument version. rotate_ghost_triangle_to_standard_form
androtate_triangle_to_standard_form
are removed. Usesort_triangle
instead.num_outer_boundary_segments
has been removed.- Iteration over
Adjacent
andAdjacent2Vertex
has been removed. Adjacent2Vertex
is now defined byAdjacent2Vertex{IntType,EdgesType}
rather thanAdjacent2Vertex{IntType,EdgesType,EdgeType}
.clear_empty_points!
is nowclear_empty_vertices!
.- The fields of
ConvexHull
are nowpoints
andvertices
rather thanpoints
andindices
. Additionally, the type is nowConvexHull{PointsType, IntegerType}
instead ofConvexHull{PointsType, Vector{IntegerType}}
. num_points
is no longer defined onConvexHull
s.- The
boundary_map
(nowghost_vertex_map
) andboundary_index_ranges
(nowghost_vertex_ranges
) are nowDict
s instead ofOrderedDict
s. - The constructor
Triangulation(points, triangles, boundary_nodes; kwargs...)
now uses the keyword argumentdelete_ghosts
instead ofadd_ghost_triangles
, with defaultdelete_ghosts=false
which is opposite to the previous defaultadd_ghost_triagnles=false
. - The function
get_empty_representative_points
has been deleted. get_convex_hull_indices
is nowget_convex_hull_vertices
.min_max
is removed - just useBase.minmax
.nearest_power_of_two
has been removed.intersection_of_ray_with_boundary
has been removed.identify_side
has been removed.intersection_of_ray_with_edge
has been removed.- The field names of
TriangulationStatistics
have been renamed to match the new segment terminology, and the fieldnum_convex_hull_points
is nownum_convex_hull_vertices
. get_total_area
is nowget_area
. The field nametotal_area
inTriangulationStatistics
is nowarea
.point_position_relative_to_box
has been removed.is_boundary_edge
has had its definition changed:is_boundary_edge(tri, i, j)
is nowis_boundary_edge(tri, j, i)
, so that we have consistency withis_boundary_triangle
.is_outer_boundary_index
is nowis_exterior_ghost_vertex
.is_outer_ghost_triangle
is nowis_exterior_ghost_triangle
.is_outer_ghost_edge
is nowis_exterior_ghost_edge
.is_outer_boundary_node
is nowis_exterior_ghost_vertex
.- The keyword arguments in
add_ghost_triangles!
anddelete_ghost_triangles!
have been removed. - The keyword argument
exterior_curve_index
intriangulate
has been removed. The exterior curves will be automatically computed. peek_triangle_ρ
has been removed, andtriangle_dequeue!
now does adequeue_pair!
.- The keyword
recompute_representative_point
is nowrecompute_representative_points
intriangulate
. - The keyword
add_ghost_triangles
intriangulate_rectangle
(andtriangulate_convex
) is nowdelete_ghosts
to be consistent withtriangulate
. The default isdelete_ghosts=false
, consistent with the previous default ofadd_ghost_triangles=true
. voronoi
now has the signaturevoronoi(tri; clip=false, smooth=false, kwargs...)
instead ofvoronoi(tri, clip=false)
(note the difference inclip
as a positional argument to a keyword argument).centroidal_smooth
is still exported (thekwargs...
are passed to it), but this can be a good alternative.- Gmsh support has been removed.
get!
is no longer defined onadjacent2vertex
.Certificate
is no longer exported.- The arguments to
construct_ghost_vertex_map
(previouslyconstruct_boundary_map
),construct_boundary_edge_map
, andconstruct_ghost_vertex_ranges
(previouslyconstruct_boundary_index_ranges
) are now positional. get_vertices
is no longer exported.map_boundary_index
is nowmap_ghost_vertex
.polylabel
is no longer an alias forpole_of_inaccessibility
.convert_to_boundary_edge
is nowconvert_to_edge_adjoining_ghost_vertex
.- References to a
point_order
are now aninsertion_order
. add_boundary_information!
is no longer exported.balanced_power_of_two_quarternary_split
has been removed.- To provide a custom constraint for triangulation, you now need to provide a constraint of the form
(tri::Triangulation, T::Triangle) -> Bool
with the keyword argumentcustom_constraint
, where the returned result istrue
if the triangleT
should be refined andfalse
otherwise. is_triangle_seditious
no longer has the unused argumentρ
at the end of its signature.- It is no longer possible to use
delete_point!
on points that are on the boundary or adjoin segments. It is too finicky, and for constrained triangulations you shouldn't be doing those operations anyway. For unconstrained triangulations, deleting a point on the boundary might be reasonable but it is difficult anddelete_point!
will not update the convex hull field of the triangulation for you either. The previous implementation did work sometimes, but it required playing around with how ghost triangles are interpreted and was unfortunately not reliable. PRs to address this are welcome, but it would need some careful thought and highly extensive testing (e.g. thousands of random tests for random triangulations, especially triangulations with very skinny or very large triangles on the boundary; triangulations with many collinearities such as fromtriangulate_rectangle
; triangulations with holes; and triangulations with disjoint domains). is_positively_oriented
now only accepts integers for the second argument, to avoid issues with misleading results when testing triangles.- Some methods like
get_right_boundary_node
have now been defined only forTriangulation
s, instead of lowering to a more complicated method that uses theadjacent
field and other fields like we used to.