예제 #1
0
        private void GenerateGraph() {
            var start = Stopwatch.GetTimestamp();
            var rand = new Random((int)nudSeed.Value);
            var w = splitPanel.Panel2.ClientSize.Width;
            var h = splitPanel.Panel2.ClientSize.Height;

            var numSites = (int)nudNumRegions.Value;
            var sites = new List<PointF>();

            for (int i = 0; i < numSites; i++) {
                var p = new Point(rand.Next(w), rand.Next(h));
                sites.Add(p);
            }

            if (nudRelax.Value > 0) {
                sites = RelaxPoints((int)nudRelax.Value, sites);
            }


            _graph = VoronoiGraph.ComputeVoronoiGraph(sites, w, h, chDebug.Checked);

            var elapsed = new TimeSpan(Stopwatch.GetTimestamp() - start);


            Console.WriteLine("Voronois done!");
            Console.WriteLine("{0} sites, {1} relaxations, time elapsed: {2}", numSites, nudRelax.Value, elapsed);


        }
예제 #2
0
        public Voronoi(IEnumerable<PointF> points, int w = 800, int h = 600, bool debug=false) {
            _sites = new SiteList(points);
            _sites.LogSites();
            _graph = new VoronoiGraph(w, h) {Debug = debug};
            
            _edgeList = new EdgeList(_sites);
            _eventQueue = new EventQueue();
            _edgeFixup = false;

            StepNumber = 0;

        }
예제 #3
0
파일: MainForm.cs 프로젝트: craigge/dx11
        private void GenerateGraph() {

            var rand = new Random((int)nudSeed.Value);
            var w = splitPanel.Panel2.ClientSize.Width;
            var h = splitPanel.Panel2.ClientSize.Height;

            var numSites = (int)nudNumRegions.Value;
            var sites = new List<PointF>();
            for (int i = 0; i < numSites; i++) {
                var p = new Point(rand.Next(w), rand.Next(h));
                sites.Add(p);
            }
            if (nudRelax.Value > 0) {
                sites = RelaxPoints((int)nudRelax.Value, sites);
            }


            _graph = Voronoi.ComputeVoronoi(sites, w, h, chDebug.Checked);
            Console.WriteLine("Voronois done!");
        }
예제 #4
0
파일: voronoiMap.cs 프로젝트: craigge/dx11
        public VoronoiMap(VoronoiGraph g) {
            _graph = g;
            Reset();
            BuildGraph(g);
            //ImproveCorners();

            AssignCornerElevations();
            AssignOceanCoastAndLand();
            //RedistributeElevations(LandCorners(Corners));
            //AssignOceanElevations();
            //AssignPolygonElevations();

            //CalculateDownslopes();
            //CalculateWatersheds();
            //CreateRivers();
            //AssignCornerMoisture();
            //RedistributeMoisture(LandCorners(Corners));
            //AssignPolygonMoisture();

            //AssignBiomes();
        }
예제 #5
0
        private void InitializeVoronoi() {
            _sitesToIgnore = new HashSet<Site>();
            Console.Clear();
            nudStepTo.Value = 0;
            Edge.EdgeCount = 0;

            var rand = new Random((int)nudSeed.Value);


            var w = splitPanel.Panel2.ClientSize.Width;
            var h = splitPanel.Panel2.ClientSize.Height;

            var numSites = (int)nudNumRegions.Value;
            var sites = new List<PointF>();
            Console.WriteLine(w);
            Console.WriteLine(h);
            for (int i = 0; i < numSites; i++) {
                var p = new Point(rand.Next(w), rand.Next(h));
                sites.Add(p);
            }
            if (nudRelax.Value > 0) {
                sites = RelaxPoints((int)nudRelax.Value, sites);
            }


            _voronoi = new Voronoi(sites, w, h, chDebug.Checked);
            _graph = _voronoi.Initialize();
        }
예제 #6
0
 private void btnStepVoronoi_Click(object sender, EventArgs e) {
     using (var graphics = splitPanel.Panel2.CreateGraphics()) {
         _graph = _voronoi.StepVoronoi();
         nudStepTo.Value++;
         PaintDiagram(graphics, false);
     }
 }
예제 #7
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);
        }
