Пример #1
0
        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();
        }