Add triangulation model and delaunay triangulation algorithm. #684
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is the biggest part of my work for GSoC2019. This PR proposes three major implementations that are strongly connected to each other. I understand that I still have work to do to get my second PR merged, but I still start this PR now because I was informed that it may be beneficial for a future proposal.
Because this is a pretty large PR, I am not optimistic enough to think that it will go through without significant changes. Once the interfaces are in a state that can pass a review, I can add doxygen comments before merging. I will now give a brief overview of the major design decisions.
The triangulation holds containers of vertices and faces. The vertices store a point, an iterator to an incident face and conform to the point concept themselves. The faces store iterators to three points, up to three adjacent triangles and conform to the ring concept. The member m_o stores the indices pointing to itself from its adjacent triangles. This information is redundant but storing it saves linear searches in some operations. Additionally, the triangulation stores an iterator to a single vertex on the boundary so that the boundary can be accessed without having to perform a search first.
There are two inner structures, namely halfedge_index and fulledge_index. They describe edges implicitly as a combination of a face_iterator and an index to an vertex that lies on the opposite of the described edge (from both triangles that lie adjacent to the edge in the case of fulledge_index). A model::segment can be obtained from such an edge.
The preferred way to use the triangulation is not through its methods but to use the free functions vertex_range, face_range, face_adjacent_range, face_incident_faces, vertex_incident_faces, vertex_incident_vertices instead. They all provide ranges of vertices, faces or iterators respectively that allow to fully navigate the triangulation.
The preferred way to build a triangulation is to use algorithm 2.
delaunay triangulation
This algorithm is adapted from http://www.s-hull.org/paper/s_hull.pdf . The most significant change is that I do not perform a linear search for visible edges in step 7 but a binary search instead. This saves calls to SideStrategy.
The algorithm is implemented as a cartesian strategy. I understand that the idea in Boost.Geometry is to implement algorithms coordinate system agnostic and only put coordinate system specific geometric calculations into strategies. I do think that this improved shull algorithm is fundamentally coordinates system specific because even if spherical predicates would be used, it would not be able to compute a spherical triangulation as it is and I do not see a general way to make it work for both. I can discuss this in more detail but I do not want to make this PR description too long.
voronoi view
As is well known, delaunay triangulations and voronoi diagrams are dual concepts. The free functions voronoi_vertex_view and voronoi_face_view allow to obtain the corresponding voronoi diagram vertices/faces given a delaunay triangulation face/vertex respectively.