Пример #1
0
        // TODO: Land-locked rivers
        // TODO?: Add the one river tile connecting ocean and river.
        // TODO: smoother curvier rivers
        processedResults process()
        {
            HashSet <Point> done   = new HashSet <Point>(); // River tiles that have been added to a river tree
            List <Point>    oceans = new List <Point>();    // Tiles that are definitely ocean.
            List <Point>    lakes  = new List <Point>();    // ditto but for lakes
            List <Node>     rivers = new List <Node>();     // List of parent nodes of finished river trees.

            // FLOOD FILL AND PUT ALL OCEAN TILES INTO OCEAN LIST
            // LAKES IN THE LAKE LIST
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    Point current = new Point(x, y);
                    if (isOcean(current))
                    {
                        oceans.Add(current);
                    }
                    else if (isLake(current))
                    {
                        lakes.Add(current);
                    }
                }
            }

            // Build rivers that start from the ocean
            processOceanToRiver(oceans, rivers, done);

            // Build rivers that start from lakes!
            processLakeToRiver(lakes, rivers, done);

            // Build rivers that start from land!
            processInlandRivers(rivers, done);

            // Update tail length counts.
            foreach (Node n in rivers)
            {
                n.getMaxTailLength();
            }


            ////// TEST: FUNCTION TO MOVE VERTEXES TO EDGE FROM CENTER SEMI-RECURSIVELY
            for (int i = 0; i < rivers.Count; i++)
            {
                startTranslate(rivers[i]);
            }

            processedResults prout = new processedResults();

            prout.rivers = rivers;
            prout.oceans = oceans;
            prout.lakes  = lakes;
            return(prout);
        }
Пример #2
0
        Dictionary<Point, int> render(processedResults pr, string filename, bool edges = false)
        {
            List<Node> rivers = pr.rivers;
            List<Point> oceans = pr.oceans;
            List<Point> lakes = pr.lakes;

            List<Node> rendernodes = new List<Node>();
            foreach (Node r in rivers) // rendernodes are different from river nodes in that they are not necessarily actual river trees.
                // They should sometimes be smaller branches of main rivers.
                rendernodes.Add(r);

            List<List<PointF>> curvepoints = new List<List<PointF>>(); // This is the result of this function, a list of list of points for use in drawCurve()
            //
            while (rendernodes.Count > 0)
            {
                List<PointF> points = new List<PointF>();
                Node current = rendernodes.First();
                rendernodes.Remove(current);

                // Initially add the coords to the list.
                points.Add(current.center_coords); // Always starts with the center coords, because the first tile never gets an edge coord set.

                while (current.numChildren() > 0)
                {
                    int largestIndex = current.maxLengthIndex;
                    // Except for the largest index, add every other child node to the rendernodes list as a separate branch.
                    for (int i = 0; i < current._children_.Count; i++)
                    {
                        if (largestIndex != i)
                        {
                            Node newparent = new Node();
                            newparent.center_coords = current.center_coords;
                            newparent.edge_coords = current.edge_coords;
                            newparent.insertChild(current._children_[i]);

                            // Extending new river tree size by 2 for smoother rivers.
                            if (current.parent != null)
                            {
                                Node newnewparent = new Node();
                                newnewparent.center_coords = current.parent.center_coords;
                                newnewparent.edge_coords = current.edge_coords;
                                newnewparent.insertChild(newparent);
                                rendernodes.Add(newnewparent);
                            }
                            else
                                rendernodes.Add(newparent);
                        }
                    }
                    current = current._children_[largestIndex]; // Finally, change the current to point to the new node.

                    if (edges)
                        points.Add(current.edge_coords);
                    else
                        points.Add(current.center_coords); // Also, extend the pointslist.
                }

                curvepoints.Add(points);
            }

            Bitmap output = new Bitmap(width * scale, height * scale);
            Graphics graphic = Graphics.FromImage(output);
            SolidBrush oceanbrush = new SolidBrush(ocean_c);
            SolidBrush landbrush = new SolidBrush(land_c);
            SolidBrush lakebrush = new SolidBrush(lake_c);

            // Draws the land
            graphic.FillRectangle(landbrush, new Rectangle(0, 0, width * scale, height * scale));

            // Draw rivers
            Pen pen = new Pen(river_c, (float)scale/2.0f);
            Random rng = new Random();

            Dictionary<PointF, PointF> RandPointFromPoint = new Dictionary<PointF, PointF>();

            foreach (var pointlist in curvepoints)
            {
                PointF[] points = pointlist.ToArray();
                for (int i = 0; i < pointlist.Count; i++ ) // Scale coordinates
                {
                    if (RandPointFromPoint.ContainsKey(points[i]))
                        points[i] = RandPointFromPoint[points[i]];
                    else
                    {
                        PointF oldpoint = points[i];

                        points[i].X *= scale;
                        points[i].X += scale / 2;
                        points[i].Y *= scale;
                        points[i].Y += scale / 2;

                        // Experimental: Add noise to coordinates.
                        points[i].X += rng.Next(-scale / 4, scale / 4);
                        points[i].Y += rng.Next(-scale / 4, scale / 4);

                        PointF newpoint = points[i];
                        RandPointFromPoint[oldpoint] = newpoint;
                    }

                }

                if (pointlist.Count == 1)
                    continue;//g.DrawRectangle(pen, new Rectangle(points[0].X, points[0].Y, scale, scale));
                else
                    graphic.DrawCurve(pen, points, 0.4f);
            }

            // Finally, draw the oceans and lakes over the rivers to "hide" the ends of the river.
            foreach (var point in oceans)
            {
                graphic.FillRectangle(oceanbrush, new Rectangle(point.X * scale, point.Y * scale, scale, scale));
            }
            foreach (var point in lakes)
            {
                graphic.FillRectangle(lakebrush, new Rectangle(point.X * scale, point.Y * scale, scale, scale));
            }

            output.Save(filename);
            var result = DictionaryFromBitmap(output);
            output.Dispose();
            return result;
        }
