private void Subdivide(Point2D a, Point2D b, Point2D c, Point2D d, double minLength, ICollection<Point2D> currentResult)
        {
            if (a.Dist(c) < minLength || b.Dist(d) < minLength)
            {
                return;
            }

            var p = m_RndGen.NextDouble(DividingProportion, 1 - DividingProportion);
            var q = m_RndGen.NextDouble(DividingProportion, 1 - DividingProportion);

            var e = Geometry.Interpolate(a, d, p);
            var f = Geometry.Interpolate(b, c, p);

            var g = Geometry.Interpolate(a, b, q);
            var i = Geometry.Interpolate(d, c, q);

            var h = Geometry.Interpolate(e, f, q);

            double k2 = DividingProportion / (1 - DividingProportion);

            var s = 1 + m_RndGen.NextDouble(-0.4, 0.4);
            var t = 1 + m_RndGen.NextDouble(-0.4, 0.4);
            var m = 1 + m_RndGen.NextDouble(-0.4, 0.4);
            var n = 1 + m_RndGen.NextDouble(-0.4, 0.4);

            Subdivide(a, Geometry.Interpolate(g, a, s), h, Geometry.Interpolate(e, a, t), minLength, currentResult);
            currentResult.Add(h);
            Subdivide(h, Geometry.Interpolate(f, c, s), c, Geometry.Interpolate(i, c, t), minLength, currentResult);
        }
        public List<Point2D> Generate(Point2D a, Point2D b, Point2D c, Point2D d, double minLength, bool makeSmooth)
        {
            Point2D left, right;

            if (makeSmooth)
            {
                var middle = (a + c) / 2;
                var smoothMultiplier = Math.Min(1, Geometry.Dist(a, c) / Geometry.Dist(b, middle)) * SmoothnessFactor;
                left = middle + (b - middle) * smoothMultiplier;
                smoothMultiplier = Math.Min(1, Geometry.Dist(a, c) / Geometry.Dist(d, middle)) * SmoothnessFactor;
                right = middle + (d - middle) * smoothMultiplier;
            }
            else
            {
                left = b;
                right = d;
            }

            var result = new List<Point2D>();

            result.Add(a);
            Subdivide(a, left, c, right, minLength, result);
            result.Add(c);

            return result;
        }
        public void Build(IMap map, MapSettings settings)
        {
            var noise = this.m_PerlinNoiseGenerator.GenerateNoise((int)map.Width, (int)map.Height, Seed, NoiseFrequency);

            var mapCenter = new Point2D(map.Width / 2, map.Height / 2);

            double l = 0;
            double r = 2;

            while (r - l > 1e-8)
            {
                double m = (l + r) / 2;
                int count = 0;
                foreach (var polygon in map.Polygons)
                {
                    var center = polygon.Center;

                    var dist = Geometry.SpecificDist(mapCenter, center, map.Width, map.Height);

                    if (polygon.IsInside && map.ContainsPointInside(center))
                    {
                        var noiseValue = noise[(int)center.X, (int)center.Y];

                        if (noiseValue > (this.BaseK + (dist > m ? (1 - this.BaseK) * (dist / m - 1) : 0)))
                        {
                            count++;
                        }
                    }
                }

                if (count > K * map.Polygons.Count)
                {
                    r = m;
                }
                else
                {
                    l = m;
                }
            }

            foreach (var polygon in map.Polygons)
            {
                var center = polygon.Center;

                var dist = Geometry.SpecificDist(mapCenter, center, map.Width, map.Height);

                if (polygon.IsInside && map.ContainsPointInside(center))
                {
                    var noiseValue = noise[(int)center.X, (int)center.Y];
                    /*polygon.IsLand = noise[(int) center.X, (int) center.Y] * (map.Width / (4 * dist + map.Width)) > 0.25;*/
                    polygon.IsLand = noiseValue > (this.BaseK + (dist > l ? (1 - this.BaseK) * (dist / l - 1) : 0));
                }
                else
                {
                    polygon.IsLand = false;
                }
            }
        }
