Beispiel #1
0
        public static VoronoiGraph ComputeVoronoiGraph(IEnumerable <PointF> points, int w = 800, int h = 600, bool debug = false)
        {
            var sites = new SiteList(points);

            if (debug)
            {
                sites.LogSites();
            }
            var graph = new VoronoiGraph(w, h)
            {
                Debug = debug
            };

            try {
                var edgeList   = new EdgeList(sites);
                var eventQueue = new EventQueue();

                sites.BottomSite = sites.ExtractMin();

                graph.PlotSite(sites.BottomSite);

                var newSite    = sites.ExtractMin();
                var newIntStar = new Site(Single.MaxValue, Single.MaxValue);

                while (true)
                {
                    if (!eventQueue.IsEmpty)
                    {
                        newIntStar = eventQueue.Min();
                    }

                    if (newSite != null && (eventQueue.IsEmpty || newSite.CompareTo(newIntStar) < 0))
                    {
                        // new site is smallest
                        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 (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 (debug)
                            {
                                Console.WriteLine("Inserting {0}", p);
                            }
                            eventQueue.Insert(bisector, p, Site.Distance(p, newSite));
                        }
                        newSite = sites.ExtractMin();
                    }
                    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, Side.Other(pm), v);
                        var p = Site.CreateIntersectingSite(llbnd, bisector);
                        if (p != null)
                        {
                            eventQueue.Delete(llbnd);
                            if (debug)
                            {
                                Console.WriteLine("Inserting {0}", p);
                            }
                            eventQueue.Insert(llbnd, p, Site.Distance(p, bot));
                        }
                        p = Site.CreateIntersectingSite(bisector, rrbnd);
                        if (p != null)
                        {
                            if (debug)
                            {
                                Console.WriteLine("Inserting {0}", p);
                            }
                            eventQueue.Insert(bisector, p, Site.Distance(p, bot));
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                for (var lbnd = edgeList.LeftEnd.Right; lbnd != edgeList.RightEnd; lbnd = lbnd.Right)
                {
                    var e = lbnd.Edge;
                    graph.PlotEndpoint(e);
                }
            } catch (Exception ex) {
                Console.WriteLine("########################################");
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
            graph.SweepLine = graph.Height;
            graph.ResetNewItems();
            foreach (var edge in graph.Edges)
            {
                edge.ClipVertices(new Rectangle(0, 0, w, h));
            }

            return(graph);
        }
Beispiel #2
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);
        }
Beispiel #3
0
 private float SiteDistance()
 {
     return(Site.Distance(Region[Side.Left], Region[Side.Right]));
 }