dodano strefy wpływów miast

This commit is contained in:
veniti 2019-11-21 20:40:35 +01:00
parent 4facf6c3ba
commit 476411f6e7
5 changed files with 126 additions and 73 deletions

View File

@ -22,7 +22,6 @@ namespace Assets.AnnotationPass
public double MinimumRoadLength { get; set; } = 2;
public double BusinessCityFields { get; set; } = 0.3;
public double LivingCityFields { get; set; } = 0.7;
public CityFieldsPass(Random random)
{
@ -144,20 +143,20 @@ namespace Assets.AnnotationPass
// add field types
var orderedFields = city.Fields.OrderBy(cf => Point.Dist(cf.Center, city.Center)).ToList();
orderedFields.First().cityFieldType = CityFieldTypes.MainSquare;
orderedFields.First().Type = FieldType.MainSquare;
int businessCityFields = (int)Math.Ceiling((BusinessCityFields*orderedFields.Count()));
foreach (var cityField in orderedFields.Skip(1).Take(businessCityFields))
{
cityField.cityFieldType = CityFieldTypes.Business;
cityField.Type = FieldType.Business;
}
foreach (var cityField in orderedFields.Skip(1+businessCityFields))
{
cityField.cityFieldType = CityFieldTypes.Living;
cityField.Type = FieldType.Living;
}
}

View File

@ -10,6 +10,11 @@ namespace Assets.AnnotationPass
{
public const string CitiesProperty = "Cities";
public const string CityProperty = "City";
public int MaxCitiesCount { get; set; } = 20;
public int MaxPlacementTries { get; set; } = 30;
public float RangeOfInfluence { get; set; } = .5f;
public float CitiesSize { get; set; } = .5f;
private Graph<Location> _locationGraph;
private Graph<MapSite> _basicGraph;
@ -20,11 +25,6 @@ namespace Assets.AnnotationPass
_random = random ?? new Random();
}
IEnumerable<int> LocateCities()
{
return ChoosePoints(5);
}
City CreateCity(int vertex, int size)
{
City newCity = new City();
@ -49,34 +49,46 @@ namespace Assets.AnnotationPass
s.Metadata.SetProperty(CityProperty, newCity);
}
newCity.RangeOfInfluence = GetCityRangeOfInfluence(newCity);
return newCity;
}
IEnumerable<int> ChoosePoints(int number)
List<City> CreateCities()
{
List<City> cities = new List<City>();
var vertices = new List<int>();
for (int i = 0; i < number; i++)
int guard = MaxPlacementTries;
int createdCitiesCount = 0;
while (createdCitiesCount < MaxCitiesCount && guard-- > 0)
{
var randomLocation = _locationGraph.Vertices[_random.Next(1, _locationGraph.Vertices.Count())];
var count = randomLocation.Sites.Count();
var randomPoint = randomLocation.Sites[_random.Next(0, count)];
vertices.Add(randomPoint.Index);
var randomLocation = _locationGraph.Vertices.Skip(1).RandomElement(_random);
var randomSite = randomLocation.Sites.RandomElement(_random);
if (cities.Any(c => Point.Dist(PointUtils.Mean(c.Sites.Select(s => s.Center)), randomSite.Center) < c.RangeOfInfluence))
continue;
cities.Add(CreateCity(randomSite.Index, (int)Math.Ceiling(CitiesSize * _random.Next(0, 30))));
guard = MaxPlacementTries;
createdCitiesCount++;
}
return vertices;
return cities;
}
public float GetCityRangeOfInfluence(City city)
{
return RangeOfInfluence*city.Sites.Count;
}
public void Annotate(Map map)
{
_basicGraph = map.Sites.Clone() as Graph<MapSite>;
_basicGraph = map.Sites.Clone() as Graph<MapSite>;
_locationGraph = map.Metadata.GetProperty<Graph<Location>>(LandmassPass.MapLocationsProperty);
var cities = new List<City>();
var locations = LocateCities();
foreach (var index in locations)
cities.Add(CreateCity(index, _random.Next(0, 10)));
var cities = CreateCities();
map.Metadata.SetProperty(CitiesProperty, cities);
}

View File

