From b445fcb05c96eb5161175a9c237d704724ababb8 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Sat, 16 Nov 2019 22:23:14 +0100 Subject: [PATCH] naprawiono aretefakty lokacji --- Assets/Scripts/AnnotationPass/LandmassPass.cs | 38 ++++++++++++++----- Assets/Scripts/Common/CommonTags.cs | 11 ++++++ Assets/Scripts/Common/CommonTags.cs.meta | 3 ++ Assets/Scripts/Common/MapSite.cs | 3 +- .../GridGenerator/VoronoiGridGenerator.cs | 32 ++++++++++++++-- 5 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 Assets/Scripts/Common/CommonTags.cs create mode 100644 Assets/Scripts/Common/CommonTags.cs.meta diff --git a/Assets/Scripts/AnnotationPass/LandmassPass.cs b/Assets/Scripts/AnnotationPass/LandmassPass.cs index 05bd984..4802d62 100644 --- a/Assets/Scripts/AnnotationPass/LandmassPass.cs +++ b/Assets/Scripts/AnnotationPass/LandmassPass.cs @@ -2,6 +2,8 @@ using System; using System.Collections.Generic; using System.Linq; using Assets.Common; +using Assets.Voronoi; +using UnityEngine.UIElements; namespace Assets.AnnotationPass { @@ -27,16 +29,17 @@ namespace Assets.AnnotationPass private void Process(int vertex, Location location) { - location.AddSite(_sites.Vertices[vertex]); - - _sites.Vertices[vertex].Metadata.SetProperty(SiteLocationProperty, location); + SetLocation(_sites.Vertices[vertex], location); foreach (var neighbour in _sites.Neighbours(vertex)) { var site = _sites[neighbour]; - + if (!site.Metadata.HasProperty(SiteLocationProperty)) - _queue.Add((neighbour, location)); + { + if (location == _locations[0] || !site.Tags.Contains(CommonTags.Edge)) + _queue.Add((neighbour, location)); + } else if (location != site.Metadata.GetProperty(SiteLocationProperty)) _locations.AddEdge( _locations.Vertices.IndexOf(location), @@ -45,6 +48,13 @@ namespace Assets.AnnotationPass } } + private void SetLocation(MapSite site, Location location) + { + location.AddSite(site); + + site.Metadata.SetProperty(SiteLocationProperty, location); + } + private (int, Location) Dequeue() { while (_queue.Count > 0) @@ -113,21 +123,29 @@ namespace Assets.AnnotationPass _points = map.Boundaries.Vertices; map.Metadata.SetProperty(MapLocationsProperty, _locations); - + + var ocean = _locations[0]; + var possible = new Queue(map.Sites + .Vertices + .Select((site, i) => (Vertex: i, Site: site)) + .Where(tuple => !tuple.Site.Tags.Contains(CommonTags.Edge)) + .Select(tuple => tuple.Vertex) + .OrderBy(tuple => _random.Next())); + var initial = from location in _locations.Vertices.Skip(1) - select (_random.Next(map.Sites.Vertices.Count), location); + select (possible.Dequeue(), location); initial = initial.Concat( map.Sites.Vertices .Select((s, i) => (Site: s, Vertex: i)) - .Where(t => t.Site.IsOuter) - .Select(t => (t.Vertex, _locations[0])) + .Where(t => t.Site.Tags.Contains(CommonTags.Outer)) + .Select(t => (t.Vertex, ocean)) ); foreach (var (vertex, location) in initial) Process(vertex, location); - + while (_queue.Count != 0) Step(); } diff --git a/Assets/Scripts/Common/CommonTags.cs b/Assets/Scripts/Common/CommonTags.cs new file mode 100644 index 0000000..7630695 --- /dev/null +++ b/Assets/Scripts/Common/CommonTags.cs @@ -0,0 +1,11 @@ +namespace Assets.Common +{ + public static class CommonTags + { + public const string Outer = "Outer"; + public const string Empty = "Empty"; + public const string Land = "Land"; + public const string Water = "Water"; + public const string Edge = "Edge"; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Common/CommonTags.cs.meta b/Assets/Scripts/Common/CommonTags.cs.meta new file mode 100644 index 0000000..6b68d23 --- /dev/null +++ b/Assets/Scripts/Common/CommonTags.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1019713c428346a2a9c5e6f57b360d15 +timeCreated: 1573936282 \ No newline at end of file diff --git a/Assets/Scripts/Common/MapSite.cs b/Assets/Scripts/Common/MapSite.cs index c9057a7..70b6062 100644 --- a/Assets/Scripts/Common/MapSite.cs +++ b/Assets/Scripts/Common/MapSite.cs @@ -18,8 +18,7 @@ namespace Assets.Common public int Index { get; internal set; } public Point Center { get; set; } - public bool IsOuter { get; set; } = false; - public ISet Tags { get; set; } = new HashSet { "Empty" }; + public ISet Tags { get; set; } = new HashSet { CommonTags.Empty }; public IEnumerable Boundary { get; set; } public IEnumerable<(int, int)> Edges => Boundary.RotateRight().Zip(Boundary, (a, b) => (a, b)); diff --git a/Assets/Scripts/GridGenerator/VoronoiGridGenerator.cs b/Assets/Scripts/GridGenerator/VoronoiGridGenerator.cs index 7d7cce4..1353f8c 100644 --- a/Assets/Scripts/GridGenerator/VoronoiGridGenerator.cs +++ b/Assets/Scripts/GridGenerator/VoronoiGridGenerator.cs @@ -9,7 +9,7 @@ namespace Assets.GridGenerator public class VoronoiGridGenerator : IGridGenerator { public const string VoronoiSiteProperty = "VoronoiSite"; - + private readonly int _seed; private readonly IPointDistribution _sampler; @@ -27,23 +27,49 @@ namespace Assets.GridGenerator var generator = new VoronoiGenerator(points); generator.Generate(); + + bool IsOutside(Point point) => !(point.x > 0 && point.x < width && point.y > 0 && point.y < height); - result.Boundaries = (Graph)generator.Voronoi.Clone(); + result.Boundaries = generator.Voronoi.Clone() as Graph; result.Sites = generator.Delaunay.Morph(s => { var site = new MapSite(s.Point, ClockwiseVertices(generator.Voronoi, s.Vertices)); site.Metadata.SetProperty(VoronoiSiteProperty, s); + if (site.Boundary.Select(n => result.Boundaries[n]).Any(IsOutside)) + site.Tags.Add(CommonTags.Edge); + return site; }); foreach (var site in result.Sites.Vertices.Take(4)) - site.IsOuter = true; + site.Tags.Add(CommonTags.Outer); + FixTooLongEdges(result, width, height); + return result; } + private void FixTooLongEdges(Map map, double width, double height) + { + List<(int, int)> remove = new List<(int, int)>(); + + bool IsValid(Point point) => point.x > 0 && point.x < width && point.y > 0 && point.y < height; + + foreach (var (a, b) in map.Boundaries.Edges) + { + var pointA = map.Boundaries[a]; + var pointB = map.Boundaries[b]; + + if (!IsValid(pointA) || !IsValid(pointB)) + remove.Add((a, b)); + } + + foreach (var (a, b) in remove) + map.Boundaries.DeleteEdge(a, b); + } + private List GeneratePoints(double width, double height) { var points = new List