public static void SortSites(List <Site> sites) { sites.Sort(delegate(Site s0, Site s1) { int returnValue = Voronoi.CompareByYThenX(s0, s1); int tempIndex; if (returnValue == -1) { if (s0.siteIndex > s1.SiteIndex) { tempIndex = s0.SiteIndex; s0.SiteIndex = s1.SiteIndex; s1.SiteIndex = tempIndex; } } else if (returnValue == 1) { if (s1.SiteIndex > s0.SiteIndex) { tempIndex = s1.SiteIndex; s1.SiteIndex = s0.SiteIndex; s0.SiteIndex = tempIndex; } } return(returnValue); }); }
public int CompareTo(Site s1) { int returnValue = Voronoi.CompareByYThenX(this, s1); int tempIndex; if (returnValue == -1) { if (this.siteIndex > s1.SiteIndex) { tempIndex = this.SiteIndex; this.SiteIndex = s1.SiteIndex; s1.SiteIndex = tempIndex; } } else if (returnValue == 1) { if (s1.SiteIndex > this.SiteIndex) { tempIndex = s1.SiteIndex; s1.SiteIndex = this.SiteIndex; this.SiteIndex = tempIndex; } } return(returnValue); }
public int CompareTo(object obj) { Site site = (Site)obj; int num = Voronoi.CompareByYThenX(this, site); switch (num) { case -1: if (_siteIndex > site._siteIndex) { uint siteIndex = _siteIndex; _siteIndex = site._siteIndex; site._siteIndex = siteIndex; } break; case 1: if (site._siteIndex > _siteIndex) { uint siteIndex = site._siteIndex; site._siteIndex = _siteIndex; _siteIndex = siteIndex; } break; } return(num); }
void CreateDelauneyAndTree() { mainRoomPoints = new Vector2[mainRooms.Count]; for (int i = 0; i < mainRooms.Count; i++) { mainRoomPoints[i] = mainRooms [i].transform.position; } List <uint> colors = new List <uint> (); foreach (Vector2 point in mainRoomPoints) { colors.Add(0); } Delaunay.Voronoi v = new Delaunay.Voronoi(mainRoomPoints.ToList(), colors, new Rect(0, 0, 100, 50)); m_delaunayTriangulation = v.DelaunayTriangulation(); m_spanningTree = v.SpanningTree(KruskalType.MINIMUM); corridors = m_spanningTree; for (int i = 0; i < m_delaunayTriangulation.Count; i++) { if (Random.value < level.chanceToAddExtraCorridor) { corridors.Add(m_delaunayTriangulation[i]); } } }
void Init(Func<Vector2, bool> checkIsland, IEnumerable<Vector2> points, Voronoi voronoi, int width, int height, float lakeThreshold) { Width = width; Height = height; inside = checkIsland; BuildGraph(points, voronoi); AssignCornerElevations(); AssignOceanCoastAndLand(lakeThreshold); RedistributeElevations(); AssignPolygonElevations(); // Determine downslope paths. CalculateDownslopes(); // Determine watersheds: for every corner, where does it flow // out into the ocean? CalculateWatersheds(); // Create rivers. CreateRivers(); // Determine moisture at corners, starting at rivers // and lakes, but not oceans. Then redistribute // moisture to cover the entire range evenly from 0.0 // to 1.0. Then assign polygon moisture as the average // of the corner moisture. AssignCornerMoisture(); RedistributeMoisture(); AssignPolygonMoisture(); centers.ForEach(p => p.biome = GetBiome(p)); }
void RunDelaunay() { Delaunay.Voronoi voronoi = new Delaunay.Voronoi(delaunay_all_qbits_posXZ_weighted, colors, new Rect(0, 0, floorWidth, floorHeight)); delaunayTriangulation = voronoi.DelaunayTriangulation(); triangles = voronoi.Triangles(); convexHull = voronoi.Hull(); }
private void setUpVoronoi() { /* Create road graph */ List <uint> colors = new List <uint>(); for (int i = 0; i < roadPoints.Count; i++) { colors.Add((uint)0); } v = new Delaunay.Voronoi(roadPoints, colors, new Rect(0, 0, Config.WIDTH, Config.HEIGHT)); List <LineSegment> m_edges = v.VoronoiDiagram(); normalizedEdges = new List <LineSegment>(); for (int i = 0; i < m_edges.Count; i++) { Vector2 p0 = (Vector2)m_edges[i].p0; Vector2 p1 = (Vector2)m_edges[i].p1; p0.x = Mathf.Round(p0.x); p0.y = Mathf.Round(p0.y); p1.x = Mathf.Round(p1.x); p1.y = Mathf.Round(p1.y); normalizedEdges.Add(new LineSegment(p0, p1)); } graph = new Graph(normalizedEdges); }
/** * sort sites on y, then x, coord * also change each site's _siteIndex to match its new position in the list * so the _siteIndex can be used to identify the site for nearest-neighbor queries * * haha "also" - means more than one responsibility... * */ public int CompareTo(System.Object obj) // XXX: Really, really worried about this because it depends on how sorting works in AS3 impl - Julian { Site s2 = (Site)obj; int returnValue = Voronoi.CompareByYThenX(this, s2); // swap _siteIndex values if necessary to match new ordering: uint tempIndex; if (returnValue == -1) { if (this._siteIndex > s2._siteIndex) { tempIndex = this._siteIndex; this._siteIndex = s2._siteIndex; s2._siteIndex = tempIndex; } } else if (returnValue == 1) { if (s2._siteIndex > this._siteIndex) { tempIndex = s2._siteIndex; s2._siteIndex = this._siteIndex; this._siteIndex = tempIndex; } } return(returnValue); }
public Dictionary <Vector2, List <Vector2> > GenDelaunay() { Dictionary <Vector2, List <Vector2> > points = new Dictionary <Vector2, List <Vector2> >(); int m_pointCount = 20; List <Vector2> m_points; float m_mapWidth = 25; float m_mapHeight = 12; List <LineSegment> m_edges = null; List <LineSegment> m_spanningTree; List <LineSegment> m_delaunayTriangulation; List <uint> colors = new List <uint>(); m_points = new List <Vector2>(); for (int i = 0; i < m_pointCount; i++) { colors.Add(0); m_points.Add(new Vector2( Random.Range(2f, m_mapWidth - 2f), Random.Range(2f, m_mapHeight)) ); } Delaunay.Voronoi v = new Delaunay.Voronoi(m_points, colors, new Rect(2f, 2f, m_mapWidth, m_mapHeight)); m_edges = v.VoronoiDiagram(); m_spanningTree = v.SpanningTree(KruskalType.MINIMUM); m_delaunayTriangulation = v.DelaunayTriangulation(); foreach (Vector2 coord in m_points) { points.Add(coord, v.NeighborSitesForSite(coord)); } return(points); }
/** * sort sites on y, then x, coord * also change each site's _siteIndex to match its new position in the list * so the _siteIndex can be used to identify the site for nearest-neighbor queries * * haha "also" - means more than one responsibility... * */ private static float Compare(Site s1, Site s2) { int returnValue = (int)Voronoi.CompareByYThenX(s1, s2); // swap _siteIndex values if necessary to match new ordering: int tempIndex; if (returnValue == -1) { if (s1._siteIndex > s2._siteIndex) { tempIndex = (int)s1._siteIndex; s1._siteIndex = s2._siteIndex; s2._siteIndex = (uint)tempIndex; } } else if (returnValue == 1) { if (s2._siteIndex > s1._siteIndex) { tempIndex = (int)s2._siteIndex; s2._siteIndex = s1._siteIndex; s1._siteIndex = (uint)tempIndex; } } return(returnValue); }
// take all the midpoints of the selected rooms and feed that into the Delaunay procedure // generate a graph, also it's good to have ID for rooms // and generate minimum spanning tree private void TriangulateMainRoomsMidpointsAndGenerateMST() { List <Vector2> midpoints = new List <Vector2>(); List <uint> colors = new List <uint>(); // Colors are just necessary part for choosen delaunay library Vector2 min = Vector2.positiveInfinity; Vector2 max = Vector2.zero; for (int i = 0; i < rooms.Count; i++) { DelaunayMSTRoom room = rooms[i]; if (room.isMainRoom) { colors.Add(0); midpoints.Add(new Vector2(room.x + room.width / 2, room.y + room.height / 2)); // use division (not multiplication) because we need INT value (or use RoundToInt) min.x = Mathf.Min(min.x, room.x); min.y = Mathf.Min(min.y, room.y); max.x = Mathf.Max(max.x, room.x); max.y = Mathf.Max(max.y, room.y); } } Delaunay.Voronoi voronoi = new Delaunay.Voronoi(midpoints, colors, new Rect(min.x, min.y, max.x, max.y)); delaunayLines = voronoi.DelaunayTriangulation(); // Triangulate main rooms spanningTree = voronoi.SpanningTree(Delaunay.KruskalType.MINIMUM); //Find min. span. tree if (settings.isDebugLogEnabled) { Debug.Log("Main passages count: " + spanningTree.Count); } }
/*! * \brief Construct a new Voronoi Diagram and generate all graphs * \param a_PointsList the points list which will be used to * as vertices to construct graphs * \param a_GenerateGraphs if graphes (voronoi graph, voronoi diagram, * MinST, MaxST, triangulation) has to be generated. * \param a_AllGraphs if we generate MaxST and triangulation */ public void Generate(List <Vector2> a_PointsList) { pointsList = a_PointsList; m_DelaunayVoronoy = constructVoronoy(a_PointsList); graph = m_DelaunayVoronoy.VoronoiDiagram(); }
private void GenerateEdges(List <Vector2> points) { List <LineSegment> minimumSpanningTree; List <LineSegment> delaunayTriangulation; List <LineSegment> finalEdges = new List <LineSegment>(); // Create the Voronoi diagram using the AS3 Delaunay library List <uint> colors = new List <uint> (); for (int i = 0; i < points.Count; i++) { colors.Add(0); } Delaunay.Voronoi voronoi = new Delaunay.Voronoi(points, colors, new Rect(0, 0, _mapWidth, _mapHeight)); minimumSpanningTree = voronoi.SpanningTree(KruskalType.MINIMUM); delaunayTriangulation = voronoi.DelaunayTriangulation(); // First add any line segment in the minimum spanning tree to the list _edges for (int i = delaunayTriangulation.Count - 1; i >= 0; i--) { for (int j = 0; j < minimumSpanningTree.Count; j++) { if (LineSegmentEquals(minimumSpanningTree[j], delaunayTriangulation[i])) { finalEdges.Add(delaunayTriangulation[i]); delaunayTriangulation.RemoveAt(i); break; } } } // Add a random amount of line segments in the delaunay triangulation but NOT in the minimum spanning tree to the list _edges for (int i = 0, count = delaunayTriangulation.Count; i < count; i++) { float rand = UnityEngine.Random.value; if (rand <= 0.35) { finalEdges.Add(delaunayTriangulation[i]); } } // Create the edges on the map // Also update neighbours properties on the nodes for (int i = 0, count = finalEdges.Count; i < count; i++) { LineSegment line = finalEdges[i]; Vector3 p0 = new Vector3(line.p0.Value.x, line.p0.Value.y, 0); Vector3 p1 = new Vector3(line.p1.Value.x, line.p1.Value.y, 0); MapEdge mapEdge = CreateMapEdge(p0, p1); mapEdge.Initialize(p0, p1); } }
public static IEnumerable <int> Triangulate(List <Vector2> points) { var triangulator = new Delaunay.Voronoi(points.ToList(), null, getBounds(points)); var lineSegments = triangulator.DelaunayTriangulation(); var edges = new HashSet <Tuple <int, int> >(lineSegments.Select(segment => new Tuple <int, int>(points.IndexOf(segment.p0.Value), points.IndexOf(segment.p1.Value)))); var neighbours = new Dictionary <int, HashSet <int> >(); foreach (var edge in edges) { if (!neighbours.ContainsKey(edge.Value1)) { neighbours[edge.Value1] = new HashSet <int>(); } neighbours[edge.Value1].Add(edge.Value2); if (!neighbours.ContainsKey(edge.Value2)) { neighbours[edge.Value2] = new HashSet <int>(); } neighbours[edge.Value2].Add(edge.Value1); } var foundTriangles = new HashSet <int>(); foreach (int p1 in neighbours.Keys) { foreach (int p2 in neighbours[p1]) { foreach (int p3 in neighbours[p1]) { if (p2 == p3) { continue; } if (!neighbours[p2].Contains(p3)) { continue; } var triangles = new int[] { p1, p2, p3 }.OrderBy(i => i).ToArray(); var intValue = triangles[0] + triangles[1] * points.Count + triangles[2] * points.Count + points.Count; if (foundTriangles.Contains(intValue)) { continue; } foundTriangles.Add(intValue); yield return(p1); yield return(p2); yield return(p3); } } } }
void Update() { List <uint> colors = new List <uint> (); for (int i = 0; i < PointTransforms.Count; i++) { colors.Add(0); } Delaunay.Voronoi v = new Delaunay.Voronoi(Points2, colors, new Rect(-mapWidth * 0.5f, -mapHeight * 0.5f, mapWidth, mapHeight)); edges = v.VoronoiDiagram(); }
public Graph(IEnumerable<Vector2> points, Voronoi voronoi, int width, int height) { Width = width; Height = height; BuildGraph(points, voronoi); //centers.ForEach(p => p.biome = GetBiome(p)); }
private void preview_Paint(object sender, PaintEventArgs e) { List<PointF> points = GetRandomPoints(); RectangleF size = new RectangleF(0, 0, preview.Width, preview.Height); Voronoi voronoi = new Voronoi(points, null, size); foreach (PointF point in points) { List<PointF> region = voronoi.Region(point); e.Graphics.DrawRectangle(Pens.Red, point.X, point.Y, 10, 10); e.Graphics.DrawLines(Pens.Black, region.ToArray()); } }
public static Vertex Intersect(Halfedge halfedge0, Halfedge halfedge1) { Edge edge = halfedge0.edge; Edge edge2 = halfedge1.edge; if (edge == null || edge2 == null) { return(null); } if (edge.rightSite == edge2.rightSite) { return(null); } float num = edge.a * edge2.b - edge.b * edge2.a; if (-1E-10 < (double)num && (double)num < 1E-10) { return(null); } float num2 = (edge.c * edge2.b - edge2.c * edge.b) / num; float y = (edge2.c * edge.a - edge.c * edge2.a) / num; Halfedge halfedge2; Edge edge3; if (Voronoi.CompareByYThenX(edge.rightSite, edge2.rightSite) < 0) { halfedge2 = halfedge0; edge3 = edge; } else { halfedge2 = halfedge1; edge3 = edge2; } bool flag = num2 >= edge3.rightSite.x; if (flag) { Side?leftRight = halfedge2.leftRight; if (leftRight.GetValueOrDefault() == Side.LEFT && leftRight.HasValue) { goto IL_0138; } } if (flag || halfedge2.leftRight != Side.RIGHT) { return(Create(num2, y)); } goto IL_0138; IL_0138: return(null); }
public void GenerateMap() { var startTime = DateTime.Now; var points = GetPoints(); var time = DateTime.Now; var voronoi = new Delaunay.Voronoi(points, null, new Rect(0, 0, meshSize, meshSize), relaxationIterations); //Debug.Log(string.Format("Voronoi Generated: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); time = DateTime.Now; heightMapSettings.noiseSettings.seed = seed; var heightMap = HeightMapGenerator.GenerateHeightMap(meshSize, meshSize, heightMapSettings, Vector2.zero); _heightMap = heightMap; //Debug.Log(string.Format("Heightmap Generated: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); time = DateTime.Now; var mapGraph = new MapGraph(voronoi, heightMap, snapDistance); _mapGraph = mapGraph; //Debug.Log(string.Format("Finished Generating Map Graph: {0:n0}ms with {1} nodes", DateTime.Now.Subtract(startTime).TotalMilliseconds, mapGraph.nodesByCenterPosition.Count)); time = DateTime.Now; MapGenerator.GenerateMap(mapGraph); //Debug.Log(string.Format("Map Generated: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); Vector3 born = MapGenerator.getBorn(); //Debug.Log(string.Format("Born: {0},{1},{2}", born.x,born.y,born.z)); if (previewType == PreviewType.HeightMap) { OnMeshDataReceived(MapMeshGenerator.GenerateMesh(mapGraph, heightMap, meshSize)); UpdateTexture(TextureGenerator.TextureFromHeightMap(heightMap)); } if (previewType == PreviewType.Map) { time = DateTime.Now; OnMeshDataReceived(MapMeshGenerator.GenerateMesh(mapGraph, heightMap, meshSize)); //Debug.Log(string.Format("Mesh Generated: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); time = DateTime.Now; var texture = MapTextureGenerator.GenerateTexture(mapGraph, meshSize, textureSize, colours, drawNodeBoundries, drawDelauneyTriangles, drawNodeCenters); //Debug.Log(string.Format("Texture Generated: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); UpdateTexture(texture); } Debug.Log(string.Format("Finished Generating World: {0:n0}ms with {1} nodes", DateTime.Now.Subtract(startTime).TotalMilliseconds, mapGraph.nodesByCenterPosition.Count)); }
private Voronoi GetVoronoi(int width, int height, int sitecount, int seed, int smoothingFactor) { var sw = new Stopwatch(); sw.Start(); var points = new List <Vector2>(); Random.seed = seed; for (int i = 0; i < sitecount; i++) { points.Add(new Vector2( Random.Range(0f, width), Random.Range(0f, height)) ); } var v = new Voronoi(points, null, new Rect(0, 0, width, height)); for (int i = 0; i < smoothingFactor; i++) { points = new List <Vector2>(); foreach (var site in v.Sites()) { //brnkhy - voices are telling me that, this should use circumference, not average var sum = Vector2.zero; var count = 0; foreach (var r in site.edges) { if (r.leftVertex != null) { sum += r.leftVertex.Coord; } if (r.rightVertex != null) { sum += r.rightVertex.Coord; } count += 2; } points.Add(sum / count); } v = new Voronoi(points, null, new Rect(0, 0, width, height)); } sw.Stop(); Debug.Log(string.Format("Voronoi generation took [{0}] milisecs with {1} smoothing iterations", sw.ElapsedMilliseconds, smoothingFactor)); return(v); }
public static IEnumerable <Vector2> RelaxPoints(IEnumerable <Vector2> startingPoints, float width, float height) { Delaunay.Voronoi v = new Delaunay.Voronoi(startingPoints.ToList(), null, new Rect(0, 0, width, height)); foreach (var point in startingPoints) { var region = v.Region(point); point.Set(0, 0); foreach (var r in region) { point.Set(point.x + r.x, point.y + r.y); } point.Set(point.x / region.Count, point.y / region.Count); yield return(point); } }
/** * This is the only way to make a Vertex * * @param halfedge0 * @param halfedge1 * @return * */ public static Vertex Intersect(Halfedge halfedge0, Halfedge halfedge1) { Edge edge0, edge1, edge; Halfedge halfedge; float determinant, intersectionX, intersectionY; bool rightOfSite; edge0 = halfedge0.edge; edge1 = halfedge1.edge; if (edge0 == null || edge1 == null) { return(null); } if (edge0.rightSite == edge1.rightSite) { return(null); } determinant = edge0.a * edge1.b - edge0.b * edge1.a; if (-1.0e-10 < determinant && determinant < 1.0e-10) { // the edges are parallel return(null); } intersectionX = (edge0.c * edge1.b - edge1.c * edge0.b) / determinant; intersectionY = (edge1.c * edge0.a - edge0.c * edge1.a) / determinant; if (Voronoi.CompareByYThenX(edge0.rightSite, edge1.rightSite) < 0) { halfedge = halfedge0; edge = edge0; } else { halfedge = halfedge1; edge = edge1; } rightOfSite = intersectionX >= edge.rightSite.x; if ((rightOfSite && halfedge.leftRight == Side.LEFT) || (!rightOfSite && halfedge.leftRight == Side.RIGHT)) { return(null); } return(Vertex.Create(intersectionX, intersectionY)); }
public void GenerateMap() { var startTime = DateTime.Now; var points = GetPoints(); var time = DateTime.Now; var voronoi = new Delaunay.Voronoi(points, null, new Rect(0, 0, meshSize, meshSize)); Debug.Log(string.Format("Voronoi Generated: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); time = DateTime.Now; heightMapSettings.noiseSettings.seed = seed; var heightMap = HeightMapGenerator.GenerateHeightMap(meshSize, meshSize, heightMapSettings, Vector2.zero); Debug.Log(string.Format("Heightmap Generated: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); time = DateTime.Now; var mapGraph = new MapGraph(voronoi, heightMap, snapDistance); Debug.Log(string.Format("Finished Generating Map Graph: {0:n0}ms with {1} nodes", DateTime.Now.Subtract(time).TotalMilliseconds, mapGraph.nodesByCenterPosition.Count)); time = DateTime.Now; MapGenerator.GenerateMap(mapGraph); Debug.Log(string.Format("Map Generated: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); time = DateTime.Now; OnMeshDataReceived(MapMeshGenerator.GenerateMesh(mapGraph, meshSize)); Debug.Log(string.Format("Mesh Generated: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); time = DateTime.Now; var texture = MapTextureGenerator.GenerateTexture(mapGraph, meshSize, textureSize, colours, drawNodeBoundries, drawDelaunayTriangles); Debug.Log(string.Format("Texture Generated: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); UpdateTexture(texture); time = DateTime.Now; EnvironmentSpawner.Spawn(mapGraph, GameObject.Find("Environment").transform, environmentSettings, seed); Debug.Log(string.Format("Environment Spawned: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); time = DateTime.Now; AnimalSpawner.Spawn(mapGraph, GameObject.Find("Animals").transform, animalSettings, seed); Debug.Log(string.Format("Animals Spawned: {0:n0}ms", DateTime.Now.Subtract(time).TotalMilliseconds)); Debug.Log(string.Format("Finished Generating World: {0:n0}ms with {1} nodes", DateTime.Now.Subtract(startTime).TotalMilliseconds, mapGraph.nodesByCenterPosition.Count)); }
private void Edges(float[,] map, Color[] pixels) { m_points = new List <Vector2> (); List <uint> colors = new List <uint> (); GenerateCity(map, m_points); for (int i = 0; i < m_points.Count; i++) { colors.Add((uint)0); } Delaunay.Voronoi v = new Delaunay.Voronoi(m_points, colors, new Rect(0, 0, WIDTH, HEIGHT)); m_edges = v.VoronoiDiagram(); m_spanningTree = v.SpanningTree(KruskalType.MINIMUM); m_delaunayTriangulation = v.DelaunayTriangulation(); Color color = Color.red; /* Shows Voronoi diagram */ /*for (int i = 0; i < m_edges.Count; i++) { * LineSegment seg = m_edges [i]; * Vector2 left = (Vector2)seg.p0; * Vector2 right = (Vector2)seg.p1; * DrawLine (pixels,left, right,color); * }*/ /* Shows Delaunay triangulation */ for (int i = 0; i < m_edges.Count; i++) { LineSegment seg = m_edges [i]; Vector2 left = (Vector2)seg.p0; Vector2 right = (Vector2)seg.p1; //DrawLine (pixels,left, right,color); /*ChunkLOD prefabLOD = mapGen.terrainPrefab.GetComponent<ChunkLOD> (); * float chunkSize = prefabLOD.SIZE_W; * float terrainSize = mapGen.WIDTH; * float SIZE = WIDTH; * * float length = (right - left).magnitude * (terrainSize * chunkSize) / (float) SIZE; * float angle = Vector2.Angle (right - left, Vector2.right);*/ float scaleFactor = ChunkLOD.GLOBAL_WIDTH * ChunkLOD.SIZE_W / WIDTH; GameObject road = Instantiate(roadPrefab, new Vector3(scaleFactor * left.x, 0.2f, scaleFactor * left.y), Quaternion.identity); Road r = road.GetComponent <Road> (); r.SetMesh(scaleFactor * (right - left)); } }
private void VoronoiGeneration() { List <Vector2> points = new List <Vector2>(); List <uint> colors = new List <uint>(); for (int i = 0; i < primaryRooms.Count; i++) { points.Add(primaryRooms[i].center); colors.Add(0); } Delaunay.Voronoi v = new Delaunay.Voronoi(points, colors, new Rect(center, size)); edges = v.VoronoiDiagram(); spanningTree = v.SpanningTree(KruskalType.MINIMUM); delaunayTriangulation = v.DelaunayTriangulation(); }
private void Demo() { List <uint> colors = new List <uint>(); m_points = new List <Vector2>(); for (int i = 0; i < m_pointCount; i++) { colors.Add(0); m_points.Add(new Vector2( UnityEngine.Random.Range(0, m_mapWidth), UnityEngine.Random.Range(0, m_mapHeight)) ); } Delaunay.Voronoi v = new Delaunay.Voronoi(m_points, colors, new Rect(0, 0, m_mapWidth, m_mapHeight)); m_delaunayTriangulation = v.DelaunayTriangulation(); }
// Use this for initialization void Start() { m_points = new List <Vector2>(); var r = 10; for (int i = 0; i < r; i++) { createCircle(i); } Delaunay.Voronoi v = new Delaunay.Voronoi(m_points, colors, new Rect(0, 0, m_mapWidth, m_mapHeight)); m_edges = v.VoronoiDiagram(); //m_spanningTree = v.SpanningTree(KruskalType.MINIMUM); m_delaunayTriangulation = v.DelaunayTriangulation(); totalPasos = m_points.Count; InvokeRepeating("UpdateSteps", 1f, 0.01f); }
private void Demo() { List <uint> colors = new List <uint>(); m_points = new List <Vector2>(); for (int i = 0; i < m_pointCount; i++) { colors.Add(0); m_points.Add(new Vector2( UnityEngine.Random.Range(0, m_mapWidth), UnityEngine.Random.Range(0, m_mapHeight))); } Delaunay.Voronoi v = new Delaunay.Voronoi(m_points, colors, new Rect(0, 0, m_mapWidth, m_mapHeight)); m_edges = v.VoronoiDiagram(); m_spanningTree = v.SpanningTree(KruskalType.MINIMUM); m_delaunayTriangulation = v.DelaunayTriangulation(); }
private void Demo () { List<uint> colors = new List<uint> (); m_points = new List<Vector2> (); for (int i = 0; i < m_pointCount; i++) { colors.Add (0); m_points.Add (new Vector2 ( UnityEngine.Random.Range (0, m_mapWidth), UnityEngine.Random.Range (0, m_mapHeight)) ); } Delaunay.Voronoi v = new Delaunay.Voronoi (m_points, colors, new Rect (0, 0, m_mapWidth, m_mapHeight)); m_edges = v.VoronoiDiagram (); m_spanningTree = v.SpanningTree (KruskalType.MINIMUM); m_delaunayTriangulation = v.DelaunayTriangulation (); }
public Map() { List<uint> colors = new List<uint>(); var points = new List<Vector2>(); for (int i = 0; i < _pointCount; i++) { colors.Add(0); points.Add(new Vector2( UnityEngine.Random.Range(0, Width), UnityEngine.Random.Range(0, Height)) ); } for (int i = 0; i < NUM_LLOYD_RELAXATIONS; i++) points = Graph.RelaxPoints(points, Width, Height).ToList(); var voronoi = new Voronoi(points, colors, new Rect(0, 0, Width, Height)); Graph = new Graph(points, voronoi, (int)Width, (int)Height, _lakeThreshold); }
public void Init(Func<Vector2, bool> checkIsland = null) { List<uint> colors = new List<uint>(); var points = new List<Vector2>(); for (int i = 0; i < _pointCount; i++) { colors.Add(0); points.Add(new Vector2( UnityEngine.Random.Range(0, Width), UnityEngine.Random.Range(0, Height)) ); } for (int i = 0; i < NUM_LLOYD_RELAXATIONS; i++) points = Graph.RelaxPoints(points, Width, Height).ToList(); var voronoi = new Voronoi(points, colors, new Rect(0, 0, Width, Height)); checkIsland = checkIsland ?? IslandShape.makePerlin(); Graph = new Graph(checkIsland, points, voronoi, (int)Width, (int)Height, _lakeThreshold); }
// Use this for initialization void Start() { List <Vector2> vertices = new List <Vector2>(); vertices.Add(new Vector2(0.0f, 0.0f)); vertices.Add(new Vector2(1.0f, 0.0f)); vertices.Add(new Vector2(1.0f, -2.0f)); vertices.Add(new Vector2(1.0f, 1.0f)); List <uint> colors = new List <uint>(); colors.Add(0); colors.Add(0); colors.Add(0); colors.Add(0); Delaunay.Voronoi V = new Delaunay.Voronoi(vertices, colors, new Rect(-1, -1, 2, 2)); List <LineSegment> lines = V.DelaunayTriangulation(); for (int i = 0; i < lines.Count; i++) { Debug.Log(string.Format("{0}, {1}", lines[i].p0, lines[i].p1)); } }
public void Demo () /** Public so that the custom Inspector class can call it */ { List<uint> colors = new List<uint> (); m_points = new List<Vector2> (); for (int i = 0; i < numSitesToGenerate; i++) { colors.Add (0); m_points.Add (new Vector2 ( UnityEngine.Random.Range (0, m_mapWidth), UnityEngine.Random.Range (0, m_mapHeight)) ); } v = new Delaunay.Voronoi (m_points, colors, new Rect (0, 0, m_mapWidth, m_mapHeight)); m_edges = v.VoronoiDiagram (); m_spanningTree = v.SpanningTree (KruskalType.MINIMUM); m_delaunayTriangulation = v.DelaunayTriangulation (); Debug.Log ("Created a Voronoi object. But for Unity, it's recommend you convert it to a VoronoiMap (data structure using Unity GameObjects and MonoBehaviours)"); //Example: VoronoiDiagram map = VoronoiDiagram.CreateDiagramFromVoronoiOutput( v, true ); }
public void generateMap(Config conf) { Random.InitState(conf.seed); var points = PointsGenerator.getPoints(conf); var voronoi = new Delaunay.Voronoi(points, null, new Rect(0, 0, conf.meshSize, conf.meshSize), conf.relaxationIterations); var elevationMap = ElevationMapGenerator.generate(conf); var mapGraph = new MapGraph(voronoi, elevationMap); BiomeMapGenerator.generate(mapGraph, conf); updateMesh(MapMeshGenerator.generate(mapGraph, meshSize)); updateTexture(MapTextureGenerator.generate(mapGraph, conf)); EvaluationResults evaluation = Evaluation.assessmentResultsToString(mapGraph, conf); beachFunction = evaluation.beachFunction; mountainFunction = evaluation.mountainFunction; lowlandFunction = evaluation.lowlandFunction; Debug.Log(evaluation.result); }
public void Demo() /** Public so that the custom Inspector class can call it */ { List <uint> colors = new List <uint> (); m_points = new List <Vector2> (); for (int i = 0; i < numSitesToGenerate; i++) { colors.Add(0); m_points.Add(new Vector2( UnityEngine.Random.Range(0, m_mapWidth), UnityEngine.Random.Range(0, m_mapHeight)) ); } v = new Delaunay.Voronoi(m_points, colors, new Rect(0, 0, m_mapWidth, m_mapHeight)); m_edges = v.VoronoiDiagram(); m_spanningTree = v.SpanningTree(KruskalType.MINIMUM); m_delaunayTriangulation = v.DelaunayTriangulation(); Debug.Log("Created a Voronoi object. But for Unity, it's recommend you convert it to a VoronoiMap (data structure using Unity GameObjects and MonoBehaviours)"); //Example: VoronoiDiagram map = VoronoiDiagram.CreateDiagramFromVoronoiOutput(v, true); }
public static IEnumerable<Vector2> RelaxPoints(IEnumerable<Vector2> startingPoints, float width, float height) { Delaunay.Voronoi v = new Delaunay.Voronoi(startingPoints.ToList(), null, new Rect(0, 0, width, height)); foreach (var point in startingPoints) { var region = v.Region(point); point.Set(0, 0); foreach (var r in region) point.Set(point.x + r.x, point.y + r.y); point.Set(point.x / region.Count, point.y / region.Count); yield return point; } }
/** Useful when experimenting and you create too much for Gizmos to render, and CPU goes nuts and dies */ public void DeleteAllData () { v = null; }
public static List <GameObject> GenerateTriangularPieces(GameObject source, int extraPoints = 0, int subshatterSteps = 0, Material mat = null) { List <GameObject> pieces = new List <GameObject>(); if (mat == null) { mat = createFragmentMaterial(source); } //get transform information Vector3 origScale = source.transform.localScale; source.transform.localScale = Vector3.one; Quaternion origRotation = source.transform.localRotation; source.transform.localRotation = Quaternion.identity; //get rigidbody information Rigidbody2D rg = source.GetComponent <Rigidbody2D>(); //Я добавил Vector2 origVelocity = rg.velocity; //get collider information PolygonCollider2D sourcePolyCollider = source.GetComponent <PolygonCollider2D>(); BoxCollider2D sourceBoxCollider = source.GetComponent <BoxCollider2D>(); List <Vector2> points = new List <Vector2>(); List <Vector2> borderPoints = new List <Vector2>(); //add points from the present collider if (sourcePolyCollider != null) { points = getPoints(sourcePolyCollider); borderPoints = getPoints(sourcePolyCollider); } else if (sourceBoxCollider != null) { points = getPoints(sourceBoxCollider); borderPoints = getPoints(sourceBoxCollider); } //create a bounding rectangle based on the polygon points Rect rect = getRect(source); //if the target polygon is a triangle, generate a point in the middle to allow for fracture if (points.Count == 3) { points.Add((points[0] + points[1] + points[2]) / 3); } for (int i = 0; i < extraPoints; i++) { points.Add(new Vector2(Random.Range(rect.width / -2, rect.width / 2), Random.Range(rect.height / -2, rect.height / 2))); } Voronoi voronoi = new Delaunay.Voronoi(points, null, rect); List <List <Vector2> > clippedTriangles = new List <List <Vector2> >(); foreach (Triangle tri in voronoi.Triangles()) { clippedTriangles = ClipperHelper.clip(borderPoints, tri); foreach (List <Vector2> triangle in clippedTriangles) { pieces.Add(generateTriangularPiece(source, triangle, origVelocity, origScale, origRotation, mat, rg)); } } List <GameObject> morePieces = new List <GameObject>(); if (subshatterSteps > 0) { subshatterSteps--; foreach (GameObject piece in pieces) { morePieces.AddRange(SpriteExploder.GenerateTriangularPieces(piece, extraPoints, subshatterSteps, mat)); GameObject.DestroyImmediate(piece); } } else { morePieces = pieces; } //reset transform information source.transform.localScale = origScale; source.transform.localRotation = origRotation; Resources.UnloadUnusedAssets(); return(morePieces); }
public static List <GameObject> GenerateVoronoiPieces(GameObject source, int extraPoints = 0, int subshatterSteps = 0, Material mat = null) { List <GameObject> pieces = new List <GameObject>(); if (mat == null) { mat = createFragmentMaterial(source); } //get transform information Vector3 origScale = source.transform.localScale; source.transform.localScale = Vector3.one; Quaternion origRotation = source.transform.localRotation; source.transform.localRotation = Quaternion.identity; //get rigidbody information Rigidbody2D rigbody = source.GetComponent <Rigidbody2D>(); //Я добавил Vector2 origVelocity = rigbody.velocity; //get collider information PolygonCollider2D sourcePolyCollider = source.GetComponent <PolygonCollider2D>(); BoxCollider2D sourceBoxCollider = source.GetComponent <BoxCollider2D>(); List <Vector2> points = new List <Vector2>(); List <Vector2> borderPoints = new List <Vector2>(); if (sourcePolyCollider != null) { points = getPoints(sourcePolyCollider); borderPoints = getPoints(sourcePolyCollider); } else if (sourceBoxCollider != null) { points = getPoints(sourceBoxCollider); borderPoints = getPoints(sourceBoxCollider); } Rect rect = getRect(source); for (int i = 0; i < extraPoints; i++) { points.Add(new Vector2(Random.Range(rect.width / -2, rect.width / 2), Random.Range(rect.height / -2, rect.height / 2))); } Voronoi voronoi = new Delaunay.Voronoi(points, null, rect); List <List <Vector2> > clippedRegions = new List <List <Vector2> >(); foreach (List <Vector2> region in voronoi.Regions()) { clippedRegions = ClipperHelper.clip(borderPoints, region); foreach (List <Vector2> clippedRegion in clippedRegions) { pieces.Add(generateVoronoiPiece(source, clippedRegion, origVelocity, origScale, origRotation, mat, rigbody)); } } List <GameObject> morePieces = new List <GameObject>(); if (subshatterSteps > 0) { subshatterSteps--; foreach (GameObject piece in pieces) { morePieces.AddRange(SpriteExploder.GenerateVoronoiPieces(piece, extraPoints, subshatterSteps)); GameObject.DestroyImmediate(piece); } } else { morePieces = pieces; } //reset transform information source.transform.localScale = origScale; source.transform.localRotation = origRotation; Resources.UnloadUnusedAssets(); return(morePieces); }
public static List<GameObject> GenerateTriangularPieces(GameObject source, int extraPoints = 0, int subshatterSteps = 0, Material mat = null) { List<GameObject> pieces = new List<GameObject>(); if (mat == null) { mat = createFragmentMaterial(source); } //get transform information Vector3 origScale = source.transform.localScale; source.transform.localScale = Vector3.one; Quaternion origRotation = source.transform.localRotation; source.transform.localRotation = Quaternion.identity; //get rigidbody information Vector2 origVelocity = source.GetComponent<Rigidbody2D>().velocity; //get collider information PolygonCollider2D sourcePolyCollider = source.GetComponent<PolygonCollider2D>(); BoxCollider2D sourceBoxCollider = source.GetComponent<BoxCollider2D>(); List<Vector2> points = new List<Vector2>(); List<Vector2> borderPoints = new List<Vector2>(); //add points from the present collider if (sourcePolyCollider != null) { points = getPoints(sourcePolyCollider); borderPoints = getPoints(sourcePolyCollider); } else if (sourceBoxCollider != null) { points = getPoints(sourceBoxCollider); borderPoints = getPoints(sourceBoxCollider); } //create a bounding rectangle based on the polygon points Rect rect = getRect(source); //if the target polygon is a triangle, generate a point in the middle to allow for fracture if (points.Count == 3) { points.Add((points[0] + points[1] + points[2]) / 3); } for (int i = 0; i < extraPoints; i++) { points.Add(new Vector2(Random.Range(rect.width / -2, rect.width / 2), Random.Range(rect.height / -2 + rect.center.y, rect.height / 2 + rect.center.y))); } Voronoi voronoi = new Delaunay.Voronoi(points, null, rect); List<List<Vector2>> clippedTriangles = new List<List<Vector2>>(); foreach (Triangle tri in voronoi.Triangles()) { clippedTriangles = ClipperHelper.clip(borderPoints, tri); foreach (List<Vector2> triangle in clippedTriangles) { pieces.Add(generateTriangularPiece(source, triangle, origVelocity, origScale, origRotation, mat)); } } List<GameObject> morePieces = new List<GameObject>(); if (subshatterSteps > 0) { subshatterSteps--; foreach (GameObject piece in pieces) { morePieces.AddRange(SpriteExploder.GenerateTriangularPieces(piece, extraPoints, subshatterSteps, mat)); GameObject.DestroyImmediate(piece); } } else { morePieces = pieces; } //reset transform information source.transform.localScale = origScale; source.transform.localRotation = origRotation; Resources.UnloadUnusedAssets(); return morePieces; }
public static List<GameObject> GenerateVoronoiPieces(GameObject source, int extraPoints = 0, int subshatterSteps = 0, Material mat = null) { List<GameObject> pieces = new List<GameObject>(); if (mat == null) { mat = createFragmentMaterial(source); } //get transform information Vector3 origScale = source.transform.localScale; source.transform.localScale = Vector3.one; Quaternion origRotation = source.transform.localRotation; source.transform.localRotation = Quaternion.identity; //get rigidbody information Vector2 origVelocity = source.GetComponent<Rigidbody2D>().velocity; //get collider information PolygonCollider2D sourcePolyCollider = source.GetComponent<PolygonCollider2D>(); BoxCollider2D sourceBoxCollider = source.GetComponent<BoxCollider2D>(); List<Vector2> points = new List<Vector2>(); List<Vector2> borderPoints = new List<Vector2>(); if (sourcePolyCollider != null) { points = getPoints(sourcePolyCollider); borderPoints = getPoints(sourcePolyCollider); } else if (sourceBoxCollider != null) { points = getPoints(sourceBoxCollider); borderPoints = getPoints(sourceBoxCollider); } Rect rect = getRect(source); for (int i = 0; i < extraPoints; i++) { points.Add(new Vector2(Random.Range( rect.width / -2 + rect.center.x, rect.width / 2 + rect.center.x), Random.Range(rect.height / -2 + rect.center.y, rect.height / 2 + rect.center.y) )); } Voronoi voronoi = new Delaunay.Voronoi(points, null, rect); List<List<Vector2>> clippedRegions = new List<List<Vector2>>(); foreach (List<Vector2> region in voronoi.Regions()) { clippedRegions = ClipperHelper.clip(borderPoints, region); foreach (List<Vector2> clippedRegion in clippedRegions) { pieces.Add(generateVoronoiPiece(source, clippedRegion, origVelocity, origScale, origRotation, mat)); } } List<GameObject> morePieces = new List<GameObject>(); if (subshatterSteps > 0) { subshatterSteps--; foreach (GameObject piece in pieces) { morePieces.AddRange(SpriteExploder.GenerateVoronoiPieces(piece, extraPoints, subshatterSteps)); GameObject.DestroyImmediate(piece); } } else { morePieces = pieces; } //reset transform information source.transform.localScale = origScale; source.transform.localRotation = origRotation; Resources.UnloadUnusedAssets(); return morePieces; }
private void DelaunayTriangulation() { List<Vector2> points = new List<Vector2>(); foreach (Room r in mainRooms) { points.Add(r.center); } voronoi = new Delaunay.Voronoi(points, null, new Rect(0, 0, mapRect.width, mapRect.height)); delaunayTriangulation = voronoi.DelaunayTriangulation(); }
public Graph(IEnumerable<Vector2> points, Voronoi voronoi, int width, int height, float lakeThreshold) { Init(IslandShape.makePerlin(), points, voronoi, width, height, lakeThreshold); }
/** Stupidly, Unity in 2D mode uses co-ords incompatible with Unity in 3D mode (xy instead of xz). So we have to provide a boolean to switch between the two modes! */ public static VoronoiDiagram CreateDiagramFromVoronoiOutput(Voronoi voronoiGenerator, bool useUnity2DCoordsNot3D ) { GameObject go = new GameObject("New VoronoiMap"); GameObject goCellHolder = new GameObject(_cellHolderName); goCellHolder.transform.parent = go.transform; GameObject goEdgeHolder = new GameObject(_edgeHolderName); goEdgeHolder.transform.parent = go.transform; GameObject goVertexHolder = new GameObject(_vertexHolderName); goVertexHolder.transform.parent = go.transform; VoronoiDiagram map = go.AddComponent<VoronoiDiagram>(); System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); Dictionary<Site,VoronoiCell> generatedCells = new Dictionary<Site, VoronoiCell>(); Dictionary<Vector2,VoronoiCellVertex> generatedVertices = new Dictionary<Vector2, VoronoiCellVertex>(); int numEdgesCreated = 0; foreach (Edge edge in voronoiGenerator.Edges()) { GameObject goEdge = new GameObject("Edge-#" + (numEdgesCreated++)); goEdge.transform.parent = goEdgeHolder.transform; VoronoiCellEdge vEdge = goEdge.AddComponent<VoronoiCellEdge>(); Debug.Log("Processing edge = "+edge+" with clippedEnds = "+(edge.clippedEnds==null?"null":""+edge.clippedEnds.Count) ); if( ! edge.visible) { Debug.Log("...Voronoi algorithm generated a non-existent edge, skipping it..."); continue; } Vector2 clippedEndLeft = (Vector2)edge.clippedEnds [Side.LEFT]; Vector2 clippedEndRight = (Vector2)edge.clippedEnds [Side.RIGHT]; vEdge.AddVertex(FetchVertexOrAddToObject( clippedEndLeft, generatedVertices, goVertexHolder, useUnity2DCoordsNot3D)); vEdge.AddVertex(FetchVertexOrAddToObject( clippedEndRight, generatedVertices, goVertexHolder, useUnity2DCoordsNot3D)); goEdge.transform.localPosition = (vEdge.edgeVertexA.transform.localPosition + vEdge.edgeVertexB.transform.localPosition ) / 2.0f; Site[] bothSites = new Site[] { edge.leftSite, edge.rightSite }; foreach (Site site in bothSites) { /** Re-use or create the Cell */ VoronoiCell newCell = null; // C# is rubbish. Crashes if Dictionary lacks the key. Very bad design. if (generatedCells.ContainsKey(site)) newCell = generatedCells [site]; GameObject goCell; if (newCell == null) { goCell = new GameObject("Cell-#" + generatedCells.Count); goCell.transform.parent = goCellHolder.transform; goCell.transform.localPosition = new Vector3( site.Coord.x, useUnity2DCoordsNot3D? site.Coord.y : 0, useUnity2DCoordsNot3D? 0 : site.Coord.y ); newCell = goCell.AddComponent<VoronoiCell>(); generatedCells.Add(site, newCell); } else { goCell = newCell.gameObject; } /** Now that cell is created, attach it to BOTH Vertex's on the new Edge (so that later its easy for us to to find Cells-for-this-Vertex, and also: for a Cell to "trace" around its edges, picking "next edge" from each Vertex by looking at which edges from the vertex border this cell (by checking that BOTH Vertex-ends of the edge are attached to this cell) Also add the edge itself to the cell, and the cell to the edge. */ vEdge.AddCellWithSideEffects(newCell); } } watch.Stop(); return map; }
public void createVoronoi(){ setPoints (); p_voronoi = new Delaunay.Voronoi (p_points, null, new Rect (0, 0, p_heightMapSize, p_heightMapSize)); createGraph (); }
public Graph(Func<Vector2, bool> checkIsland, IEnumerable<Vector2> points, Voronoi voronoi, int width, int height, float lakeThreshold) { Init(checkIsland, points, voronoi, width, height, lakeThreshold); }