@ -16,6 +16,7 @@ namespace Assets.Cities
public List<(int, int)> Edges = new List<(int, int)>();
public Point Center { get; set; }
public float RangeOfInfluence { get; set; } = 0;
public City()
{
@ -26,6 +27,7 @@ namespace Assets.Cities
Sites = sites;
}
public void AddSite(MapSite site)
{
Sites.Add(site);

View File

@ -3,7 +3,7 @@ using Assets.Common;
namespace Assets.Cities
{
public enum CityFieldTypes
public enum FieldType
{
MainSquare,
Business,
@ -13,7 +13,7 @@ namespace Assets.Cities
public class CityField
{
public IList<Point> Boundary { get; set; } = new List<Point>();
public CityFieldTypes cityFieldType { get; set; }
public FieldType Type { get; set; }
public Point Center { get; set; }
}
}

View File

@ -37,6 +37,7 @@ namespace Assets
public bool displayCityFields = true;
[NonSerialized] public float generationTime = 0.0f;
public bool displayRangeOfInfluence = false;
}
[Serializable]
@ -60,13 +61,21 @@ namespace Assets
[Range(0f, 360f)]
public float minimumRoadAngle = 30f;
[Range(0f, 1f)]
public float businessCityFields = 0.3f;
[Range(0f, 4f)]
public float minimumNudgeDistance = 0.5f;
[Range(0f, 4f)]
public float maximumNudgeDistance = 1f;
[Range(0f, 4f)]
public float minimumRoadLength = 1f;
public float rangeOfInfluence = .5f;
[Range(0f, 1f)]
public float citiesSize = .5f;
[Range(0, 50)]
public int citiesCount = 20;
[Range(2.0f, 64.0f)]
public float radius = 8;
@ -109,13 +118,19 @@ namespace Assets
var generator = new MapGenerator(new VoronoiGridGenerator(seed, new PoissonDiskSampler(radius) { Generator = new Random(seed) }));
generator.AddAnnotationPass(new LandmassPass(types.Prepend(new LocationType { name = "Ocean", height = -1 }).Select(t => new Location { Type = t }), new Random(seed)));
generator.AddAnnotationPass(new LocateCitiesPass(new Random(seed)));
generator.AddAnnotationPass(new LocateCitiesPass(new Random(seed))
{
MaxCitiesCount = citiesCount,
RangeOfInfluence = rangeOfInfluence,
CitiesSize = citiesSize
});
generator.AddAnnotationPass(new CityFieldsPass(new Random(seed))
{
MinimumAngle = Mathf.Deg2Rad * minimumRoadAngle,
MaxNudgeDistance = maximumNudgeDistance,
MinNudgeDistance = minimumNudgeDistance,
MinimumRoadLength = minimumRoadLength
MinimumRoadLength = minimumRoadLength,
BusinessCityFields = businessCityFields
});
return generator;
@ -198,26 +213,26 @@ namespace Assets
Gizmos.DrawSphere(site.Center.ToVector3(), 2);
}
}
//
// if (debug.displayLocations && _locationGraph != null)
// {
// DisplayGraphEdges(_locationGraph.Morph(a => a.Item1));
// }
//
// if (debug.displayLocationPoints)
// {
// foreach (var location in _locations.Skip(1))
// {
// Gizmos.color = location.Type.color;
// foreach (var point in location.BoundaryPoints)
// {
// var v = VoronoiGenerator.Voronoi.Vertices[point].ToVector3();
// Gizmos.DrawSphere(v, 1);
// if (debug.displayLabels) Handles.Label(v + Vector3.right, $"{point} at {v.x:F2}, {v.y:f2}");
// }
//
// if (debug.displayLocations && _locationGraph != null)
// {
// DisplayGraphEdges(_locationGraph.Morph(a => a.Item1));
// }
//
// if (debug.displayLocationPoints)
// {
// foreach (var location in _locations.Skip(1))
// {
// Gizmos.color = location.Type.color;
// foreach (var point in location.BoundaryPoints)
// {
// var v = VoronoiGenerator.Voronoi.Vertices[point].ToVector3();
// Gizmos.DrawSphere(v, 1);
// if (debug.displayLabels) Handles.Label(v + Vector3.right, $"{point} at {v.x:F2}, {v.y:f2}");
// }
// }
// }
// }
// }
if (debug.displayLocationEdges)
{
@ -261,14 +276,39 @@ namespace Assets
}
}
if (debug.displayRangeOfInfluence)
{
foreach (var city in cities)
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(PointUtils.Mean(city.Sites.Select(s => s.Center)).ToVector3(), city.RangeOfInfluence);
Gizmos.DrawSphere(PointUtils.Mean(city.Sites.Select(s => s.Center)).ToVector3(), 1);
}
}
if (debug.displayCityFields)
{
Gizmos.color = Color.green;
Gizmos.color = Color.blue;
foreach (var city in cities)
{
foreach (var field in city.Fields)
{
switch (field.Type)
{
case FieldType.Business:
Gizmos.color = Color.green;
break;
case FieldType.Living:
Gizmos.color = Color.yellow;
break;
case FieldType.MainSquare:
Gizmos.color = Color.red;
break;
default:
Gizmos.color = Color.blue;
break;
}
foreach (var (a, b) in field.Boundary.RotateRight().Zip(field.Boundary, (a, b) => (a, b)))
Gizmos.DrawLine(a.ToVector3(), b.ToVector3());