Example #4
0
        public void AddTriangle(Point2D point, Triangle triangle)
        {
            var c = GetCoordinate(point);

            if (c != null)
            {
                m_Hash[c.X, c.Y] = triangle;
                TriangleCount++;
            }
        }
Example #5
0
        public bool ContainsPoint(Point2D point)
        {
            double[] vects = new double[3];

            for (int i = 0; i < 3; i++)
            {
                vects[i] = Geometry.Vect(Points[i], Points[(i + 1) % 3], point);
            }

            return vects.All(s => s >= 0);
        }
Example #6
0
        public Triangle GetTriangle(Point2D point)
        {
            var c = GetCoordinate(point);

            if (c != null)
            {
                return m_Hash[c.X, c.Y];
            }

            throw new ApplicationException("Can't find triangle in Hash");
        }
Example #7
0
        private void AddNewPoint(Point2D newPoint)
        {
            var point = new StructurePoint(newPoint);

            _points.Add(point);

            Triangle triangle = SearchTriangle(point);

            var newTriangles = new Triangle[3];

            for (int i = 0; i < 2; i++)
            {
                newTriangles[i] = new Triangle();
            }
            newTriangles[2] = triangle;

            for (int i = 0; i < 3; i++)
            {
                Edge edge = triangle.Edge(i);
                newTriangles[i].Points = new[] {edge.First, edge.Second, point};
                newTriangles[i].Triangles = new[] {
                                                      newTriangles[(i + 1) % 3],
                                                      newTriangles[(i + 2) % 3],
                                                      triangle.Triangles[i]
                                                  };
                if (triangle.Triangles[i] != null)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        if (triangle.Triangles[i].Triangles[j] == triangle)
                        {
                            triangle.Triangles[i].Triangles[j] = newTriangles[i];
                            break;
                        }
                    }
                }
            }

            /*newTriangles[2].Id = triangle.Id;
            Triangles[triangle.Id] = newTriangles[2];
            m_TrianglesToCheck.Enqueue(newTriangles[2]);*/

            for (int i = 0; i < 2; i++)
            {
                AddTriangle(newTriangles[i]);
                m_TrianglesToCheck.Enqueue(newTriangles[i]);
            }
            m_TrianglesToCheck.Enqueue(newTriangles[2]);

            CheckTriangles();
        }
