コード例 #1
0
        /// <summary>
        /// Generates random points around a given point
        /// </summary>
        public static List <Vector2> GeneratePointsAround(Vector2 point, int pointAmount, float maxRadius, float minDistance = 0f)
        {
            var points = new List <Vector2>(pointAmount);
            var sa     = GlobalPRNG.Next() * 2 * Mathf.PI;

            var cnt = 0;

            do
            {
                var a = sa + Mathf.Sqrt(points.Count) * (3 + 2 * GlobalPRNG.Next());

                var r = maxRadius * GlobalPRNG.Next();
                var x = Mathf.Cos(a) * r + point.x;
                var y = Mathf.Sin(a) * r + point.y;

                var v = new Vector2(x, y);
                if (Mathf.Abs(minDistance) > float.Epsilon)
                {
                    var closestPoint = v.FindClosestIn(points);
                    if (closestPoint.HasValue && Vector2.Distance(v, closestPoint.Value) < minDistance)
                    {
                        cnt++;
                        continue;
                    }
                }

                points.Add(v);
            } while (cnt < pointAmount * 10 && points.Count < pointAmount);


            return(points);
        }
コード例 #2
0
        public static Vector2 BisectSegment(Vector2 p0, Vector2 p1, float maxDeviation = 0f)
        {
            Vector2 vector = p1 - p0;
            Vector2 normal = GetNormalVector(vector);

            float deviationDirection = MathUtils.Sign((GlobalPRNG.Next() - 0.5f) * 2);
            var   deviation          = GlobalPRNG.Next() * maxDeviation * deviationDirection;

            Vector2 bisector = p0 + vector * 0.5f + deviation * vector.magnitude * normal;

            return(new Vector2(bisector.x, bisector.y));
        }
コード例 #3
0
ファイル: DistrictLayer.cs プロジェクト: Cxyda/Urbanice
        /// <summary>
        /// Finds a valid district type for a district
        /// </summary>
        private DistrictType GetDistrictTypeForRegion(Polygon region)
        {
            var neighbors       = region.GetNeighbors();
            var districtWeights = new WeightedDistrictList();

            List <DistrictType> forbiddenTypes = new List <DistrictType>();

            // Gather all neighbors and sum up the weights
            foreach (var neighbor in neighbors)
            {
                if (!PolygonIdToDistrictMap.ContainsKey(neighbor) || PolygonIdToDistrictMap[neighbor] == null)
                {
                    continue;
                }

                var config = DefinitionContainer.GetDefinitionFor(PolygonIdToDistrictMap[neighbor].Type);

                foreach (DistrictWeight nd in config.NeighboringDistricts)
                {
                    if (nd.Weight == 0)
                    {
                        // A forbidden type was found! Add it to the list to remove it later
                        forbiddenTypes.Add(nd.Element);
                        continue;
                    }

                    districtWeights.Add(nd);
                }
            }

            // Assign invalid type because the weighted list is empty
            if (districtWeights.OverallWeight == 0)
            {
                return(DistrictType.Invalid);
            }

            // Remove all forbidden district types
            foreach (var ft in forbiddenTypes)
            {
                districtWeights.RemoveAll(ft);
            }
            // TODO : Apply filters later

            // finally return one of the valid types
            var value = GlobalPRNG.Next();
            var type  = districtWeights.GetElement(value);

            return(type);
        }
コード例 #4
0
ファイル: Vertex.cs プロジェクト: Cxyda/Urbanice
        /// <summary>
        /// Returns a random vertex of the given list within distance to this vertex
        /// </summary>
        public Vertex GetRandomPointWithinDistance(List <Vertex> list, float maxDistance)
        {
            var list1 = new List <Vertex>();

            foreach (var p in list)
            {
                if (Vector2.Distance(this, p) > maxDistance)
                {
                    continue;
                }

                list1.Add(p);
            }

            var index = (int)(GlobalPRNG.Next() * list1.Count);

            return(index >= list1.Count ? null : list1[index]);
        }