Пример #3
0
        // TODO: Land-locked rivers
        // TODO?: Add the one river tile connecting ocean and river.
        // TODO: smoother curvier rivers
        processedResults process()
        {
            HashSet<Point> done = new HashSet<Point>(); // River tiles that have been added to a river tree
            List<Point> oceans = new List<Point>(); // Tiles that are definitely ocean.
            List<Point> lakes = new List<Point>(); // ditto but for lakes
            List<Node> rivers = new List<Node>(); // List of parent nodes of finished river trees.
            // FLOOD FILL AND PUT ALL OCEAN TILES INTO OCEAN LIST
            // LAKES IN THE LAKE LIST
            for (int y = 0; y < height; y++)
            for (int x = 0; x < width; x++)
            {
                Point current = new Point(x, y);
                if (isOcean(current))
                    oceans.Add(current);
                else if (isLake(current))
                    lakes.Add(current);
            }

            // Build rivers that start from the ocean
            processOceanToRiver(oceans, rivers, done);

            // Build rivers that start from lakes!
            processLakeToRiver(lakes, rivers, done);

            // Build rivers that start from land!
            processInlandRivers(rivers, done);

            // Update tail length counts.
            foreach (Node n in rivers)
                n.getMaxTailLength();

            ////// TEST: FUNCTION TO MOVE VERTEXES TO EDGE FROM CENTER SEMI-RECURSIVELY
            for (int i = 0; i < rivers.Count; i++)
            {
                startTranslate(rivers[i]);
            }

            processedResults prout = new processedResults();
            prout.rivers = rivers;
            prout.oceans = oceans;
            prout.lakes = lakes;
            return prout;
        }