Example #8
0
        private void ButtonAddRandomPointClick(object sender, EventArgs e)
        {
            Point2D point = new Point2D(m_Random.NextDouble() * MaxWidth, m_Random.NextDouble() * MaxHeight);

            // TODO: centralize try/catch
            try
            {
                m_MapCreatorModel.AddPoint(point);
            }
            catch (ApplicationException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        public override void Build(IMap map, MapSettings settings)
        {
            // TODO: change parameters
            //var noise = new NormNoiseDecorator(m_NoiseGenerator).GenerateNoise((int)map.Width, (int)map.Height, new Random().Next(), 10);
            var noise = m_NoiseGenerator.GenerateNoise((int)map.Width, (int)map.Height, new Random().Next(), 10);

            var queue = new PriorityQueue<Corner>((a, b) => -a.DistanceFromCoast.CompareTo(b.DistanceFromCoast));

            foreach (var corner in map.Corners)
            {
                if (corner.IsOceanCoast)
                {
                    corner.DistanceFromCoast = 0;
                    queue.Enqueue(corner);
                }
                else
                {
                    corner.DistanceFromCoast = 1e9;
                }
            }

            while (queue.Count > 0)
            {
                var current = queue.Dequeue();
                foreach (var corner in current.Corners.Where(c => c != null))
                {
                    var dist = current.Dist(corner);
                    if (corner.DistanceFromCoast > current.DistanceFromCoast + dist)
                    {
                        corner.DistanceFromCoast = current.DistanceFromCoast + dist;

                        queue.Enqueue(corner);

                        if (corner.IsLake)
                        {
                            double minNoise = noise[(int)corner.X, (int)corner.Y];
                            var lakeCorners = new List<Corner> { corner };

                            double bigStep = 2 * map.Corners.Count * this.SmallStep;

                            var lakeQueue = new Queue<Corner>();
                            lakeQueue.Enqueue(corner);
                            while (lakeQueue.Count > 0)
                            {
                                var lakeCorner = lakeQueue.Dequeue();
                                foreach (var c in lakeCorner.Corners)
                                {
                                    if (c.IsLake && c.DistanceFromCoast > lakeCorner.DistanceFromCoast + bigStep)
                                    {
                                        c.DistanceFromCoast = lakeCorner.DistanceFromCoast +
                                                              this.SmallStep * Geometry.Dist(lakeCorner, c) / map.Diagonal;
                                        lakeQueue.Enqueue(c);
                                        queue.Enqueue(c);

                                        minNoise = Math.Min(minNoise, noise[(int)c.X, (int)c.Y]);
                                        lakeCorners.Add(c);
                                    }
                                }
                            }

                            foreach (var lakeCorner in lakeCorners)
                            {
                                noise[(int)lakeCorner.X, (int)lakeCorner.Y] = minNoise;
                            }
                        }
                    }
                }
            }

            if (map.Corners.Any(c => c.IsLand))
            {
                var maxDistance = map.Corners.Where(c => c.IsLand).Max(c => c.DistanceFromCoast);
                foreach (var corner in map.Corners)
                {
                    double noiseInCorner;
                    if (map.ContainsPointInside(corner))
                    {
                        noiseInCorner = noise[(int) corner.X, (int) corner.Y];
                    }
                    else
                    {
                        var point = new Point2D(corner);
                        if (point.X < 0)
                        {
                            point.X = 0;
                        }
                        if (point.X >= map.Width - 1)
                        {
                            point.X = map.Width - 1;
                        }
                        if (point.Y < 0)
                        {
                            point.Y = 0;
                        }
                        if (point.Y >= map.Height - 1)
                        {
                            point.Y = map.Height - 1;
                        }
                        noiseInCorner = noise[(int) point.X, (int) point.Y];
                    }

                    var distanceConstraint = 2 * corner.DistanceFromCoast/maxDistance;

                    if (corner.IsOcean)
                    {
                        corner.Elevation = -Math.Min(distanceConstraint, noiseInCorner);
                    }
                    else
                    {
                        corner.Elevation = Math.Min(distanceConstraint, noiseInCorner);
                    }
                }
            }

            this.NormalizeCornerElevation(map);
        }
Example #10
0
 public static double Cos(Point2D a, Point2D b)
 {
     return Scal(a, b) / a.Length / b.Length;
 }
        private void CreateSkeleton(int width, Point2D direction, Polygon current, int totalLength, Queue<Polygon> queue,
                                    bool addAtMiddle)
        {
            current.InSkeleton = true;
            current.DistanceFromSkeleton = 0;
            current.IsLand = true;

            Polygon middlePolygon = null;
            Point2D newBaseDirection = null;

            for (int i = 0; i < totalLength - 1; i++)
            {
                Polygon nextPolygon = null;
                double cos = 0;
                foreach (var polygon in current.Polygons)
                {
                    if (polygon.IsInside && !polygon.InSkeleton && polygon.DistanceFromEdge > width)
                    {
                        var newCos = Geometry.Cos(direction, polygon.Center - current.Center);
                        if (nextPolygon == null || cos < newCos)
                        {
                            nextPolygon = polygon;
                            cos = newCos;
                        }
                    }
                }
                if (nextPolygon != null)
                {
                    nextPolygon.InSkeleton = true;
                    nextPolygon.DistanceFromSkeleton = 0;
                    nextPolygon.IsLand = true;
                    queue.Enqueue(nextPolygon);
                    direction = nextPolygon.Center - current.Center;
                    current = nextPolygon;
                    if (i == totalLength / 2)
                    {
                        middlePolygon = current;
                        newBaseDirection = new Point2D(direction.Y, -direction.X);
                        if (m_Random.Next(2) == 0)
                        {
                            newBaseDirection = -newBaseDirection;
                        }
                    }
                }
                else
                {
                    break;
                }
            }

            if (addAtMiddle && middlePolygon != null)
            {
                CreateSkeleton(width, newBaseDirection, middlePolygon, totalLength / 2, queue, m_Random.Next(2) == 0);
            }
        }
Example #12
0
        public void AddPoint(Point2D point)
        {
            m_Structure.AddPoint(point);

            UpdateMap();
        }
Example #13
0
 public Polygon(Point2D basePoint)
 {
     BasePoint = basePoint;
     Init();
 }
Example #14
0
 public static double Scal(Point2D a, Point2D b, Point2D c)
 {
     return (b.X - a.X)*(c.X - a.X) + (b.Y - a.Y)*(c.Y - a.Y);
 }
Example #15
0
 public MapPoint(Point2D point)
     : base(point)
 {
 }
Example #16
0
 private double Vect(Edge edge, Point2D point)
 {
     return Geometry.Vect(edge.First, edge.Second, point);
 }
Example #17
0
 public static double Dist(Point2D a, Point2D b)
 {
     return Math.Sqrt((a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y));
 }
Example #18
0
        private PointInt GetCoordinate(Point2D point)
        {
            int x = (int) (m_Size * point.X / Width);
            int y = (int) (m_Size * point.Y / Height);

            if (x < 0 || x >= m_Size || y < 0 || y >= m_Size)
            {
                return null;
            }
            return new PointInt(x, y);
        }
Example #19
0
 public double Dist(Point2D point)
 {
     return Geometry.Dist(this, point);
 }
Example #20
0
 public static double Vect(Point2D a, Point2D b, Point2D c)
 {
     return (b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X);
 }
Example #21
0
 public static double SpecificDist(Point2D center, Point2D p, double width, double height)
 {
     double dx = (p.X - center.X) / (width / 2);
     double dy = (p.Y - center.Y) / (height / 2);
     return Math.Sqrt(dx*dx + dy*dy);
 }
Example #22
0
 // TODO: Finish
 public static bool SegmentsIntersects(Point2D a, Point2D b, Point2D c, Point2D d)
 {
     bool intersect1 = (Vect(a, b, c) * Vect(a, b, d) < 0);
     bool intersect2 = (Vect(c, d, a) * Vect(c, d, b) < 0);
     return intersect1 && intersect2;
 }
Example #23
0
 public void AddPoint(Point2D point)
 {
     AddNewPoint(point);
 }
Example #24
0
 public bool ContainsPointInside(Point2D point)
 {
     return 0 <= point.X && point.X <= Width && 0 <= point.Y && point.Y <= Height;
 }
Example #25
0
 private static double Scal(Point2D a, Point2D b)
 {
     return a.X * b.X + a.Y * b.Y;
 }
Example #26
0
 public static Point2D Interpolate(Point2D a, Point2D b, double k)
 {
     return (1 - k) * a + k * b;
 }
Example #27
0
 public Point2D(Point2D point)
     : this(point.X, point.Y)
 {
 }
        private void CreateIndent(double[,] noise, double width, double height, double indent)
        {
            var mapCenter = new Point2D(width/2, height/2);

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    var point = new Point2D(i, j);
                    var dist = Geometry.SpecificDist(mapCenter, point, width, height);
                    if (dist > 1 - indent)
                    {
                        double overhead = (dist - (1 - indent)) / indent;
                        noise[i, j] = Math.Max(0, noise[i, j]*(1 - overhead));
                    }
                }
            }
        }
Example #29
0
 public Corner(Point2D point)
     : base(point.X, point.Y)
 {
     Init();
 }
Example #30
0
 public StructurePoint(Point2D point)
     : base(point.X, point.Y)
 {
 }