private static int MinDistToMapEdge(PlanarGraph graph, Node n, int limit) { if (n.Coordinate.X == 0 || n.Coordinate.X == Size || n.Coordinate.Y == 0 || n.Coordinate.Y == Size) { return(0); } int ret = int.MaxValue; Stack <Tuple <int, Node> > stack = new Stack <Tuple <int, Node> >(); HashSet <Node> visited = new HashSet <Node>(); stack.Push(new Tuple <int, Node>(0, n)); do { Tuple <int, Node> state = stack.Pop(); if (state.Item2.Coordinate.X == 0 || state.Item2.Coordinate.X == Size || state.Item2.Coordinate.Y == 0 || state.Item2.Coordinate.Y == Size) { if (state.Item1 < ret) { ret = state.Item1; } if (ret == 0) { return(0); } continue; } visited.Add(state.Item2); if (state.Item1 > limit) { continue; } foreach (EdgeEnd i in state.Item2.Edges) { Node node = graph.Find(i.DirectedCoordinate); if (!visited.Contains(node)) { stack.Push(new Tuple <int, Node>(state.Item1 + 1, node)); } } } while (stack.Count > 0); return(ret); }
public void Generate(int pointCount) { //Generate random points HashSet <Coordinate> hashSet = new HashSet <Coordinate>(); { Random rand = new Random(seed); while (hashSet.Count < pointCount) { double x = rand.NextDouble() * 2 - 1; double y = rand.NextDouble() * 2 - 1; if (x < -0.99 || y < -0.99 || x > 0.99 || y > 0.99) { continue; } hashSet.Add(new Coordinate(x, y)); } } //Optimize points { Coordinate[] points = hashSet.ToArray(); for (int i = 0; i < 2; i++) { VoronoiDiagramBuilder builder = new VoronoiDiagramBuilder(); builder.SetSites(points); VoronoiDiagram = builder.GetDiagram(new GeometryFactory()); for (int j = 0; j < points.Length; j++) { Polygon poly = VoronoiDiagram[j] as Polygon; points[j] = new Coordinate(poly.Centroid.X, poly.Centroid.Y); } } } //Build graph PlanarGraph graph; { VoronoiDiagram = ClipGeometryCollection(VoronoiDiagram, new Envelope(-1, 1, -1, 1)); graph = new PlanarGraph(new OverlayNodeFactory()); List <Edge> edges = new List <Edge>(); for (int i = 0; i < VoronoiDiagram.Count; i++) { Polygon poly = VoronoiDiagram[i] as Polygon; Coordinate[] coords = poly.Coordinates; for (int j = 1; j < coords.Length; j++) { edges.Add(new Edge(new[] { coords[j - 1], coords[j] }, new Label(Location.Boundary))); } } graph.AddEdges(edges); } //Convert graph Dictionary <Node, MapNode> nodeDict; { Dictionary <MapPolygon, HashSet <MapPolygon> > polys = new Dictionary <MapPolygon, HashSet <MapPolygon> >(); nodeDict = new Dictionary <Node, MapNode>(); Dictionary <MapNode, Tuple <HashSet <MapPolygon>, HashSet <MapEdge> > > dats = new Dictionary <MapNode, Tuple <HashSet <MapPolygon>, HashSet <MapEdge> > >(); for (int i = 0; i < VoronoiDiagram.Count; i++) { List <MapNode> nodes = new List <MapNode>(); MapPolygon poly = new MapPolygon { CentroidX = VoronoiDiagram[i].Centroid.X, CentroidY = VoronoiDiagram[i].Centroid.Y, Polygon = VoronoiDiagram[i] as Polygon }; foreach (Coordinate j in VoronoiDiagram[i].Coordinates.Skip(1)) { Node n = graph.Find(j); MapNode mapNode; if (!nodeDict.TryGetValue(n, out mapNode)) { mapNode = new MapNode { X = j.X, Y = j.Y }; dats[mapNode] = new Tuple <HashSet <MapPolygon>, HashSet <MapEdge> >(new HashSet <MapPolygon> { poly }, new HashSet <MapEdge>()); } else { dats[mapNode].Item1.Add(poly); } nodes.Add(nodeDict[n] = mapNode); } poly.Nodes = nodes.ToArray(); polys.Add(poly, new HashSet <MapPolygon>()); } foreach (KeyValuePair <Node, MapNode> i in nodeDict) { foreach (MapPolygon j in dats[i.Value].Item1) { foreach (MapPolygon k in dats[i.Value].Item1) { if (j != k) { polys[j].Add(k); polys[k].Add(j); } } } foreach (EdgeEnd j in i.Key.Edges) { MapNode from = nodeDict[graph.Find(j.Coordinate)]; MapNode to = nodeDict[graph.Find(j.DirectedCoordinate)]; dats[from].Item2.Add(new MapEdge { From = from, To = to }); } } int ftrh = dats.Count(_ => _.Value.Item2.Count == 0); foreach (KeyValuePair <MapNode, Tuple <HashSet <MapPolygon>, HashSet <MapEdge> > > i in dats) { i.Key.Edges = i.Value.Item2.ToArray(); } KeyValuePair <MapPolygon, HashSet <MapPolygon> >[] x = polys.ToArray(); for (int i = 0; i < x.Length; i++) { x[i].Key.Neighbour = x[i].Value.ToArray(); x[i].Key.Id = i; } Polygons = x.Select(_ => _.Key).ToArray(); } //Generate map DetermineLandmass(); FindOceans(); ComputeDistances(); RedistributeElevation(nodeDict.Values); FindLakesAndCoasts(); }