/// <summary> /// Quads the contains any point in cell. /// No Matter how small the piece, even if it's only one VoronoiEdge point /// We need to know if the polygon of the cell overlaps the Quad, if so /// Add that cell to this Quads list of cells to know about. /// This will lead to duplicate data, it would be better to just keep cells in the /// smallest box that will contain it completely, but for now I'm tired, and can't think. /// </summary> /// <returns><c>true</c>, if contains any point in cell was quaded, <c>false</c> otherwise.</returns> /// <param name="c">C.</param> public bool QuadContainsEveryPointInCell (Cell c) { if (!BoundingBox.Contains (c.site.AsVector2 ())) return false; foreach (VoronoiEdge edge in c.voronoiEdges) { if (edge.VVertexA != Fortune.VVInfinite) { if (!BoundingBox.Contains (edge.VVertexA.AsVector2 ())) return false; } if (edge.VVertexB != Fortune.VVInfinite) { if (!BoundingBox.Contains (edge.VVertexB.AsVector2 ())) return false; } } return true; }
/// <summary> /// Insert the specified Cell In the tree. /// </summary> /// <param name="c">C.</param> public bool Insert (Cell c) { //Debug.Log ("Inserting Cell: " + c.site.AsVector2 () + " into Quad: " + ID + " at Depth: " + Depth + " Max Depth: " + MaxDepth); // First make sure this cell is in bounds. // It should always be, but just to be sure. //if (!BoundingBox.Contains (c.site.AsVector2 ())) if (!QuadContainsEveryPointInCell (c)) return false; // object could not be added. Cells.Add (c); // If we don't already have children if (Children == null) { // AND we aren't too deep in the tree. . . if ((Depth + 1) < MaxDepth) { Split (); // Split to make room. return true; // } else { // If we ARE at Max Depth stick the cell at this level. // Cells.Add (c); // return true; } } if (Children != null) { // If we split this quad . . . // Now Check if the point fits in a Child. if (Children [0].Insert (c)) return true; if (Children [1].Insert (c)) return true; if (Children [2].Insert (c)) return true; if (Children [3].Insert (c)) return true; } // For some reason this cell couldn't be inserted, this should never happen! //Debug.Log ("Could Not Insert cell: " + c.site.AsVector2 ().ToString ()); return false; }
private int NumberOfSites = 512; // Number of seed points to generate for the voronoi diagram, the higher the number the more tesselated the map will be. private bool BuildGraph () { Sites_World = GenerateRandom (Seed, NumberOfSites, 0, Max); Profiler.BeginSample ("Fortune Compute VoronoiGraph"); Graph_World = Fortune.ComputeVoronoiGraph (Sites_World); Profiler.EndSample (); if (Relax) { // Lloyd Relax the points here to get more even distribution. // First we need to know the N number of Voronoi Verts that make up each cell. // Then we can find the centroid of each of those Cells, and move the Site that created this cell to that centroid. // Finally we replace our existing Voronoi graph with a new one made from these centered sites. // This will be computationally expensive so we don't want to do it too many times, 2 max?? for (int i = 0; i < RelaxSteps; i++) { Sites_World = LloydRelax (Sites_World, Graph_World); Graph_World = Fortune.ComputeVoronoiGraph (Sites_World); } } // now you have all the voronoi vertices in graph.Vertices and all the voronoi edges in Relsult.Edges //Debug.Log ("Number of Sites: " + sites.Length); //Debug.Log ("graph.Verts Length: " + graph.Vertizes.Count); if (GenerateCells) { Debug.Log ("Starting Generating Cells in the BuildGraph, Max is: " + Max); //Convert Voronoi to Cells for (int j =0; j < Sites_World.Length; j++) { Vector v = Sites_World [j]; Cell c = new Cell (v); c.max = Max; c.border = false; List<VoronoiEdge> currentBorders = new List<VoronoiEdge> (); // Find Cell VoronoiEdges foreach (VoronoiEdge edge in Graph_World.Edges) { if (edge.LeftData == v || edge.RightData == v) { if (edge.IsInfinite) { c.IsBorder (); Vector AdjustedVec = edge.FixedPoint; edge.VVertexA = AdjustedVec; edge.VVertexB = AdjustedVec + (edge.DirectionVector * InfinityLength); } else if (edge.IsPartlyInfinite) { c.IsBorder (); Vector AdjustedVec = edge.FixedPoint; if (edge.VVertexA == Fortune.VVInfinite) { edge.VVertexA = AdjustedVec; } if (edge.VVertexB == Fortune.VVInfinite) { edge.VVertexB = AdjustedVec; } } BorderCellMax = Max - Border; BorderCellMin = Border; if (edge.VVertexA [0] < BorderCellMin || edge.VVertexA [0] > BorderCellMax || edge.VVertexA [1] < BorderCellMin || edge.VVertexA [1] > BorderCellMax || edge.VVertexB [0] < BorderCellMin || edge.VVertexB [0] > BorderCellMax || edge.VVertexB [1] < BorderCellMin || edge.VVertexB [1] > BorderCellMax) { c.IsBorder (); } if (!currentBorders.Contains (edge)) { currentBorders.Add (edge); } if (!c.neighborCells.Contains (edge.RightData)) { c.neighborCells.Add (edge.RightData); } } else if (edge.RightData == v) { if (!c.neighborCells.Contains (edge.LeftData)) { c.neighborCells.Add (edge.LeftData); } } } c.voronoiEdges = currentBorders; CellGraph.Add (v, c); } } //TODO make exceptions to handle errors during graph creation. if (CellGraph.Count > 0) { return true; } else { return false; } }