private void GetCornersAndEdges() { foreach (var dTriangle in centroid.dTriangles) { if (dTriangle.isInvalidated) // this can't happen at this point.... { continue; } var corner = dTriangle.GetCorner(); VoronoiHelper.Associate(this, corner); foreach (var tri in centroid.dTriangles) { if (tri == dTriangle || tri.isInvalidated) { continue; } if (dTriangle.SharesEdgeWith(tri)) { corner.TryGetEdgeWith(tri.GetCorner(), out VEdge vEdge); if (!voronoiEdges.Contains(vEdge)) { VoronoiHelper.Associate(this, vEdge); } } } } if (voronoiEdges.Count < 3) { Invalidate(); return; } }
/// <summary> /// Replaces oldSite with newSite in this edge, using newSites position and all other properties. /// Connects newSite with polygons this edge is border of but does not remove oldSite from polygons. /// </summary> /// <param name="oldSite"></param> /// <param name="newSite"></param> public void ReplaceSite(Corner oldSite, Corner newSite) { if (!Contains(oldSite)) { throw new System.Exception("This edge does not contain input oldSite"); } if (start == oldSite) { start.connectedEdges.Remove(this); start = newSite; start.connectedEdges.Add(this); } else { end.connectedEdges.Remove(this); end = newSite; end.connectedEdges.Add(this); } foreach (var polygon in polygons) { if (!polygon.corners.Contains(newSite)) { VoronoiHelper.Associate(polygon, newSite); } } }
/// <summary> /// Some random seeds produce invalid polygon that uses map corners. Ex: /// 637427950365396994 /// 637427958541256155 /// </summary> /// <param name="vGen"></param> /// <param name="dGraph"></param> public VoronoiGraph(VoronoiGenerator vGen, DelaunayGraph dGraph) { generator = vGen; delaunayGraph = dGraph; cornerCount = 0; uniqueVEdges = new HashSet <VEdge>(); uniqueCorners = new HashSet <Corner>(); removeCorners = new List <Corner>(); mapCorners = new Dictionary <byte, Corner>() { [VoronoiGenerator.TopRightCornerByte] = new Corner(VoronoiGenerator.topRight, cornerCount++, true), [VoronoiGenerator.TopLeftCornerByte] = new Corner(VoronoiGenerator.topLeft, cornerCount++, true), [VoronoiGenerator.BottomRightCornerByte] = new Corner(VoronoiGenerator.bottomRight, cornerCount++, true), [VoronoiGenerator.BottomLeftCornerByte] = new Corner(VoronoiGenerator.bottomLeft, cornerCount++, true), }; invalidatedPolygons = new List <Polygon>(); invalidatedEdges = new HashSet <VEdge>(); polygons = new List <Polygon>(); for (int i = 0; i < dGraph.centroids.Count; ++i) // first 4 centroids are map corners { Polygon poly = new Polygon(dGraph.centroids[i]); polygons.Add(poly); } if (polygons[0].corners == null || polygons[1].corners == null || polygons[2].corners == null || polygons[3].corners == null) { logMsgs = new List <string>(); logMsgs.Add("****** Error found on Seed: " + generator.randomSeed + "******"); logMsgs.Add("Map dimensions: " + generator.mapWidth + ", " + generator.mapHeight); logMsgs.Add("Region amt: " + generator.regionAmount); logMsgs.Add("MinSqrDistBtwnSites: " + generator.minSqrDistBtwnSites); logMsgs.Add("MinDistBtwnSiteAndBorder: " + generator.minDistBtwnSiteAndBorder); logMsgs.Add("MinDistBtwnCornerAndBorder: " + generator.minDistBtwnCornerAndBorder); logMsgs.Add("MinEdgeLengthToMerge: " + generator.minEdgeLengthToMerge); logMsgs.Add("Merge near corners: " + generator.mergeNearCorners); logMsgs.Add("******************************************\n"); logMsgs.Add("Corner polygon did not make it passed initial generation"); System.IO.File.WriteAllLines(logFilePath + "BorderCornerDeletedIssue_" + generator.randomSeed + ".txt", logMsgs); Log("Corner polygon did not make it passed initial generation", LogType.Exception, false); } VoronoiHelper.Associate(polygons[0], mapCorners[TopLeftCornerByte]); VoronoiHelper.Associate(polygons[1], mapCorners[TopRightCornerByte]); VoronoiHelper.Associate(polygons[2], mapCorners[BottomRightCornerByte]); VoronoiHelper.Associate(polygons[3], mapCorners[BottomLeftCornerByte]); if (VoronoiGenerator.MergeNearCorners) { MergeNearCorners(); } if (generator.clampToMapBounds) { if (!ClampToMapBounds()) { return; } foreach (Corner corner in uniqueCorners) { if (corner.isInvalidated) { if (!removeCorners.Contains(corner)) { removeCorners.Add(corner); } continue; } if (corner.isOOB) { removeCorners.Add(corner); } } } for (int i = removeCorners.Count - 1; i >= 0; --i) { Corner removingCorner = removeCorners[i]; for (int j = removingCorner.connectedEdges.Count - 1; j >= 0; --j) { VEdge edge = removingCorner.connectedEdges[j]; removingCorner.connectedEdges.Remove(edge); uniqueVEdges.Remove(edge); Corner opposite = edge.GetOppositeSite(removingCorner); opposite.connectedEdges.Remove(edge); foreach (var poly in removingCorner.polygons) { poly.Remove(edge); } } removingCorner.connectedEdges.Clear(); RemoveCorner(removingCorner); } int culled = 0; foreach (var polygon in invalidatedPolygons) { debugPolygons.Add(polygon); polygons.Remove(polygon); ++culled; } foreach (Polygon polygon in polygons) { polygon.CenterCentroid(); polygon.SortEdges(); } }
private void CreateBorderEdge(Corner corner1, Corner corner2, Polygon polygon) { corner1.TryGetEdgeWith(corner2, out VEdge sharedEdge); VoronoiHelper.Associate(polygon, sharedEdge); }