Пример #4
0
        Dictionary <Point, int> render(processedResults pr, string filename, bool edges = false)
        {
            List <Node>  rivers = pr.rivers;
            List <Point> oceans = pr.oceans;
            List <Point> lakes  = pr.lakes;

            List <Node> rendernodes = new List <Node>();

            foreach (Node r in rivers) // rendernodes are different from river nodes in that they are not necessarily actual river trees.
            // They should sometimes be smaller branches of main rivers.
            {
                rendernodes.Add(r);
            }

            List <List <PointF> > curvepoints = new List <List <PointF> >(); // This is the result of this function, a list of list of points for use in drawCurve()

            //
            while (rendernodes.Count > 0)
            {
                List <PointF> points  = new List <PointF>();
                Node          current = rendernodes.First();
                rendernodes.Remove(current);

                // Initially add the coords to the list.
                points.Add(current.center_coords); // Always starts with the center coords, because the first tile never gets an edge coord set.

                while (current.numChildren() > 0)
                {
                    int largestIndex = current.maxLengthIndex;
                    // Except for the largest index, add every other child node to the rendernodes list as a separate branch.
                    for (int i = 0; i < current._children_.Count; i++)
                    {
                        if (largestIndex != i)
                        {
                            Node newparent = new Node();
                            newparent.center_coords = current.center_coords;
                            newparent.edge_coords   = current.edge_coords;
                            newparent.insertChild(current._children_[i]);

                            // Extending new river tree size by 2 for smoother rivers.
                            if (current.parent != null)
                            {
                                Node newnewparent = new Node();
                                newnewparent.center_coords = current.parent.center_coords;
                                newnewparent.edge_coords   = current.edge_coords;
                                newnewparent.insertChild(newparent);
                                rendernodes.Add(newnewparent);
                            }
                            else
                            {
                                rendernodes.Add(newparent);
                            }
                        }
                    }
                    current = current._children_[largestIndex]; // Finally, change the current to point to the new node.

                    if (edges)
                    {
                        points.Add(current.edge_coords);
                    }
                    else
                    {
                        points.Add(current.center_coords); // Also, extend the pointslist.
                    }
                }

                curvepoints.Add(points);
            }

            Bitmap     output     = new Bitmap(width * scale, height * scale);
            Graphics   graphic    = Graphics.FromImage(output);
            SolidBrush oceanbrush = new SolidBrush(ocean_c);
            SolidBrush landbrush  = new SolidBrush(land_c);
            SolidBrush lakebrush  = new SolidBrush(lake_c);

            // Draws the land
            graphic.FillRectangle(landbrush, new Rectangle(0, 0, width * scale, height * scale));

            // Draw rivers
            Pen    pen = new Pen(river_c, (float)scale / 2.0f);
            Random rng = new Random();

            Dictionary <PointF, PointF> RandPointFromPoint = new Dictionary <PointF, PointF>();

            foreach (var pointlist in curvepoints)
            {
                PointF[] points = pointlist.ToArray();
                for (int i = 0; i < pointlist.Count; i++)  // Scale coordinates
                {
                    if (RandPointFromPoint.ContainsKey(points[i]))
                    {
                        points[i] = RandPointFromPoint[points[i]];
                    }
                    else
                    {
                        PointF oldpoint = points[i];

                        points[i].X *= scale;
                        points[i].X += scale / 2;
                        points[i].Y *= scale;
                        points[i].Y += scale / 2;

                        // Experimental: Add noise to coordinates.
                        points[i].X += rng.Next(-scale / 4, scale / 4);
                        points[i].Y += rng.Next(-scale / 4, scale / 4);

                        PointF newpoint = points[i];
                        RandPointFromPoint[oldpoint] = newpoint;
                    }
                }

                if (pointlist.Count == 1)
                {
                    continue;//g.DrawRectangle(pen, new Rectangle(points[0].X, points[0].Y, scale, scale));
                }
                else
                {
                    graphic.DrawCurve(pen, points, 0.4f);
                }
            }

            // Finally, draw the oceans and lakes over the rivers to "hide" the ends of the river.
            foreach (var point in oceans)
            {
                graphic.FillRectangle(oceanbrush, new Rectangle(point.X * scale, point.Y * scale, scale, scale));
            }
            foreach (var point in lakes)
            {
                graphic.FillRectangle(lakebrush, new Rectangle(point.X * scale, point.Y * scale, scale, scale));
            }


            output.Save(filename);
            var result = DictionaryFromBitmap(output);

            output.Dispose();
            return(result);
        }