private void FortunesAlgorithm ()
{
Site newSite, bottomSite, topSite, tempSite;
Vertex v, vertex;
Vector2 newintstar = Vector2.zero; //Because the compiler doesn't know that it will have a value - Julian
Side leftRight;
Halfedge lbnd, rbnd, llbnd, rrbnd, bisector;
Edge edge;
Rect dataBounds = _sites.GetSitesBounds ();
int sqrt_nsites = (int)(Mathf.Sqrt (_sites.Count + 4));
HalfedgePriorityQueue heap = new HalfedgePriorityQueue (dataBounds.y, dataBounds.height, sqrt_nsites);
EdgeList edgeList = new EdgeList (dataBounds.x, dataBounds.width, sqrt_nsites);
List<Halfedge> halfEdges = new List<Halfedge> ();
List<Vertex> vertices = new List<Vertex> ();
fortunesAlgorithm_bottomMostSite = _sites.Next ();
newSite = _sites.Next ();
for (;;) {
if (heap.Empty () == false) {
newintstar = heap.Min ();
}
if (newSite != null
&& (heap.Empty () || CompareByYThenX (newSite, newintstar) < 0)) {
/* new site is smallest */
//trace("smallest: new site " + newSite);
// Step 8:
lbnd = edgeList.EdgeListLeftNeighbor (newSite.Coord); // the Halfedge just to the left of newSite
//trace("lbnd: " + lbnd);
rbnd = lbnd.edgeListRightNeighbor; // the Halfedge just to the right
//trace("rbnd: " + rbnd);
bottomSite = FortunesAlgorithm_rightRegion (lbnd); // this is the same as leftRegion(rbnd)
// this Site determines the region containing the new site
//trace("new Site is in region of existing site: " + bottomSite);
// Step 9:
edge = Edge.CreateBisectingEdge (bottomSite, newSite);
//trace("new edge: " + edge);
_edges.Add (edge);
bisector = Halfedge.Create (edge, Side.LEFT);
halfEdges.Add (bisector);
// inserting two Halfedges into edgeList constitutes Step 10:
// insert bisector to the right of lbnd:
edgeList.Insert (lbnd, bisector);
// first half of Step 11:
if ((vertex = Vertex.Intersect (lbnd, bisector)) != null) {
vertices.Add (vertex);
heap.Remove (lbnd);
lbnd.vertex = vertex;
lbnd.ystar = vertex.y + newSite.Dist (vertex);
heap.Insert (lbnd);
}
lbnd = bisector;
bisector = Halfedge.Create (edge, Side.RIGHT);
halfEdges.Add (bisector);
// second Halfedge for Step 10:
// insert bisector to the right of lbnd:
edgeList.Insert (lbnd, bisector);
// second half of Step 11:
if ((vertex = Vertex.Intersect (bisector, rbnd)) != null) {
vertices.Add (vertex);
bisector.vertex = vertex;
bisector.ystar = vertex.y + newSite.Dist (vertex);
heap.Insert (bisector);
}
newSite = _sites.Next ();
} else if (heap.Empty () == false) {
/* intersection is smallest */
lbnd = heap.ExtractMin ();
llbnd = lbnd.edgeListLeftNeighbor;
rbnd = lbnd.edgeListRightNeighbor;
rrbnd = rbnd.edgeListRightNeighbor;
bottomSite = FortunesAlgorithm_leftRegion (lbnd);
topSite = FortunesAlgorithm_rightRegion (rbnd);
// these three sites define a Delaunay triangle
// (not actually using these for anything...)
_triangles.Add(new Triangle(bottomSite, topSite, FortunesAlgorithm_rightRegion(lbnd)));
v = lbnd.vertex;
v.SetIndex ();
lbnd.edge.SetVertex ((Side)lbnd.leftRight, v);
rbnd.edge.SetVertex ((Side)rbnd.leftRight, v);
edgeList.Remove (lbnd);
heap.Remove (rbnd);
edgeList.Remove (rbnd);
leftRight = Side.LEFT;
if (bottomSite.y > topSite.y) {
tempSite = bottomSite;
bottomSite = topSite;
topSite = tempSite;
leftRight = Side.RIGHT;
}
edge = Edge.CreateBisectingEdge (bottomSite, topSite);
_edges.Add (edge);
bisector = Halfedge.Create (edge, leftRight);
halfEdges.Add (bisector);
edgeList.Insert (llbnd, bisector);
edge.SetVertex (SideHelper.Other (leftRight), v);
if ((vertex = Vertex.Intersect (llbnd, bisector)) != null) {
vertices.Add (vertex);
heap.Remove (llbnd);
llbnd.vertex = vertex;
llbnd.ystar = vertex.y + bottomSite.Dist (vertex);
heap.Insert (llbnd);
}
if ((vertex = Vertex.Intersect (bisector, rrbnd)) != null) {
vertices.Add (vertex);
bisector.vertex = vertex;
bisector.ystar = vertex.y + bottomSite.Dist (vertex);
heap.Insert (bisector);
}
} else {
break;
}
}
// heap should be empty now
heap.Dispose ();
edgeList.Dispose ();
for (int hIndex = 0; hIndex<halfEdges.Count; hIndex++) {
Halfedge halfEdge = halfEdges [hIndex];
halfEdge.ReallyDispose ();
}
halfEdges.Clear ();
// we need the vertices to clip the edges
for (int eIndex = 0; eIndex<_edges.Count; eIndex++) {
edge = _edges [eIndex];
edge.ClipVertices (_plotBounds);
}
// but we don't actually ever use them again!
for (int vIndex = 0; vIndex<vertices.Count; vIndex++) {
vertex = vertices [vIndex];
vertex.Dispose ();
}
vertices.Clear ();
}