public static bool TryGetCornerOOBofSameSideAs(Vector2 borderCoord, VEdge edge, out Corner sameSideCorner, out MapSide mapSide) { mapSide = GetOnBorderMapSide(borderCoord); float lockedCoord = 0; switch (mapSide) { case MapSide.Left: lockedCoord = topLeft.x; if (edge.start.position.y > lockedCoord) { sameSideCorner = edge.start; } else { sameSideCorner = edge.end; } return(true); case MapSide.Right: lockedCoord = topRight.x; if (edge.start.position.x > lockedCoord) { sameSideCorner = edge.start; } else { sameSideCorner = edge.end; } return(true); case MapSide.Bottom: lockedCoord = bottomRight.y; if (edge.start.position.y < lockedCoord) { sameSideCorner = edge.start; } else { sameSideCorner = edge.end; } return(true); case MapSide.Top: lockedCoord = topLeft.y; if (edge.start.position.x < lockedCoord) { sameSideCorner = edge.start; } else { sameSideCorner = edge.end; } return(true); } sameSideCorner = null; return(false); }
/// <summary> /// Check if a VEdge already exists between the two corners. /// If the edge doesn't already exist it creates it and adds it to uniqueVEdges list. /// Returns true if edge already existed, false if it was created. /// </summary> /// <param name="other"></param> /// <param name="sharedEdge"></param> /// <returns></returns> public bool TryGetEdgeWith(Corner other, out VEdge sharedEdge) { sharedEdge = FindSharedEdgeWith(other); if (sharedEdge != null) { return(true); } sharedEdge = new VEdge(this, other); VoronoiGraph.uniqueVEdges.Add(sharedEdge); return(false); }
public List <Polygon> GetSharedPolygons(VEdge edge) { List <Polygon> shared = new List <Polygon>(); foreach (Polygon poly in polygons) { if (edge.Contains(poly)) { shared.Add(poly); } } return(shared); }
public bool SharesCorner(VEdge lastEdge, out Corner sharedCorner) { if (lastEdge == this) { throw new System.Exception("Trying to find shared corner with self"); } sharedCorner = null; if (lastEdge.Contains(start)) { sharedCorner = start; } else if (lastEdge.Contains(end)) { sharedCorner = end; } return(sharedCorner != null); }
/// <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(); } }
public void SortEdges() { // Sort edges List <VEdge> newOrder = new List <VEdge>(); List <Corner> newCornerOrder = new List <Corner>(); VEdge last = voronoiEdges[0]; newOrder.Add(last); voronoiEdges.Remove(last); for (int i = 0; i < voronoiEdges.Count;) { VEdge current = voronoiEdges[i]; if (current.SharesCorner(last, out Corner sharedCorner)) { newCornerOrder.Add(sharedCorner); newOrder.Add(current); voronoiEdges.Remove(current); last = current; i = 0; } else { ++i; } } if (voronoiEdges.Count != 0) { throw new System.Exception("Faaaaawk"); } if (!last.SharesCorner(newOrder[0], out Corner shared)) { throw new System.Exception("All hell broke loose"); } newCornerOrder.Insert(0, shared); if (newCornerOrder.Count != corners.Count) { throw new System.Exception("Fawrk"); } corners = newCornerOrder; voronoiEdges = newOrder; for (int i = 1; i < voronoiEdges.Count; ++i) { if (!voronoiEdges[i].SharesCorner(voronoiEdges[i - 1], out Corner noneed)) { Debug.Log("Srsly?"); } } for (int i = 1; i < corners.Count; ++i) { if (newCornerOrder[i].FindSharedEdgeWith(newCornerOrder[i - 1]) == null) { throw new System.Exception("All hell broke loose"); } } }
public bool Contains(VEdge edge) { return(voronoiEdges.Contains(edge)); }
public void Remove(VEdge edge) { voronoiEdges.Remove(edge); }
public void Add(VEdge edge) { voronoiEdges.Add(edge); }