コード例 #1
0
        public void AddEdge(VoronoiCellEdge edge, bool isAFirstBSecond)
        {
            if (pathNodes == null)
            {
                pathNodes = new List <VoronoiEdgePathNode>();
            }

/** When you add first edge, need to pre-add its first vertex too - but only for first edge! */
            if (pathNodes.Count < 1)
            {
                if (isAFirstBSecond)
                {
                    pathNodes.Add(new VoronoiEdgePathNode(edge.edgeVertexA));
                }
                else
                {
                    pathNodes.Add(new VoronoiEdgePathNode(edge.edgeVertexB));
                }
            }

            pathNodes.Add(new VoronoiEdgePathNode(edge));

            if (isAFirstBSecond)
            {
                pathNodes.Add(new VoronoiEdgePathNode(edge.edgeVertexB));
            }
            else
            {
                pathNodes.Add(new VoronoiEdgePathNode(edge.edgeVertexA));
            }
        }
コード例 #2
0
        public VoronoiCellEdge GetOtherEdgeContainingCell(VoronoiCellEdge currentEdge, VoronoiCell targetCell)
        {
            foreach (VoronoiCellEdge e in new VoronoiCellEdge[] { edge1, edge2, edge3 })
            {
                if (e == null)
                {
                    continue;
                }

                if (e == currentEdge)
                {
                    continue;
                }

                if (e.cell1 == targetCell ||
                    e.cell2 == targetCell)
                {
                    return(e);
                }
            }

            if (edge3 != null)
            {
                /** this is ONLY an error if all 3 edges existed; otherwise its an expected outcome */
                Debug.LogError("Cannot find another edge from this vertex (" + this + ") that borders cell: " + targetCell);
            }
            return(null);
        }
コード例 #3
0
 public bool ContainsEdge(VoronoiCellEdge e)
 {
     if (e == null)
     {
         return(false);
     }
     return(e == edge1 || e == edge2 || e == edge3);
 }
コード例 #4
0
				public void AddEdge (VoronoiCellEdge e)
				{
						if( edge1 == null )
                        edge1 = e;
      else if( edge2 == null )
        edge2 = e;
      else if( edge3 == null )
        edge3 = e;
			
				}
コード例 #5
0
 public void AddEdge(VoronoiCellEdge e)
 {
     if (edge1 == null)
     {
         edge1 = e;
     }
     else if (edge2 == null)
     {
         edge2 = e;
     }
     else if (edge3 == null)
     {
         edge3 = e;
     }
 }
