void Triangulate() { List <Vector2> points = new List <Vector2>(); List <uint> colors = new List <uint>(); Vector2 min = Vector2.positiveInfinity; Vector2 max = Vector2.zero; foreach (GeneratorCell c in cells) { if (c.isMainRoom) { colors.Add(0); points.Add(new Vector2(c.posX + (c.width / 2), c.posY + (c.height / 2))); min.x = Mathf.Min(c.posX, min.x); min.y = Mathf.Min(c.posY, min.y); max.x = Mathf.Max(c.posX, max.x); max.y = Mathf.Max(c.posY, max.y); } } Voronoi v = new Voronoi(points, colors, new Rect(min.x, min.y, max.x, max.y)); delaunayLines = v.DelaunayTriangulation(); spanningTree = v.SpanningTree(KruskalType.MINIMUM); }
private void Demo() { GenerateSimplexPlane(); m_points = new List <Vector2>(); m_colors = new List <uint>(); for (int i = 0; i < m_pointCount; i++) { m_colors.Add(RandomUintColor()); 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, m_colors, new Rect (0, 0, m_mapWidth, m_mapHeight)); m_voronoi = new Delaunay.Voronoi(m_points, m_colors, new Rect(0, 0, m_mapWidth, m_mapHeight)); //m_edges = v.VoronoiDiagram(); m_edges = m_voronoi.VoronoiDiagram(); m_spanningTree = m_voronoi.SpanningTree(KruskalType.MINIMUM); m_delaunayTriangulation = m_voronoi.DelaunayTriangulation(); tmpVBoundary = m_voronoi.VoronoiBoundaryForSite(m_points[0]); //DrawVoronoiPolygon(m_points[0]); AssignSimplexColors(); }
void Calculate() { List <uint> colors = new List <uint>(); MainRooms = new Dictionary <Vector2, Room>(); //Get a point list of all our main rooms for (int n = 0; n < Rooms.Count; n++) { if (Rooms[n].IsMainRoom) { Points.Add(Rooms[n].Center); colors.Add(0); if (!MainRooms.ContainsKey(Rooms[n].Center)) { MainRooms.Add(Rooms[n].Center, Rooms[n]); } } } //Calculate min spanning tree Voronoi v = new Voronoi(Points, colors, new Rect(0, 0, 50, 50)); SpanningTree = v.SpanningTree(KruskalType.MINIMUM); DelaunayTriangulation = v.DelaunayTriangulation(); //Add room connections GenerateSpanningTree(true); ProcessRoomConnections(false); SetStartAndEndRooms(); //Calculate boundaries XMin = float.MaxValue; YMin = float.MaxValue; XMax = float.MinValue; YMax = float.MinValue; for (int n = 0; n < Rooms.Count; n++) { if (Rooms[n].IsVisible) { XMin = Mathf.Min(XMin, Rooms[n].TopLeft.x); XMax = Mathf.Max(XMax, Rooms[n].BottomRight.x); YMin = Mathf.Min(YMin, Rooms[n].BottomRight.y); YMax = Mathf.Max(YMax, Rooms[n].TopLeft.y); } } OnRoomsGenerated(); }
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(2, m_mapWidth - 2), UnityEngine.Random.Range(2, m_mapHeight - 2)) ); } 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(); m_regions = v.Regions(); // m_test = v.VoronoiBoundaryForSite(m_points[0]); // m_vector2 = v.HullPointsInOrder(); // m_test = v.HullEdgesTest(); m_test = v.Hull(); // render(); generateData(); renderMapData(); // var p = m_points[0]; // var list_point = v.VoronoiBoundaryForSite(p); // foreach (var lineSegment in list_point) // { // Debug.Log($"({lineSegment.p0.Value.x},{lineSegment.p0.Value.y})({lineSegment.p1.Value.x},{lineSegment.p1.Value.y})"); // } // // var center = getMapCenter(p); // var list_vec = center.edges; // foreach (var mapEdge in list_vec) // { // Debug.Log($"e({mapEdge.p0.x},{mapEdge.p0.y})({mapEdge.p1.x},{mapEdge.p1.y})"); // // } // // var list_p =sortBound(list_vec); // foreach (var vector2 in list_p) // { // Debug.Log(vector2); // } }
private void Button_Click(object sender, RoutedEventArgs ea) { Random rand = new Random(); List <Point> points = new List <Point>(); for (int i = 0; i < 60; i++) { points.Add(new Point((float)(rand.NextDouble() * brect.ActualWidth), (rand.NextDouble() * brect.ActualHeight))); } Voronoi v = new Voronoi(points, colors, new Rect(0, 0, brect.ActualWidth, brect.ActualHeight)); using (var r = Dots.RenderOpen()) { foreach (var p in points) { r.DrawEllipse(Brushes.Teal, null, p, 3, 3); } } using (var r = Edges.RenderOpen()) { foreach (var l in v.VoronoiDiagram()) { r.DrawLine(new Pen(Brushes.Black, 1), l.p0.Value, l.p1.Value); } foreach (var l in v.DelaunayTriangulation()) { r.DrawLine(new Pen(Brushes.Azure, 1), l.p0.Value, l.p1.Value); } } using (var r = Colors.RenderOpen()) { int indx = 0; foreach (var l in v.Regions()) { StreamGeometry poly = new StreamGeometry(); using (var g = poly.Open()) { g.BeginFigure(l[0], true, true); g.PolyLineTo(l.Select(p => (Point)p).ToList(), false, false); } r.DrawGeometry(new SolidColorBrush(colors[indx % colors.Count]), null, poly); indx++; } } }
void GenerateDiagram() { voronoi = new Voronoi(map_points, new Rect(0, 0, mapWidth, mapHeight), relaxations); map_edges = voronoi.VoronoiDiagram(); if (relaxations > 0) { map_points = voronoi.SiteCoordinates(); } //map_spanningTree = voronoi.SpanningTree(KruskalType.MINIMUM); map_delaunayTriangulation = voronoi.DelaunayTriangulation(); }
private void TriangulateAndBuildTree() { List <uint> colors = new List <uint>(); List <Vector2> points = new List <Vector2>(); roomConnectionTree = new List <LineSegment>(); delaunayTriangulation = new List <LineSegment>(); connectionDictionary = new Dictionary <Vector2, Room>(); foreach (Room room in dungeonGenerator.dungeonRooms) { connectionDictionary.Add(room.GetCenter(), room); points.Add(room.GetCenter()); colors.Add(0); } Voronoi voroni = new Voronoi(points, colors, new Rect(0, 0, 50, 50)); roomConnectionTree = voroni.SpanningTree(KruskalType.MINIMUM); delaunayTriangulation = voroni.DelaunayTriangulation(); }
void GenerateTriangles() { var colors = new List <uint>(); for (int i = 0; i < points.Count; ++i) { colors.Add(0); } var rect = new Rect(0, 0, graph.size.x, graph.size.y); Voronoi v = new Voronoi(points, colors, rect); var delaunayTriangulation = v.DelaunayTriangulation(); var resolver = new TriangleResolver(graph.size); for (int i = 0; i < delaunayTriangulation.Count; ++i) { var p0 = (Vector2)delaunayTriangulation[i].p0; var p1 = (Vector2)delaunayTriangulation[i].p1; resolver.AddEdge(p0, p1); } resolver.Resolve(); triangles = resolver.Triangles; }
IEnumerator Create() { #region Create Random Size & Pos Rooms int counter = 0; int roomAmount = 25; int widthSum = 0; int heightSum = 0; while (counter < roomAmount) { Room room = CreateRandRoom(); room.name = counter.ToString(); rooms.Add(room); counter++; // sum width/height widthSum += room.Width; heightSum += room.Height; yield return(new WaitForSeconds(0.05f)); } #endregion #region Remove Small Rooms float widthMean = widthSum / roomAmount; float heightMean = heightSum / roomAmount; yield return(new WaitForSeconds(4)); for (int i = 0; i < rooms.Count; i++) { //rooms[i].RemovePhysics(); rooms [i].ResetRect(); if (rooms [i].Width < widthMean || rooms [i].Height < heightMean) { Destroy(rooms [i].gameObject); rooms.Remove(rooms [i]); i--; } } yield return(new WaitForSeconds(0.5f)); #endregion #region Create room connection using DelaunayTriangles _points = new List <Vector2> (); for (int i = 0; i < rooms.Count; i++) { _points.Add(rooms [i].Position); } Rect rect = GetMinRect(rooms); Voronoi v = new Voronoi(_points, null, rect); _edges = v.VoronoiDiagram(); _spanningTree = v.SpanningTree(KruskalType.MINIMUM); _delaunayTriangulation = v.DelaunayTriangulation(); #endregion #region Extra Loop Connection int maxExtraPathAmt = (int)(_delaunayTriangulation.Count * 0.1f); int rand = Random.Range(1, maxExtraPathAmt); Debug.Log(rand); while (rand > 0) { int randIndex = Random.Range(0, _delaunayTriangulation.Count); if (_spanningTree.Contains(_delaunayTriangulation [randIndex])) { continue; } else { _spanningTree.Add(_delaunayTriangulation [randIndex]); rand--; } } yield return(new WaitForSeconds(0.5f)); #endregion #region Create HallWays for (int i = 0; i < _spanningTree.Count; i++) { yield return(new WaitForSeconds(0.2f)); Room room0 = GetRoomFromPos(_spanningTree [i].p0); Room room1 = GetRoomFromPos(_spanningTree [i].p1); Debug.Log("Creating Hallway Between " + room0.name + " " + room1.name); float xDistance = Mathf.Abs(room0.Position.x - room1.Position.x); float yDistance = Mathf.Abs(room0.Position.y - room1.Position.y); float xMidPointDistance = xDistance / 2; float yMidPointDistance = yDistance / 2; #region Close in X-Axis // mid x point is inside of both rects if (room0.Position.x + xMidPointDistance < room0.rectMaxX && // removed equal sign ==> 避免房间刚好快要重叠,防止做路径时麻烦,因为路径瓦片可能会刚好在网格线上 room1.Position.x + xMidPointDistance < room1.rectMaxX) { Vector2 startPoint = Vector2.zero; Vector2 endPoint = Vector2.zero; // room0 above room1 if (room0.Position.y >= room1.Position.y) { // room0 left to room1 if (room0.Position.x <= room1.Position.x) { startPoint.Set(room0.Position.x + xMidPointDistance, room0.rectMinY); endPoint.Set(room1.Position.x - xMidPointDistance, room1.rectMaxY); } // room1 left to room0 else if (room0.Position.x > room1.Position.x) { startPoint.Set(room0.Position.x - xMidPointDistance, room0.rectMinY); endPoint.Set(room1.Position.x + xMidPointDistance, room1.rectMaxY); } } // room1 above room0 else if (room0.Position.y < room1.Position.y) { // room0 left to room1 if (room0.Position.x <= room1.Position.x) { startPoint.Set(room0.Position.x + xMidPointDistance, room0.rectMaxY); endPoint.Set(room1.Position.x - xMidPointDistance, room1.rectMinY); } // room1 left to room0 else if (room0.Position.x > room1.Position.x) { startPoint.Set(room0.Position.x - xMidPointDistance, room0.rectMaxY); endPoint.Set(room1.Position.x + xMidPointDistance, room1.rectMinY); } } #endregion // create vertical line HallWay hallway = new HallWay(startPoint, endPoint, room0, room1); _hallways.Add(hallway); room0.AddHallWay(hallway); Debug.Log("##CloseXAxis created hallway from " + startPoint + " to " + endPoint + " between " + room0.name + " " + room1.name); } #region Close In Y-Axis // mid y point is inside of both rects else if (room0.Position.y + yMidPointDistance < room0.rectMaxY && room1.Position.y + yMidPointDistance < room1.rectMaxY) { Vector2 startPoint = Vector2.zero; Vector2 endPoint = Vector2.zero; // room0 above room1 if (room0.Position.y >= room1.Position.y) { // room0 left to room1 if (room0.Position.x <= room1.Position.x) { startPoint.Set(room0.rectMaxX, room0.Position.y - yMidPointDistance); endPoint.Set(room1.rectMinX, room1.Position.y + yMidPointDistance); } // room1 left to room0 else if (room0.Position.x > room1.Position.x) { startPoint.Set(room0.rectMinX, room0.Position.y - yMidPointDistance); endPoint.Set(room1.rectMaxX, room1.Position.y + yMidPointDistance); } } // room1 above room0 else if (room0.Position.y < room1.Position.y) { // room0 left to room1 if (room0.Position.x <= room1.Position.x) { startPoint.Set(room0.rectMaxX, room0.Position.y + yMidPointDistance); endPoint.Set(room1.rectMinX, room1.Position.y - yMidPointDistance); } // room1 left to room0 else if (room0.Position.x > room1.Position.x) { startPoint.Set(room0.rectMinX, room0.Position.y + yMidPointDistance); endPoint.Set(room1.rectMaxX, room1.Position.y - yMidPointDistance); } } // create vertical line HallWay hallway = new HallWay(startPoint, endPoint, room0, room1); _hallways.Add(hallway); room0.AddHallWay(hallway); Debug.Log("##CloseYAxis created hallway from " + startPoint + " to " + endPoint + " between " + room0.name + " " + room1.name); } #endregion #region Far In Both Axis // create L shape hall way else { Vector2 startPoint = Vector2.zero; Vector2 turnPoint = Vector2.zero; Vector2 endPoint = Vector2.zero; // room0 above room1 if (room0.Position.y >= room1.Position.y) { // room0 left to room1 if (room0.Position.x <= room1.Position.x) { startPoint.Set(room0.rectMaxX, room0.Position.y); turnPoint.Set(room0.Position.x + xDistance, room0.Position.y); endPoint.Set(room1.Position.x, room1.rectMaxY); #region Check If Line Collider With Other Room if (LineHasCollision(startPoint, turnPoint, room0.Collider) || LineHasCollision(turnPoint, endPoint, room1.Collider)) { // go other way startPoint.Set(room0.Position.x, room0.rectMinY); turnPoint.Set(room0.Position.x, room0.Position.y - yDistance); endPoint.Set(room1.rectMinX, room1.Position.y); Debug.Log("go other way"); } // still has collision, delete this segment from spanning tree if (LineHasCollision(startPoint, turnPoint, room0.Collider) || LineHasCollision(turnPoint, endPoint, room1.Collider)) { Debug.Log("still collision, remove path"); _spanningTree.RemoveAt(i); i--; continue; } #endregion } // room1 left to room0 else if (room0.Position.x > room1.Position.x) { startPoint.Set(room0.rectMinX, room0.Position.y); turnPoint.Set(room0.Position.x - xDistance, room0.Position.y); endPoint.Set(room1.Position.x, room1.rectMaxY); #region Check If Line Collider With Other Room if (LineHasCollision(startPoint, turnPoint, room0.Collider) || LineHasCollision(turnPoint, endPoint, room1.Collider)) { // go other way startPoint.Set(room0.Position.x, room0.rectMinY); turnPoint.Set(room0.Position.x, room0.Position.y - yDistance); endPoint.Set(room1.rectMaxX, room1.Position.y); Debug.Log("go other way"); } // still has collision, delete this segment from spanning tree if (LineHasCollision(startPoint, turnPoint, room0.Collider) || LineHasCollision(turnPoint, endPoint, room1.Collider)) { Debug.Log("still collison, delete path"); _spanningTree.RemoveAt(i); i--; continue; } #endregion } } // room1 above room0 else if (room0.Position.y < room1.Position.y) { // room0 left to room1 if (room0.Position.x <= room1.Position.x) { startPoint.Set(room0.Position.x, room0.rectMaxY); turnPoint.Set(room0.Position.x, room0.Position.y + yDistance); endPoint.Set(room1.rectMinX, room1.Position.y); #region Check If Line Collider With Other Room if (LineHasCollision(startPoint, turnPoint, room0.Collider) || LineHasCollision(turnPoint, endPoint, room1.Collider)) { // go other way startPoint.Set(room0.rectMaxX, room0.Position.y); turnPoint.Set(room0.Position.x + xDistance, room0.Position.y); endPoint.Set(room1.Position.x, room1.rectMinY); Debug.Log("go other way"); } // still has collision, delete this segment from spanning tree if (LineHasCollision(startPoint, turnPoint, room0.Collider) || LineHasCollision(turnPoint, endPoint, room1.Collider)) { Debug.Log("still collision, delete path"); _spanningTree.RemoveAt(i); i--; continue; } #endregion } // room1 left to room0 else if (room0.Position.x > room1.Position.x) { startPoint.Set(room1.rectMaxX, room1.Position.y); turnPoint.Set(room1.Position.x + xDistance, room1.Position.y); endPoint.Set(room0.Position.x, room0.rectMaxY); #region Check If Line Collider With Other Room if (LineHasCollision(startPoint, turnPoint, room1.Collider) || LineHasCollision(turnPoint, endPoint, room0.Collider)) { // go other way startPoint.Set(room1.Position.x, room1.rectMinY); turnPoint.Set(room1.Position.x, room1.Position.y - yDistance); endPoint.Set(room0.rectMinX, room0.Position.y); Debug.Log("go other way"); } // still has collision, delete this segment from spanning tree if (LineHasCollision(startPoint, turnPoint, room1.Collider) || LineHasCollision(turnPoint, endPoint, room0.Collider)) { Debug.Log("still collision, delete path"); _spanningTree.RemoveAt(i); i--; continue; } #endregion } } // create vertical line LHallWay hallway = new LHallWay(startPoint, turnPoint, endPoint, room0, room1); _hallways.Add(hallway); room0.AddHallWay(hallway); Debug.Log("##Lshape created hallway from " + startPoint + " to " + turnPoint + " to " + endPoint + " between " + room0.name + " " + room1.name); } #endregion } #endregion #region Remove Physics for (int i = 0; i < rooms.Count; i++) { rooms [i].RemovePhysics(); } #endregion #region Create Tiles for (int i = 0; i < rooms.Count; i++) { rooms [i].Fill(); yield return(new WaitForSeconds(0.2f)); } //for (int i = 0; i < _hallways.Count; i++) { // _hallways [i].Fill (); // yield return new WaitForSeconds (0.2f); //} #endregion }
private void DrawDelaunay() { List <LineSegment> delaunay = voronoi.DelaunayTriangulation(); DrawLineSegments(delaunay, Color.red); }
private void CreateVoronoiDiagram() { double width = Application.Current.MainWindow.Width; double height = Application.Current.MainWindow.Height; List <Color> colors = ColorUtils.GenerateRandomColors(MaxPoints); List <Point> points = CreateRandomPoints(width, height); _voronoi = new Voronoi(points, colors, new Rect(0, 0, width, height)); foreach (LineSegment lineSegment in _voronoi.VoronoiDiagram()) { if (!lineSegment.P0.HasValue || !lineSegment.P1.HasValue) { continue; } ShapeSegments.Add(new Line { X1 = lineSegment.P0.Value.X, X2 = lineSegment.P1.Value.X, Y1 = lineSegment.P0.Value.Y, Y2 = lineSegment.P1.Value.Y, Stroke = new SolidColorBrush(Colors.Black), StrokeThickness = 1 }); } int index = 0; foreach (List <Point> point in _voronoi.Regions()) { Polygon polygon = new Polygon { Stroke = new SolidColorBrush(Colors.Black), StrokeThickness = 1, Fill = new SolidColorBrush(colors[index % colors.Count]), Points = new PointCollection(point) }; ShapeSegments.Add(polygon); index++; } foreach (LineSegment lineSegment in _voronoi.DelaunayTriangulation()) { if (!lineSegment.P0.HasValue || !lineSegment.P1.HasValue) { continue; } ShapeSegments.Add(new Line { X1 = lineSegment.P0.Value.X, X2 = lineSegment.P1.Value.X, Y1 = lineSegment.P0.Value.Y, Y2 = lineSegment.P1.Value.Y, Stroke = new SolidColorBrush(Colors.Azure), StrokeThickness = 1 }); } foreach (Point point in points) { var ellipse = new Ellipse { Stroke = new SolidColorBrush(Colors.OrangeRed), StrokeThickness = 5 }; Canvas.SetLeft(ellipse, point.X - ellipse.StrokeThickness / 2); Canvas.SetTop(ellipse, point.Y - ellipse.StrokeThickness / 2); ShapeSegments.Add(ellipse); } }