Edges() 공개 메소드

public Edges ( ) : List
리턴 List
예제 #1
0
        private void BuildGraph(IEnumerable <Vector2> points, Delaunay.Voronoi voronoi)
        {
            // Build graph data structure in 'edges', 'centers', 'corners',
            // based on information in the Voronoi results: point.neighbors
            // will be a list of neighboring points of the same type (corner
            // or center); point.edges will be a list of edges that include
            // that point. Each edge connects to four points: the Voronoi edge
            // edge.{v0,v1} and its dual Delaunay triangle edge edge.{d0,d1}.
            // For boundary polygons, the Delaunay edge will have one null
            // point, and the Voronoi edge may be null.
            var libedges = voronoi.Edges();

            var centerLookup = new Dictionary <Vector2?, Center>();

            // Build Center objects for each of the points, and a lookup map
            // to find those Center objects again as we build the graph
            foreach (var point in points)
            {
                var p = new Center {
                    index = centers.Count, point = point
                };
                centers.Add(p);
                centerLookup[point] = p;
            }

            // Workaround for Voronoi lib bug: we need to call region()
            // before Edges or neighboringSites are available
            foreach (var p in centers)
            {
                voronoi.Region(p.point);
            }

            foreach (var libedge in libedges)
            {
                var dedge = libedge.DelaunayLine();
                var vedge = libedge.VoronoiEdge();

                // Fill the graph data. Make an Edge object corresponding to
                // the edge from the voronoi library.
                var edge = new Edge
                {
                    index = edges.Count,
                    river = 0,

                    // Edges point to corners. Edges point to centers.
                    v0 = MakeCorner(vedge.p0),
                    v1 = MakeCorner(vedge.p1),
                    d0 = centerLookup[dedge.p0],
                    d1 = centerLookup[dedge.p1]
                };
                if (vedge.p0.HasValue && vedge.p1.HasValue)
                {
                    edge.midpoint = Vector2Extensions.Interpolate(vedge.p0.Value, vedge.p1.Value, 0.5f);
                }

                edges.Add(edge);

                // Centers point to edges. Corners point to edges.
                if (edge.d0 != null)
                {
                    edge.d0.borders.Add(edge);
                }
                if (edge.d1 != null)
                {
                    edge.d1.borders.Add(edge);
                }
                if (edge.v0 != null)
                {
                    edge.v0.protrudes.Add(edge);
                }
                if (edge.v1 != null)
                {
                    edge.v1.protrudes.Add(edge);
                }

                // Centers point to centers.
                if (edge.d0 != null && edge.d1 != null)
                {
                    AddToCenterList(edge.d0.neighbors, edge.d1);
                    AddToCenterList(edge.d1.neighbors, edge.d0);
                }

                // Corners point to corners
                if (edge.v0 != null && edge.v1 != null)
                {
                    AddToCornerList(edge.v0.adjacent, edge.v1);
                    AddToCornerList(edge.v1.adjacent, edge.v0);
                }

                // Centers point to corners
                if (edge.d0 != null)
                {
                    AddToCornerList(edge.d0.corners, edge.v0);
                    AddToCornerList(edge.d0.corners, edge.v1);
                }
                if (edge.d1 != null)
                {
                    AddToCornerList(edge.d1.corners, edge.v0);
                    AddToCornerList(edge.d1.corners, edge.v1);
                }

                // Corners point to centers
                if (edge.v0 != null)
                {
                    AddToCenterList(edge.v0.touches, edge.d0);
                    AddToCenterList(edge.v0.touches, edge.d1);
                }
                if (edge.v1 != null)
                {
                    AddToCenterList(edge.v1.touches, edge.d0);
                    AddToCenterList(edge.v1.touches, edge.d1);
                }
            }

            // TODO: use edges to determine these
            var topLeft = centers.OrderBy(p => p.point.x + p.point.y).First();

            AddCorner(topLeft, 0, 0);

            var bottomRight = centers.OrderByDescending(p => p.point.x + p.point.y).First();

            AddCorner(bottomRight, Width, Height);

            var topRight = centers.OrderByDescending(p => Width - p.point.x + p.point.y).First();

            AddCorner(topRight, 0, Height);

            var bottomLeft = centers.OrderByDescending(p => p.point.x + Height - p.point.y).First();

            AddCorner(bottomLeft, Width, 0);

            // required for polygon fill
            foreach (var center in centers)
            {
                center.corners.Sort(ClockwiseComparison(center));
            }
        }
예제 #2
0
/**
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;
    }
예제 #3
0
        private void CreateDataStructure(Map map, Voronoi v, KDTree <Center> kd, DataFactory factory)
        {
            foreach (var voronEdge in v.Edges())
            {
                if (voronEdge.leftSite == null ||
                    voronEdge.rightSite == null ||
                    voronEdge.leftVertex == null ||
                    voronEdge.rightVertex == null)
                {
                    continue;
                }

                var centerLeft  = factory.CenterFactory(voronEdge.leftSite.Coord.ToVector3xz());
                var centerRight = factory.CenterFactory(voronEdge.rightSite.Coord.ToVector3xz());
                var cornerLeft  = factory.CornerFactory(voronEdge.leftVertex.Coord.ToVector3xz());
                var cornerRight = factory.CornerFactory(voronEdge.rightVertex.Coord.ToVector3xz());
                var ed          = factory.EdgeFactory(cornerLeft, cornerRight, centerLeft, centerRight);
            }

            foreach (var edge in map.Edges.Values)
            {
                edge.VoronoiStart.Protrudes[edge.Midpoint] = edge;
                edge.VoronoiEnd.Protrudes[edge.Midpoint]   = edge;
                edge.DelaunayStart.Borders[edge.Midpoint]  = edge;
                edge.DelaunayEnd.Borders[edge.Midpoint]    = edge;
            }

            foreach (var corner in map.Corners.Values)
            {
                foreach (var edge in corner.Protrudes.Values)
                {
                    if (edge.VoronoiStart != corner)
                    {
                        corner.Adjacents[edge.VoronoiStart.Point] = edge.VoronoiStart;
                    }
                    if (edge.VoronoiEnd != corner)
                    {
                        corner.Adjacents[edge.VoronoiEnd.Point] = edge.VoronoiEnd;
                    }

                    // Adding one side of every protruder will make it all
                    if (!corner.Touches.ContainsKey(edge.DelaunayStart.Point))
                    {
                        corner.Touches[edge.DelaunayStart.Point] = edge.DelaunayStart;
                    }
                    if (!corner.Touches.ContainsKey(edge.DelaunayEnd.Point))
                    {
                        corner.Touches[edge.DelaunayEnd.Point] = edge.DelaunayEnd;
                    }
                }
            }

            foreach (var center in map.Centers.Values)
            {
                foreach (var edge in center.Borders.Values)
                {
                    if (edge.DelaunayStart != center)
                    {
                        center.Neighbours[edge.DelaunayStart.Point] = edge.DelaunayStart;
                    }
                    if (edge.DelaunayStart != center && !center.Neighbours.ContainsKey(edge.DelaunayStart.Point))
                    {
                        center.Neighbours[edge.DelaunayStart.Point] = edge.DelaunayStart;
                    }

                    // Adding one side of every border will make it all
                    if (!center.Corners.ContainsKey(edge.VoronoiStart.Point))
                    {
                        center.Corners[edge.VoronoiStart.Point] = edge.VoronoiStart;
                    }
                    if (!center.Corners.ContainsKey(edge.VoronoiEnd.Point))
                    {
                        center.Corners[edge.VoronoiEnd.Point] = edge.VoronoiEnd;
                    }
                }
            }
        }