コード例 #6
0
public void AddEdge( VoronoiCellEdge edge, bool isAFirstBSecond )
{
if( pathNodes == null )
{
pathNodes = new List<VoronoiEdgePathNode>();
}

/** When you add first edge, need to pre-add its first vertex too - but only for first edge! */
if( pathNodes.Count < 1 )
{
				if( isAFirstBSecond )
					pathNodes.Add ( new VoronoiEdgePathNode(edge.edgeVertexA));
				else
					pathNodes.Add ( new VoronoiEdgePathNode(edge.edgeVertexB));
}

pathNodes.Add( new VoronoiEdgePathNode(edge) );

if( isAFirstBSecond )
pathNodes.Add ( new VoronoiEdgePathNode(edge.edgeVertexB));
else
				pathNodes.Add ( new VoronoiEdgePathNode(edge.edgeVertexA));
}
コード例 #7
0
        /** AS3Delaunay library automatically gives us this, and its useless for most things, but great when
         *          trying to make a simple mesh.
         *
         *           Complex meshes would need to know the original Edge objects, so they can set vertex-colouring,
         *           vertex-texture-blending etc (which this CANNOT provide), but we might as well make the simple
         *           version easy while we can!
         *
         *           TODO: border cells will randomly miss some of their edges because this
         *           method stops when it hits an outside / infinite edge, and does NOT scan
         *           through the dictionary to try and find a resume point
         */
        //public List<Vector2> orderedPointsOnCircumference;
        public VoronoiEdgePath CalculateOrderedPathAroundEdges()
        {
            VoronoiEdgePath path = new VoronoiEdgePath();

            /** pick a random edge */
            VoronoiCellEdge firstEdge = neighbours.Keys.ToList().First();

            VoronoiCellEdge currentEdge = firstEdge;

            path.AddEdge(currentEdge, true); // true means nextVertex will be B, false means A; you can choose, just implement next few lines appropriately!

            /** Trace the edge, and when yuo reach a vertex, find the only OTHER edge from
             * that vertex that leads to a vertex that is ALSO on this cell */
            VoronoiCellVertex nextVertex = currentEdge.edgeVertexB;
            VoronoiCellEdge   nextEdge   = nextVertex.GetOtherEdgeContainingCell(currentEdge, this);

            while (nextEdge != firstEdge)
            {
                if (nextEdge == null)
                {
                    /** We hit the end prematurely; means this Cell is on the outer edge of diagram
                     * and is UNCLOSED.
                     *
                     * So we need to scan through neighbours looking for a vertex that
                     * only has ONE edge in this cell, but is NOT the last edge (which meets that criteria too)
                     */
                    foreach (KeyValuePair <VoronoiCellEdge, VoronoiCell> item in neighbours)
                    {
                        if (item.Key == currentEdge)
                        {
                            continue; // found the edge we're already on
                        }
                        VoronoiCellVertex newNextVertex = null;
                        if (item.Key.edgeVertexA.GetEdgesBorderingCell(this).Count < 2)
                        {
                            /** we've found the other one. Now need to start from that vertex.
                             */
                            newNextVertex = item.Key.edgeVertexA;
                        }
                        else if (item.Key.edgeVertexB.GetEdgesBorderingCell(this).Count < 2)
                        {
                            /** we've found the other one. Now need to start from that vertex.
                             */
                            newNextVertex = item.Key.edgeVertexB;
                        }

                        if (newNextVertex != null)
                        {
                            /** Need to FORCE-ADD that vertex onto the path too, since we're jumping
                             * the gap */
                            path.AddJumpToVertex(newNextVertex);

                            nextVertex = newNextVertex;
                            nextEdge   = item.Key;
                        }
                    }

                    if (nextEdge == firstEdge) // rare, but can happen!
                    {
                        break;                 // we added the forced jump to vertex, but have no more edges to add, so stop
                    }
                    if (nextEdge == null)
                    {
                        /** Something has gone badly wrong */
                        Debug.LogError("Major error: was trying to close the loop of an outer Cell, but couldn't find a restart point");
                        break;
                    }
                }

                /** ... normal body of while loop starts here ... */
                bool isNextEdgeAToB = (nextVertex == nextEdge.edgeVertexA);
                path.AddEdge(nextEdge, isNextEdgeAToB);

                if (isNextEdgeAToB)
                {
                    nextVertex = nextEdge.edgeVertexB;
                }
                else
                {
                    nextVertex = nextEdge.edgeVertexA;
                }

                currentEdge = nextEdge;
                nextEdge    = nextVertex.GetOtherEdgeContainingCell(currentEdge, this);
            }

            return(path);
        }
コード例 #8
0
 public VoronoiEdgePathNode( VoronoiCellEdge e )
 {
   nodeType = VoronoiEdgePathNodeType.EDGE;
   edge = e;
 }
コード例 #9
0
 public VoronoiEdgePathNode(VoronoiCellEdge e)
 {
     nodeType = VoronoiEdgePathNodeType.EDGE;
     edge     = e;
 }
コード例 #10
0
				public bool ContainsEdge (VoronoiCellEdge e)
				{
                if( e == null )
        return false;
						return (e == edge1 || e == edge2 || e == edge3);
				}
コード例 #11
0
				public VoronoiCellEdge GetOtherEdgeContainingCell (VoronoiCellEdge currentEdge, VoronoiCell targetCell)
				{
                		foreach ( VoronoiCellEdge e in new VoronoiCellEdge[] { edge1, edge2, edge3})
                        {
                        if( e == null )
                        continue;
                        
								if (e == currentEdge)
										continue;
			
								if (e.cell1 == targetCell
										|| e.cell2 == targetCell)
										return e;
				   
						}
        
                        if( edge3 != null )
                        {                
                        /** this is ONLY an error if all 3 edges existed; otherwise its an expected outcome */
      Debug.LogError ("Cannot find another edge from this vertex (" + this + ") that borders cell: " + targetCell);
      }
      return null;
				}
コード例 #12
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);
        }