예제 #8
0
파일: Voronoi.cs 프로젝트: craigge/dx11
        public static VoronoiGraph ComputeVoronoi(IEnumerable<PointF> points, int w = 800, int h = 600, bool debug=false) {
            var sites = new SiteList(points);
            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(float.MaxValue, float.MaxValue);

                while (true) {
                    if (!eventQueue.IsEmpty) {
                        newIntStar = eventQueue.Min();
                    }
                    // new site is smallest
                    if (newSite != null && 
                        (eventQueue.IsEmpty || newSite.Y < newIntStar.Y || (Math.Abs(newSite.Y - newIntStar.Y) < Geometry.Tolerance && newSite.X < newIntStar.X))) {

                        graph.PlotSite(newSite);

                        var lbnd = edgeList.LeftBound(newSite);
                        var rbnd = lbnd.Right;
                        var bot = edgeList.RightRegion(lbnd);
                        var e = Geometry.Bisect(bot, newSite);
                        graph.PlotBisector(e);
                        var bisector = new HalfEdge(e, Side.Left);
                        edgeList.Insert(lbnd, bisector);
                        var p = Geometry.Intersect(lbnd, bisector);
                        if (p != null) {
                            eventQueue.Delete(lbnd);
                            if (debug) {
                                Console.WriteLine("Inserting {0}", p);
                            }
                            eventQueue.Insert(lbnd, p, Geometry.Distance(p, newSite));
                        }
                        lbnd = bisector;
                        bisector = new HalfEdge(e, Side.Right);
                        edgeList.Insert(lbnd, bisector);
                        p = Geometry.Intersect(bisector, rbnd);
                        if (p != null) {
                            if (debug) {
                                Console.WriteLine("Inserting {0}", p);
                            }
                            eventQueue.Insert(bisector, p, Geometry.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);



                        Geometry.EndPoint(lbnd.Edge, lbnd.Side, v, graph);
                        Geometry.EndPoint(rbnd.Edge, rbnd.Side, v, graph);
                        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 = Geometry.Bisect(bot, top);
                        graph.PlotBisector(e);
                        var bisector = new HalfEdge(e, pm);
                        edgeList.Insert(llbnd, bisector);
                        Geometry.EndPoint(e, Side.Other(pm), v, graph);
                        var p = Geometry.Intersect(llbnd, bisector);
                        if (p != null) {
                            eventQueue.Delete(llbnd);
                            if (debug) {
                                Console.WriteLine("Inserting {0}", p);
                            }
                            eventQueue.Insert(llbnd, p, Geometry.Distance(p, bot));
                        }
                        p = Geometry.Intersect(bisector, rrbnd);
                        if (p != null) {
                            if (debug) {
                                Console.WriteLine("Inserting {0}", p);
                            }
                            eventQueue.Insert(bisector, p, Geometry.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;
        }
예제 #9
0
파일: MainForm.cs 프로젝트: craigge/dx11
 private void btnStepVoronoi_Click(object sender, EventArgs e) {
     _graph = _voronoi.StepVoronoi();
     nudStepTo.Value++;
     splitPanel.Panel2.Invalidate();
 }
예제 #10
0
파일: Geometry.cs 프로젝트: craigge/dx11
 public static void EndPoint(Edge edge, Side side, Site site, VoronoiGraph c) {
     edge.Endpoint[side] = site;
     var opSide = side == Side.Left ? Side.Right : Side.Left;
     if (edge.Endpoint[opSide] == null) {
         return;
     }
     c.PlotEndpoint(edge);
 }
예제 #11
0
파일: voronoiMap.cs 프로젝트: craigge/dx11
        private void BuildGraph(VoronoiGraph voronoi) {
            var points = voronoi.Sites;
            var libedges = voronoi.Edges;
            var centerLookup = new Dictionary<PointF, Center>();

            foreach (var point in points) {
                point.Region(new RectangleF(0, 0, voronoi.Width, voronoi.Height));
                var p = new Center {
                    Index = Centers.Count,
                    Point = point
                };
                Centers.Add(p);
                centerLookup[point] = p;
                
            }

            foreach (var libedge in libedges.Where(e=>e.Visible)) {
                var dedge = libedge.DelauneyLine;
                var vedge = libedge.VoronoiEdge;

                var edge = new Edge1 {
                    Index = Edges.Count,
                    Midpoint = (Valid(vedge.P1) && Valid(vedge.P2)) ? new PointF((vedge.P1.X + vedge.P2.X) * 0.5f, (vedge.P1.Y + vedge.P2.Y) * 0.5f) : InvalidPoint
                };

                Edges.Add(edge);

                // edges point to corners
                edge.V0 = MakeCorner(vedge.P1);
                edge.V1 = MakeCorner(vedge.P2);
                // edges point to centers
                edge.D0 = centerLookup[dedge.P1];
                edge.D1 = centerLookup[dedge.P2];

                // Centers point to edges
                if (edge.D0 != null) { edge.D0.Borders.Add(edge); }
                if (edge.D1 != null) { edge.D1.Borders.Add(edge); }
                // Corners point to edges
                if (edge.V0 != null) { edge.V0.Protrudes.Add(edge); }
                if (edge.V1 != null) { edge.V1.Protrudes.Add(edge); }

                // Centers point to centers
                if (edge.D0 != null && edge.D1 != null) {
                    AddToCenterList(edge.D0.Neighbors, edge.D1);
                    AddToCenterList(edge.D1.Neighbors, edge.D0);
                }
                // Corners point to corners
                if (edge.V0 != null && edge.V1 != null) {
                    AddToCornerList(edge.V0.Adjacent, edge.V1);
                    AddToCornerList(edge.V1.Adjacent, edge.V0);
                }
                // Centers point to corners
                if (edge.D0 != null) {
                    AddToCornerList(edge.D0.Corners, edge.V0);
                    AddToCornerList(edge.D0.Corners, edge.V1);
                }
                if (edge.D1 != null) {
                    AddToCornerList(edge.D1.Corners, edge.V0);
                    AddToCornerList(edge.D1.Corners, edge.V1);
                }

                // Corners point to centers
                if (edge.V0 != null) {
                    AddToCenterList(edge.V0.Touches, edge.D0);
                    AddToCenterList(edge.V0.Touches, edge.D1);
                }
                if (edge.V1 != null) {
                    AddToCenterList(edge.V1.Touches, edge.D0);
                    AddToCenterList(edge.V1.Touches, edge.D1);
                }
            }
        }