private void FortunesAlgorithm() { Site newSite, bottomSite, topSite, tempSite; Vertex v, vertex; PointF newintstar = PointF.Empty; LR leftRight; Halfedge lbnd, rbnd, llbnd, rrbnd, bisector; Edge edge; RectangleF dataBounds = _sites.GetSitesBounds(); int sqrt_nsites = (int)(Math.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 static readonlyitutes 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.Add(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(); // we need the vertices to clip the edges foreach (Edge edge2 in _edges) { edge2.ClipVertices(_plotBounds); } // but we don't actually ever use them again! foreach (Vertex vertex2 in vertices) { vertex2.Dispose(); } vertices.Clear(); }
private void FortunesAlgorithm() { Site newSite, bottomSite, topSite, tempSite; Vertex v, vertex; Vector2f newIntStar = Vector2f.zero; LR leftRight; Halfedge lbnd, rbnd, llbnd, rrbnd, bisector; Edge edge; Rectf dataBounds = sites.GetSitesBounds(); int sqrtSitesNb = (int)Math.Sqrt(sites.Count() + 4); HalfedgePriorityQueue heap = new HalfedgePriorityQueue(dataBounds.y, dataBounds.height, sqrtSitesNb); EdgeList edgeList = new EdgeList(dataBounds.x, dataBounds.width, sqrtSitesNb); List <Halfedge> halfEdges = new List <Halfedge>(); List <Vertex> vertices = new List <Vertex>(); Site bottomMostSite = sites.Next(); newSite = sites.Next(); while (true) { if (!heap.Empty()) { newIntStar = heap.Min(); } if (newSite != null && (heap.Empty() || CompareByYThenX(newSite, newIntStar) < 0)) { // New site is smallest //Debug.Log("smallest: new site " + newSite); // Step 8: lbnd = edgeList.EdgeListLeftNeighbor(newSite.Coord); // The halfedge just to the left of newSite //UnityEngine.Debug.Log("lbnd: " + lbnd); rbnd = lbnd.edgeListRightNeighbor; // The halfedge just to the right //UnityEngine.Debug.Log("rbnd: " + rbnd); bottomSite = RightRegion(lbnd, bottomMostSite); // This is the same as leftRegion(rbnd) // This Site determines the region containing the new site //UnityEngine.Debug.Log("new Site is in region of existing site: " + bottomSite); // Step 9 edge = Edge.CreateBisectingEdge(bottomSite, newSite); //UnityEngine.Debug.Log("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()) { // 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.Add(new Triangle(bottomSite, topSite, RightRegion(lbnd, bottomMostSite))); 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(); // we need the vertices to clip the edges foreach (Edge e in edges) { e.ClipVertices(plotBounds); } // But we don't actually ever use them again! foreach (Vertex ve in vertices) { ve.Dispose(); } vertices.Clear(); }
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...) // ******ADDED****** _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(); }
private void FortunesAlgorithm() { Vector2 s = Vector2.zero; Rect sitesBounds = _sites.GetSitesBounds(); int sqrt_nsites = (int)Mathf.Sqrt(_sites.Count + 4); HalfedgePriorityQueue halfedgePriorityQueue = new HalfedgePriorityQueue(sitesBounds.y, sitesBounds.height, sqrt_nsites); EdgeList edgeList = new EdgeList(sitesBounds.x, sitesBounds.width, sqrt_nsites); List <Halfedge> list = new List <Halfedge>(); List <Vertex> list2 = new List <Vertex>(); fortunesAlgorithm_bottomMostSite = _sites.Next(); Site site = _sites.Next(); while (true) { if (!halfedgePriorityQueue.Empty()) { s = halfedgePriorityQueue.Min(); } if (site != null && (halfedgePriorityQueue.Empty() || CompareByYThenX(site, s) < 0)) { Halfedge halfedge = edgeList.EdgeListLeftNeighbor(site.Coord); Halfedge edgeListRightNeighbor = halfedge.edgeListRightNeighbor; Site site2 = FortunesAlgorithm_rightRegion(halfedge); Edge edge = Edge.CreateBisectingEdge(site2, site); _edges.Add(edge); Halfedge halfedge2 = Halfedge.Create(edge, Side.LEFT); list.Add(halfedge2); edgeList.Insert(halfedge, halfedge2); Vertex vertex; if ((vertex = Vertex.Intersect(halfedge, halfedge2)) != null) { list2.Add(vertex); halfedgePriorityQueue.Remove(halfedge); halfedge.vertex = vertex; halfedge.ystar = vertex.y + site.Dist(vertex); halfedgePriorityQueue.Insert(halfedge); } halfedge = halfedge2; halfedge2 = Halfedge.Create(edge, Side.RIGHT); list.Add(halfedge2); edgeList.Insert(halfedge, halfedge2); if ((vertex = Vertex.Intersect(halfedge2, edgeListRightNeighbor)) != null) { list2.Add(vertex); halfedge2.vertex = vertex; halfedge2.ystar = vertex.y + site.Dist(vertex); halfedgePriorityQueue.Insert(halfedge2); } site = _sites.Next(); continue; } if (!halfedgePriorityQueue.Empty()) { Halfedge halfedge = halfedgePriorityQueue.ExtractMin(); Halfedge edgeListLeftNeighbor = halfedge.edgeListLeftNeighbor; Halfedge edgeListRightNeighbor = halfedge.edgeListRightNeighbor; Halfedge edgeListRightNeighbor2 = edgeListRightNeighbor.edgeListRightNeighbor; Site site2 = FortunesAlgorithm_leftRegion(halfedge); Site site3 = FortunesAlgorithm_rightRegion(edgeListRightNeighbor); _triangles.Add(new Triangle(site2, site3, FortunesAlgorithm_rightRegion(halfedge))); Vertex vertex2 = halfedge.vertex; vertex2.SetIndex(); Edge edge2 = halfedge.edge; Side?leftRight = halfedge.leftRight; edge2.SetVertex(leftRight.Value, vertex2); Edge edge3 = edgeListRightNeighbor.edge; Side?leftRight2 = edgeListRightNeighbor.leftRight; edge3.SetVertex(leftRight2.Value, vertex2); edgeList.Remove(halfedge); halfedgePriorityQueue.Remove(edgeListRightNeighbor); edgeList.Remove(edgeListRightNeighbor); Side side = Side.LEFT; if (site2.y > site3.y) { Site site4 = site2; site2 = site3; site3 = site4; side = Side.RIGHT; } Edge edge = Edge.CreateBisectingEdge(site2, site3); _edges.Add(edge); Halfedge halfedge2 = Halfedge.Create(edge, side); list.Add(halfedge2); edgeList.Insert(edgeListLeftNeighbor, halfedge2); edge.SetVertex(SideHelper.Other(side), vertex2); Vertex vertex; if ((vertex = Vertex.Intersect(edgeListLeftNeighbor, halfedge2)) != null) { list2.Add(vertex); halfedgePriorityQueue.Remove(edgeListLeftNeighbor); edgeListLeftNeighbor.vertex = vertex; edgeListLeftNeighbor.ystar = vertex.y + site2.Dist(vertex); halfedgePriorityQueue.Insert(edgeListLeftNeighbor); } if ((vertex = Vertex.Intersect(halfedge2, edgeListRightNeighbor2)) != null) { list2.Add(vertex); halfedge2.vertex = vertex; halfedge2.ystar = vertex.y + site2.Dist(vertex); halfedgePriorityQueue.Insert(halfedge2); } continue; } break; } halfedgePriorityQueue.Dispose(); edgeList.Dispose(); for (int i = 0; i < list.Count; i++) { Halfedge halfedge3 = list[i]; halfedge3.ReallyDispose(); } list.Clear(); for (int j = 0; j < _edges.Count; j++) { Edge edge = _edges[j]; edge.ClipVertices(_plotBounds); } for (int k = 0; k < list2.Count; k++) { Vertex vertex = list2[k]; vertex.Dispose(); } list2.Clear(); }