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();
}