コード例 #1
0
        public VoronoiGraph StepVoronoi()
        {
            _graph.ResetNewItems();
            if (!_edgeFixup)
            {
                if (!_eventQueue.IsEmpty)
                {
                    _newIntStar = _eventQueue.Min();
                }

                if (_newSite != null && (_eventQueue.IsEmpty || /*Geometry.CompareByYThenX(_newSite, _newIntStar)*/ _newSite.CompareTo(_newIntStar) < 0))
                {
                    _graph.PlotSite(_newSite);

                    var lbnd = _edgeList.LeftBound(_newSite);
                    var rbnd = lbnd.Right;
                    var bot  = _edgeList.RightRegion(lbnd);
                    var e    = Edge.CreateBisectingEdge(bot, _newSite);
                    _graph.PlotBisector(e);
                    var bisector = new HalfEdge(e, Side.Left);
                    EdgeList.Insert(lbnd, bisector);
                    var p = Site.CreateIntersectingSite(lbnd, bisector);
                    if (p != null)
                    {
                        _eventQueue.Delete(lbnd);
                        if (_graph.Debug)
                        {
                            Console.WriteLine("Inserting {0}", p);
                        }
                        _eventQueue.Insert(lbnd, p, Site.Distance(p, _newSite));
                    }
                    lbnd     = bisector;
                    bisector = new HalfEdge(e, Side.Right);
                    EdgeList.Insert(lbnd, bisector);
                    p = Site.CreateIntersectingSite(bisector, rbnd);
                    if (p != null)
                    {
                        if (_graph.Debug)
                        {
                            Console.WriteLine("Inserting {0}", p);
                        }
                        _eventQueue.Insert(bisector, p, Site.Distance(p, _newSite));
                    }
                    _newSite = _sites.ExtractMin();
                    if (_newSite != null && _newSite.Y > _graph.SweepLine)
                    {
                        _graph.SweepLine = _newSite.Y;
                    }
                    else if (_newSite == null)
                    {
                        _graph.SweepLine = _graph.Height;
                    }
                }
                else if (!_eventQueue.IsEmpty)     // intersection is smallest
                {
                    var lbnd  = _eventQueue.ExtractMin();
                    var llbnd = lbnd.Left;
                    var rbnd  = lbnd.Right;
                    var rrbnd = rbnd.Right;
                    var bot   = _edgeList.LeftRegion(lbnd);
                    var top   = _edgeList.RightRegion(rbnd);
                    _graph.PlotTriple(bot, top, _edgeList.RightRegion(lbnd));
                    var v = lbnd.Vertex;

                    _graph.PlotVertex(v);

                    _graph.EndPoint(lbnd.Edge, lbnd.Side, v);
                    _graph.EndPoint(rbnd.Edge, rbnd.Side, v);
                    EdgeList.Delete(lbnd);
                    _eventQueue.Delete(rbnd);
                    EdgeList.Delete(rbnd);
                    var pm = Side.Left;
                    if (bot.Y > top.Y)
                    {
                        var temp = bot;
                        bot = top;
                        top = temp;
                        pm  = Side.Right;
                    }
                    var e = Edge.CreateBisectingEdge(bot, top);
                    _graph.PlotBisector(e);
                    var bisector = new HalfEdge(e, pm);
                    EdgeList.Insert(llbnd, bisector);
                    _graph.EndPoint(e, pm == Side.Left ? Side.Right : Side.Left, v);
                    var p = Site.CreateIntersectingSite(llbnd, bisector);
                    if (p != null)
                    {
                        _eventQueue.Delete(llbnd);
                        if (_graph.Debug)
                        {
                            Console.WriteLine("Inserting {0}", p);
                        }
                        _eventQueue.Insert(llbnd, p, Site.Distance(p, bot));
                    }
                    p = Site.CreateIntersectingSite(bisector, rrbnd);
                    if (p != null)
                    {
                        if (_graph.Debug)
                        {
                            Console.WriteLine("Inserting {0}", p);
                        }
                        _eventQueue.Insert(bisector, p, Site.Distance(p, bot));
                    }
                }
                else
                {
                    _edgeFixup = true;
                }
                StepNumber++;
            }
            else
            {
                var lbnd = _edgeList.LeftEnd.Right;
                if (lbnd != _edgeList.RightEnd)
                {
                    var e = lbnd.Edge;
                    _graph.PlotEndpoint(e);
                    EdgeList.Delete(lbnd);
                    StepNumber++;
                }
                else
                {
                    foreach (var edge in _graph.Edges)
                    {
                        edge.ClipVertices(new Rectangle(0, 0, _graph.Width, _graph.Height));
                    }
                    if (_graph.Debug)
                    {
                        Console.WriteLine("Done computing graph!");
                    }
                }
            }
            if (_graph.Debug)
            {
                Console.WriteLine("Step: " + StepNumber);
            }
            return(_graph);
        }