Since nothing ever moves once its been inserted into the beachline by which I mean that beachline never gets re-ordered , I originally linked list and simply inserted items in the correct place. There are multiple ways of doing this.
You could also just use a generic implementation of some self-balancing tree. The basic idea of this tree is that all leaf nodes are arcs and all internal nodes are edges.
The tree is such that an in-order traversal will list the items in left-to-right order as they appear at the beachline. Since its a tree the lookup is pretty straightforward, its just the usual decide-which-branch-to-take-and-recurse approach. The only time anything gets inserted into the beachline is when we encounter a new site and at that point we insert 5 items a left and right arc and edge, and a new arc in the middle as shown below:.
Removal is a little more complicated. The only time anything gets removed from the beachline is when we encounter an edge-intersection event and at that point we remove 3 items an arc and the edge on either side of it. We can then safely remove the arc and parent edge from the tree, but there is another parent somewhere higher up the tree. This higher edge simply gets substituted with the new replacement edge, inheriting the same parent and children.
While attempting to write my own implementation, I encountered quite a number of edge-cases. Below are some edge-cases to look out for, along with how I handled them. This is a problem if there are no existing arcs or if none of those that exist measurably cover the required x-coordinate.
During initialization we start by just adding the first arc to the beachline. However if the first two arcs have the exact same y-coordinate, then when we arrive via the standard code-path at the lookup for the second one, the first arc is still just a straight vertical line. To solve this, I added an extra case during startup that takes all points that are close enough in y to the first one my cutoff was a difference of 1.
Fortune's algorithm generates a voronoi diagram with a sweep-line. The conversion of this algorithm for triangulation is trivial, but it produces a delaunay triangulation.
Fortunes Algorithm: An intuitive explanation
I attempted to convert this algorithm into producing a constrained triangulation, useful for filling polygons. Computational geometry algorithms can be really difficult to understand and implement despite that they have clear visual interpretations. Their implementations can be extremely short and laborious to conjure. I got some results after working few evenings on this. Here's a visualization that illustrates how the algorithm sweeps through some glyph outlines, producing triangles for their innards.
I can use the results once I clean it up and solve some edge cases that I find interesting. In the rest of this blogpost I'm describing some difficult parts of this algorithm to understand it better. This is an extension into Fortune's algorithm, but first that algorithm is stripped down to produce delaunay triangles. Instead of producing edges into a voronoi diagram, it is generating a triangle for every valid circle event that occurs during the sweep.
Fortune's algorithm, the details
Fortune's algorithm maintains an arc consisting of parabolas. Finally, in DCEL, cells are implemented as a circular doubly linked list of half-edges where adjacent half-edges are linked together. Thus the prev and next fields points to the previous and next half-edges in the cell. Finally, the Face class represents a cell and it just contains a pointer to its site and another to one of its half-edges.
It does not matter which half-edge it is because a cell is a closed polygon. Thus we can access to all of its half-edges by traversing the circular linked list. The standard way to implement the event queue is to use a priority queue. During the processing of site and circle events we may need to remove circle events from the queue because they are not valid anymore. But most of the standard implementations of priority queues do not allow to remove an element which is not the top one.
There are two ways to tackle this problem. The first and simplest one is to add a valid flag to events. We set valid to true initially. Then instead of removing the circle event from the queue, we just set its flag to false. Finally, when we process the events in the main loop, if the valid flag of an event equals to false , we simply discard it and process the next one. Instead, I implemented my own priority queue which supports removal of any element it contains. The implementation of such a queue is pretty straightforward. I choose this method because I find it makes the code for the algorithm clearer.
The beachline data structure is the tricky part of the algorithm. If not implemented correctly there is no guarantee that the algorithm will run in. The key to reach this time complexity is to use a self-balancing tree. In most resources I have consulted the two blog articles aforementioned and Computational Geometry , they advise to implement the beachline as a tree where interior nodes represent breakpoints and leaves represent arcs. But they do not indicate how to balance the tree. I think that this representation is not the best possible because:.
Thus, I decided to represent the beachline differently. In my implementation the beachline is still a tree, but all nodes represent an arc. This representation has none of the previous shortcomings.
- Medical Marijuana 2012 State of the Union: State by State Legal Status (Medical Marijuana Series)?
- Visualization Skills - How To Use Your Imagination To Visualize And Manifest Your Goals And Dreams?
- The Tao of Healing: Meditations for Body and Spirit?
The first three fields are for the tree structure. The leftHalfEdge field points to the half-edge drawn by the left extremity of the arc. And rightHalfEdge to the half-edge drawn by the right extremity. The two pointers prev and next are useful to have a direct access to the previous and next arcs in the beachline.
They also allow to traverse the beachline like a doubly linked list. Finally, every arc has a color which is used to balance the beachline. I choose to use the red-black scheme to balance the beachline.
Related Fortunes Edge
Copyright 2019 - All Right Reserved