/// <summary> /// Computes a polygon from its tiles. /// </summary> /// <param name="allPoints"></param> /// <returns></returns> public static PolygonGrid2D GetPolygonFromTiles(HashSet <Vector3Int> allPoints) { if (allPoints.Count == 0) { throw new ArgumentException("There must be at least one point"); } var orderedDirections = new Dictionary <EdgarVector2Int, List <EdgarVector2Int> > { { IntVector2Helper.Top, new List <EdgarVector2Int> { IntVector2Helper.Left, IntVector2Helper.Top, IntVector2Helper.Right } }, { IntVector2Helper.Right, new List <EdgarVector2Int> { IntVector2Helper.Top, IntVector2Helper.Right, IntVector2Helper.Bottom } }, { IntVector2Helper.Bottom, new List <EdgarVector2Int> { IntVector2Helper.Right, IntVector2Helper.Bottom, IntVector2Helper.Left } }, { IntVector2Helper.Left, new List <EdgarVector2Int> { IntVector2Helper.Bottom, IntVector2Helper.Left, IntVector2Helper.Top } } }; var allPointsInternal = allPoints.Select(x => x.ToCustomIntVector2()).ToHashSet(); var smallestX = allPointsInternal.Min(x => x.X); var smallestXPoints = allPointsInternal.Where(x => x.X == smallestX).ToList(); var smallestXYPoint = smallestXPoints[smallestXPoints.MinBy(x => x.Y)]; var startingPoint = smallestXYPoint; var startingDirection = IntVector2Helper.Top; var polygonPoints = new List <EdgarVector2Int>(); var currentPoint = startingPoint + startingDirection; var firstPoint = currentPoint; var previousDirection = startingDirection; var first = true; if (!allPointsInternal.Contains(currentPoint)) { throw new ArgumentException("Invalid room shape."); } while (true) { var foundNeighbor = false; var currentDirection = new EdgarVector2Int(); foreach (var directionVector in orderedDirections[previousDirection]) { var newPoint = currentPoint + directionVector; if (allPointsInternal.Contains(newPoint)) { currentDirection = directionVector; foundNeighbor = true; break; } } if (!foundNeighbor) { throw new ArgumentException("Invalid room shape."); } if (currentDirection != previousDirection) { polygonPoints.Add(currentPoint); } currentPoint += currentDirection; previousDirection = currentDirection; if (first) { first = false; } else if (currentPoint == firstPoint) { break; } } if (!IsClockwiseOriented(polygonPoints)) { polygonPoints.Reverse(); } return(new PolygonGrid2D(polygonPoints)); }
public static Vector3Int ToUnityIntVector3(this EdgarVector2Int vector) { return(new Vector3Int(vector.X, vector.Y, 0)); }