//HashSet<VoronoiCell2> public HashSet <VoronoiCell2> UnNormalize(HashSet <VoronoiCell2> data) { HashSet <VoronoiCell2> unNormalizedData = new HashSet <VoronoiCell2>(); foreach (VoronoiCell2 cell in data) { MyVector2 sitePosUnNormalized = UnNormalize(cell.sitePos); VoronoiCell2 cellUnNormalized = new VoronoiCell2(sitePosUnNormalized); foreach (VoronoiEdge2 e in cell.edges) { MyVector2 p1UnNormalized = UnNormalize(e.p1); MyVector2 p2UnNormalized = UnNormalize(e.p2); VoronoiEdge2 eUnNormalized = new VoronoiEdge2(p1UnNormalized, p2UnNormalized, sitePosUnNormalized); cellUnNormalized.edges.Add(eUnNormalized); } unNormalizedData.Add(cellUnNormalized); } return(unNormalizedData); }
//List<VoronoiCell2> public static List <VoronoiCell2> UnNormalize(List <VoronoiCell2> data, AABB2 aabb, float dMax) { List <VoronoiCell2> unNormalizedData = new List <VoronoiCell2>(); foreach (VoronoiCell2 cell in data) { MyVector2 sitePosUnNormalized = HelpMethods.UnNormalize(cell.sitePos, aabb, dMax); VoronoiCell2 cellUnNormalized = new VoronoiCell2(sitePosUnNormalized); foreach (VoronoiEdge2 e in cell.edges) { MyVector2 p1UnNormalized = HelpMethods.UnNormalize(e.p1, aabb, dMax); MyVector2 p2UnNormalized = HelpMethods.UnNormalize(e.p2, aabb, dMax); VoronoiEdge2 eUnNormalized = new VoronoiEdge2(p1UnNormalized, p2UnNormalized, sitePosUnNormalized); cellUnNormalized.edges.Add(eUnNormalized); } unNormalizedData.Add(cellUnNormalized); } return(unNormalizedData); }
public static HashSet <VoronoiCell2> GenerateVoronoiDiagram(HashSet <MyVector2> sites) { //First generate the delaunay triangulation //This one has caused a bug so should be avoided //HalfEdgeData2 data = _Delaunay.FlippingEdges(sites, new HalfEdgeData2()); //This one is faster and more accurate, so use it. But if you are using it, make sure to normalize the sites! HalfEdgeData2 delaunayTriangulation = _Delaunay.PointByPoint(sites, new HalfEdgeData2()); //Generate the voronoi diagram //Step 1. For every delaunay edge, compute a voronoi edge //The voronoi edge is the edge connecting the circumcenters of two neighboring delaunay triangles List <VoronoiEdge2> voronoiEdges = new List <VoronoiEdge2>(); HashSet <HalfEdgeFace2> triangles = delaunayTriangulation.faces; //Loop through each triangle foreach (HalfEdgeFace2 t in triangles) { //Each triangle consists of these edges HalfEdge2 e1 = t.edge; HalfEdge2 e2 = e1.nextEdge; HalfEdge2 e3 = e2.nextEdge; //Calculate the circumcenter for this triangle MyVector2 v1 = e1.v.position; MyVector2 v2 = e2.v.position; MyVector2 v3 = e3.v.position; //The circumcenter is the center of a circle where the triangles corners is on the circumference of that circle //The circumcenter is also known as a voronoi vertex, which is a position in the diagram where we are equally //close to the surrounding sites (= the corners ina voronoi cell) MyVector2 voronoiVertex = _Geometry.CalculateCircleCenter(v1, v2, v3); //Debug.Log(voronoiVertex.x + " " + voronoiVertex.y); //We will generate a single edge belonging to this site //Try means that this edge might not have an opposite and then we can't generate an edge TryAddVoronoiEdgeFromTriangleEdge(e1, voronoiVertex, voronoiEdges); TryAddVoronoiEdgeFromTriangleEdge(e2, voronoiVertex, voronoiEdges); TryAddVoronoiEdgeFromTriangleEdge(e3, voronoiVertex, voronoiEdges); } //Step 2. Find the voronoi cells where each cell is a list of all edges belonging to a site //So we have a lot of edges and now each edge should get a cell //These edges are not sorted, so they are added as we find them HashSet <VoronoiCell2> voronoiCells = new HashSet <VoronoiCell2>(); for (int i = 0; i < voronoiEdges.Count; i++) { VoronoiEdge2 e = voronoiEdges[i]; //Find the cell in the list of all cells that includes this site VoronoiCell2 cell = TryFindCell(e, voronoiCells); //No cell was found so we need to create a new cell if (cell == null) { VoronoiCell2 newCell = new VoronoiCell2(e.sitePos); voronoiCells.Add(newCell); newCell.edges.Add(e); } else { cell.edges.Add(e); } } return(voronoiCells); }
public static List <VoronoiCell2> GenerateVoronoiDiagram(HashSet <MyVector2> sites) { //First generate the delaunay triangulation //This one has caused a bug so should be avoided //HalfEdgeData2 data = _Delaunay.FlippingEdges(sites, new HalfEdgeData2()); //This one is faster and more accurate, so use it. But if you are using it, make sure to normalize the sites! HalfEdgeData2 data = _Delaunay.PointByPoint(sites, new HalfEdgeData2()); //Generate the voronoi diagram //Step 1. For every delaunay edge, compute a voronoi edge //The voronoi edge is the edge connecting the circumcenters of two neighboring delaunay triangles List <VoronoiEdge2> voronoiEdges = new List <VoronoiEdge2>(); HashSet <HalfEdgeFace2> triangles = data.faces; foreach (HalfEdgeFace2 t in triangles) { //Each triangle consists of these edges HalfEdge2 e1 = t.edge; HalfEdge2 e2 = e1.nextEdge; HalfEdge2 e3 = e2.nextEdge; //Calculate the circumcenter for this triangle MyVector2 v1 = e1.v.position; MyVector2 v2 = e2.v.position; MyVector2 v3 = e3.v.position; //The circumcenter is the center of a circle where the triangles corners is on the circumference of that circle //The circumcenter is also known as a voronoi vertex, which is a position in the diagram where we are equally //close to the surrounding sites MyVector2 voronoiVertex = _Geometry.CalculateCircleCenter(v1, v2, v3); //This will generate double edges - one belonging to each site, and could maybe be improved in the future //by using the half-edge data structure TryAddVoronoiEdgeFromTriangleEdge(e1, voronoiVertex, voronoiEdges); TryAddVoronoiEdgeFromTriangleEdge(e2, voronoiVertex, voronoiEdges); TryAddVoronoiEdgeFromTriangleEdge(e3, voronoiVertex, voronoiEdges); } //Step 2. Find the voronoi cells where each cell is a list of all edges belonging to a site List <VoronoiCell2> voronoiCells = new List <VoronoiCell2>(); for (int i = 0; i < voronoiEdges.Count; i++) { VoronoiEdge2 e = voronoiEdges[i]; //Find the position in the list of all cells that includes this site int cellPos = TryFindCellPos(e, voronoiCells); //No cell was found so we need to create a new cell if (cellPos == -1) { VoronoiCell2 newCell = new VoronoiCell2(e.sitePos); voronoiCells.Add(newCell); newCell.edges.Add(e); } else { voronoiCells[cellPos].edges.Add(e); } } return(voronoiCells); }