private void fortunesAlgorithm() { Site newSite, bottomSite, topSite, tempSite; Vertex v, vertex; Vector2 newintstar; LR leftRight; Halfedge lbnd, rbnd, llbnd, rrbnd, bisector; Edge edge; Rect dataBounds = _sites.getSitesBounds(); int sqrt_nsites = (int)(Mathf.Sqrt(_sites.length + 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>(); Site 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 = rightRegion(lbnd,bottomMostSite); // 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, LR.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, LR.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 = leftRegion(lbnd,bottomMostSite); topSite = rightRegion(rbnd,bottomMostSite); // these three sites define a Delaunay triangle // (not actually using these for anything...) //_triangles.push(new Triangle(bottomSite, topSite, rightRegion(lbnd))); v = lbnd.vertex; v.setIndex(); lbnd.edge.setVertex(lbnd.leftRight, v); rbnd.edge.setVertex(rbnd.leftRight, v); edgeList.remove(lbnd); heap.remove(rbnd); edgeList.remove(rbnd); leftRight = LR.LEFT; if (bottomSite.y > topSite.y) { tempSite = bottomSite; bottomSite = topSite; topSite = tempSite; leftRight = LR.RIGHT; } edge = Edge.createBisectingEdge(bottomSite, topSite); _edges.Add(edge); bisector = Halfedge.create(edge, leftRight); halfEdges.Add(bisector); edgeList.insert(llbnd, bisector); edge.setVertex(LR.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(); // foreach (Halfedge halfEdge in halfEdges) // { // halfEdge.reallyDispose(); // } halfEdges.Clear();// = 0; // we need the vertices to clip the edges foreach (Edge edge1 in _edges) { edge1.clipVertices(_plotBounds); } // but we don't actually ever use them again! // foreach (vertex in vertices) // { // vertex.dispose(); // } vertices.Clear();// = 0; }