JuliaGeometry / DelaunayTriangulation.jl

Delaunay triangulations and Voronoi tessellations in two dimensions.
https://juliageometry.github.io/DelaunayTriangulation.jl/
MIT License
55 stars 5 forks source link

Some thoughts on constrained Delaunay triangulations #31

Closed DanielVandH closed 1 year ago

DanielVandH commented 1 year ago

Need to implement constrained Delaunay triangulation at some point. The method here https://www.sciencedirect.com/science/article/pii/S0925772115000322?via%3Dihub would be good. Once this is implemented, de Berg's method will probably be removed.

Some thoughts:

With this interface, we could define three methods:

triangulate(pts) # Unconstrained Delaunay
triangulate(pts, edges) # Constrained Delaunay, no holes (this is a planar straight line graph)
triangulate(pts, edges, loops) # Constrained Delaunay, with holes (this is a piecewise linear complex)

(Maybe a PSLG or PLC struct needs to be defined?)

The returned value for all of these could still be a Triangulation. Triangulation would be updated to be something like

struct Triangulation
    points
    adjacent
    adjacent2vertex
    graph
    edges # better named needed probably - this will just be the list of constrained edges, not all edges in the triangulation - edges(graph) serves that purpose
    loops
    boundary_nodes
end

(The boundary_nodes field is just something extra to store boundaries for both the exterior and for the interiors.)

Will probably have to sit on these ideas for a while before getting the time to complete it, and to just think about the interface in general. The point location work needs a lot of thought as mentioned.

DanielVandH commented 1 year ago

My Gmsh code could be extended as a good way to test all this, providing the interfaces I give above for triangulate except for generate_mesh (except entirely in terms of loops, since the main point there is dealing with boundaries and holes).

This has now been done (not on this master yet, need to incorporate the interface). Just provide a vector of vector of vectors to provide a list of boundaries, with boundaries split by segments, and the first boundary is the outer-most boundary. Very simple to do. Will be a good test case for point location, etc.

Does give me the idea to remove loops from the above, and just let boundary_nodes be such that boundary_nodes[m][n] is the list of boundary nodes for the nth segment of the mth boundary. The outer-most boundary is boundary_nodes[m]. If a vector of floats was provided, boundary_nodes is just a vector (rather than a vector of vector of vectors).

Example mesh: example_triangulation

sparse_example_triangulation

DanielVandH commented 1 year ago

Some progress for this is in https://github.com/DanielVandH/DelaunayTriangulationDev.jl, where I've also rewritten how the predicates are implemented (with each predicate returning a Certificate type defined via EnumX.jl). No constrained triangulation yet, but everything has been rewritten to remove some assumptions that will no longer be true with multiple boundaries (e.g. BoundaryIndex is the only boundary index). Will be ported over eventually, probably once the interface is fully finalised + constrained triangulation is added, aiming for a 1.0 release.

DanielVandH commented 1 year ago

See #32 for some progress

DanielVandH commented 1 year ago

Still thinking about this. https://github.com/DanielVandH/DelaunayTriangulation.jl/tree/convex-triangulation has some work on triangulation convex polygons, i.e. vertex deletion, which involves code that will later go into constrained triangulation. Just have to keep working on it so that I understand how it works in the presence of cocircular/collinear points.