예제 #1
0
        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();
    }
예제 #3
0
    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();
    }
예제 #4
0
    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++;
                }
            }
        }
예제 #6
0
    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();
        }
예제 #8
0
    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;
    }
예제 #9
0
    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
    }
예제 #10
0
    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);
            }
        }