コード例 #5
0
ファイル: CityLayer.cs プロジェクト: Cxyda/Urbanice
        public void Generate(BaseLayer parentLayer)
        {
            _generatedCityCores = new List <Vector2>();
            CityCanvas          = CanvasPolygon();

            while (_generatedCityCores.Count < (int)Size)
            {
                var x = CityCorePlacement.Evaluate(GlobalPRNG.Next());
                var y = CityCorePlacement.Evaluate(GlobalPRNG.Next());

                // TODO : Apply filters later

                _generatedCityCores.Add(new Vector2(Mathf.Lerp(BoundingBox.xMin, BoundingBox.xMax, x),
                                                    Mathf.Lerp(BoundingBox.yMin, BoundingBox.yMax, y)));
            }

            CityCores = _generatedCityCores;
        }
コード例 #6
0
ファイル: WardLayer.cs プロジェクト: Cxyda/Urbanice
        /// <summary>
        /// Finds a valid ward type for a polygon ward
        /// </summary>
        /// <param name="nPolygon"></param>
        /// <returns></returns>
        private WardType GetNeighborhoodTypeFor(Polygon nPolygon)
        {
            var neighbors = nPolygon.GetNeighbors();
            var wardWeights = new WeightedNWardList();

            List<WardType> forbiddenTypes = new List<WardType>();

            // Check all neighbors for valid and invalid neighbor types
            foreach (var neighbor in neighbors)
            {
                if (!PolygonIdToNeighborhoodMap.ContainsKey(neighbor) || PolygonIdToNeighborhoodMap[neighbor] == null)
                    continue;

                var config = WardDefinition.GetDefinitionFor(PolygonIdToNeighborhoodMap[neighbor].Type);

                foreach (WardWeight nd in config.NeighboringWards)
                {
                    if (nd.Weight == 0)
                    {
                        // A weight of 0 means this type is forbidden, add it to the list to remove it later
                        forbiddenTypes.Add(nd.Element);
                        continue;
                    }

                    wardWeights.Add(nd);
                }
            }

            // Assign type invalid, because for some reason the weighs list is empty
            if (wardWeights.OverallWeight == 0)
                return WardType.Invalid;

            // Remove all forbidden types
            foreach (var ft in forbiddenTypes)
            {
                wardWeights.RemoveAll(ft);
            }
            // TODO : Apply filters later

            // Finally get the type
            var value = GlobalPRNG.Next();
            var type = wardWeights.GetElement(value);
            return type;
        }
コード例 #7
0
        public static Vector2 CreateLineSegmentInDirection(Vector2 p0, Vector2 direction, float segmentLength,
                                                           float deviation = 0f)
        {
            direction.Normalize();

            var p1 = p0 + direction * segmentLength;

            if (!(deviation > 0f))
            {
                return(p1);
            }

            var   normal             = GetNormalVector(direction);
            float deviationDirection = MathUtils.Sign((GlobalPRNG.Next() - 0.5f) * 2);

            var deviationVector = normal * deviation * GlobalPRNG.Next() * segmentLength;

            p1 += deviationVector * deviationDirection;
            return(p1);
        }
コード例 #8
0
        public void GenerateCity()
        {
            CleanupSerializedData();

            GlobalPRNG.Init(GlobalSeed);

            TerrainData.Init();
            CityLayer.Init();
            DistrictLayer.Init();
            WardLayer.Init();
            PrimaryStreetLayer.Init();

            Stopwatch sw = new Stopwatch();

            sw.Start();

            TerrainData.Generate(null);

            if (CityLayer.Visibility == LayerVisibility.Generate)
            {
                CityLayer.Generate(null);
            }

            if (DistrictLayer.Visibility == LayerVisibility.Generate)
            {
                DistrictLayer.Generate(CityLayer);
            }

            if (WardLayer.Visibility == LayerVisibility.Generate)
            {
                WardLayer.Generate(DistrictLayer);
            }
            if (PrimaryStreetLayer.Visibility == LayerVisibility.Generate)
            {
                PrimaryStreetLayer.Generate(DistrictLayer);
            }

            sw.Stop();
            Debug.Log($"GenerationTime: {sw.Elapsed.Milliseconds} ms");
        }
コード例 #9
0
 public static Vector2 GetRandomPointBetween(Vector2 p0, Vector2 p1)
 {
     return(GetPointBetween(p0, p1, GlobalPRNG.Next()));
 }