private void FortunesAlgorithm() { var dataBounds = _sites.GetSiteBounds(); var sqrtNSites = (int)Math.Sqrt(_sites.Length + 4); var heap = new HalfEdgePriorityQueue(dataBounds.Top, dataBounds.Height, sqrtNSites); var edgeList = new EdgeList(dataBounds.Left, dataBounds.Width, sqrtNSites); var halfEdges = new List<HalfEdge>(); var vertices = new List<Vertex>(); var bottomMostSite = _sites.Next(); var newSite = _sites.Next(); var newIntStar = new Vector2(); for (; ; ) { if (!heap.Empty) { newIntStar = heap.Min(); } if (newSite != null && (heap.Empty || CompareByYThenX(newSite, newIntStar) < 0)) { Console.WriteLine("smallest: new site " + newSite); var lbnd = edgeList.EdgeListLeftNeighbor(newSite.Coord); Console.WriteLine("lbnd: " + lbnd); var rbnd = lbnd.EdgeListRightNeighbor; Console.WriteLine("rbnd: " + rbnd); var bottomSite = RightRegion(lbnd) ?? bottomMostSite; Console.WriteLine("new site is in region of existing site: " + bottomSite); var edge = Edge.CreateBisectingEdge(bottomSite, newSite); Console.WriteLine("new edge: " + edge); Edges.Add(edge); var bisector = new HalfEdge(edge, LR.Left); halfEdges.Add(bisector); edgeList.Insert(lbnd, bisector); Vertex vertex = Vertex.Intersect(lbnd, bisector); if (vertex != null) { vertices.Add(vertex); heap.Remove(lbnd); lbnd.Vertex = vertex; lbnd.YStar = vertex.Y + newSite.Distance(vertex); heap.Insert(lbnd); } lbnd = bisector; bisector = new HalfEdge(edge, LR.Right); halfEdges.Add(bisector); edgeList.Insert(lbnd, bisector); vertex = Vertex.Intersect(bisector, rbnd); if (vertex != null) { vertices.Add(vertex); bisector.Vertex = vertex; bisector.YStar = vertex.Y + newSite.Distance(vertex); heap.Insert(bisector); } newSite = _sites.Next(); } else if (!heap.Empty) { var lbnd = heap.ExtractMin(); var llbnd = lbnd.EdgeListLeftNeighbor; var rbnd = lbnd.EdgeListRightNeighbor; var rrbnd = rbnd.EdgeListRightNeighbor; var bottomSite = LeftRegion(lbnd) ?? bottomMostSite; var topSite = RightRegion(rbnd) ?? bottomMostSite; var 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); var leftRight = LR.Left; if (bottomSite.Y > topSite.Y) { var tempSite = bottomSite; bottomSite = topSite; topSite = tempSite; leftRight = LR.Right; } var edge = Edge.CreateBisectingEdge(bottomSite, topSite); Edges.Add(edge); var bisector = new HalfEdge(edge, leftRight); halfEdges.Add(bisector); edgeList.Insert(llbnd, bisector); edge.SetVertex(LR.Other(leftRight), v); Vertex vertex; if ((vertex = Vertex.Intersect(llbnd, bisector)) != null) { vertices.Add(vertex); heap.Remove(llbnd); llbnd.Vertex = vertex; llbnd.YStar = vertex.Y + bottomSite.Distance(vertex); heap.Insert(llbnd); } if ((vertex = Vertex.Intersect(bisector, rrbnd)) != null) { vertices.Add(vertex); bisector.Vertex = vertex; bisector.YStar = vertex.Y + bottomSite.Distance(vertex); heap.Insert(bisector); } } else { break; } } halfEdges.Clear(); var nullVerts = Edges.Where(e => e.RightVertex == null || e.LeftVertex == null).ToList(); foreach (var edge in Edges) { edge.ClipVertices(PlotBounds); } vertices.Clear(); }
private void FortunesAlgorithm() { var dataBounds = _sites.GetSiteBounds(); var sqrtNSites = (int)Math.Sqrt(_sites.Length + 4); var heap = new HalfEdgePriorityQueue(dataBounds.Top, dataBounds.Height, sqrtNSites); var edgeList = new EdgeList(dataBounds.Left, dataBounds.Width, sqrtNSites); var halfEdges = new List <HalfEdge>(); var vertices = new List <Vertex>(); var bottomMostSite = _sites.Next(); var newSite = _sites.Next(); var newIntStar = new Vector2(); for (; ;) { if (!heap.Empty) { newIntStar = heap.Min(); } if (newSite != null && (heap.Empty || CompareByYThenX(newSite, newIntStar) < 0)) { Console.WriteLine("smallest: new site " + newSite); var lbnd = edgeList.EdgeListLeftNeighbor(newSite.Coord); Console.WriteLine("lbnd: " + lbnd); var rbnd = lbnd.EdgeListRightNeighbor; Console.WriteLine("rbnd: " + rbnd); var bottomSite = RightRegion(lbnd) ?? bottomMostSite; Console.WriteLine("new site is in region of existing site: " + bottomSite); var edge = Edge.CreateBisectingEdge(bottomSite, newSite); Console.WriteLine("new edge: " + edge); Edges.Add(edge); var bisector = new HalfEdge(edge, LR.Left); halfEdges.Add(bisector); edgeList.Insert(lbnd, bisector); Vertex vertex = Vertex.Intersect(lbnd, bisector); if (vertex != null) { vertices.Add(vertex); heap.Remove(lbnd); lbnd.Vertex = vertex; lbnd.YStar = vertex.Y + newSite.Distance(vertex); heap.Insert(lbnd); } lbnd = bisector; bisector = new HalfEdge(edge, LR.Right); halfEdges.Add(bisector); edgeList.Insert(lbnd, bisector); vertex = Vertex.Intersect(bisector, rbnd); if (vertex != null) { vertices.Add(vertex); bisector.Vertex = vertex; bisector.YStar = vertex.Y + newSite.Distance(vertex); heap.Insert(bisector); } newSite = _sites.Next(); } else if (!heap.Empty) { var lbnd = heap.ExtractMin(); var llbnd = lbnd.EdgeListLeftNeighbor; var rbnd = lbnd.EdgeListRightNeighbor; var rrbnd = rbnd.EdgeListRightNeighbor; var bottomSite = LeftRegion(lbnd) ?? bottomMostSite; var topSite = RightRegion(rbnd) ?? bottomMostSite; var 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); var leftRight = LR.Left; if (bottomSite.Y > topSite.Y) { var tempSite = bottomSite; bottomSite = topSite; topSite = tempSite; leftRight = LR.Right; } var edge = Edge.CreateBisectingEdge(bottomSite, topSite); Edges.Add(edge); var bisector = new HalfEdge(edge, leftRight); halfEdges.Add(bisector); edgeList.Insert(llbnd, bisector); edge.SetVertex(LR.Other(leftRight), v); Vertex vertex; if ((vertex = Vertex.Intersect(llbnd, bisector)) != null) { vertices.Add(vertex); heap.Remove(llbnd); llbnd.Vertex = vertex; llbnd.YStar = vertex.Y + bottomSite.Distance(vertex); heap.Insert(llbnd); } if ((vertex = Vertex.Intersect(bisector, rrbnd)) != null) { vertices.Add(vertex); bisector.Vertex = vertex; bisector.YStar = vertex.Y + bottomSite.Distance(vertex); heap.Insert(bisector); } } else { break; } } halfEdges.Clear(); var nullVerts = Edges.Where(e => e.RightVertex == null || e.LeftVertex == null).ToList(); foreach (var edge in Edges) { edge.ClipVertices(PlotBounds); } vertices.Clear(); }