Exemplo n.º 1
0
        /// <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));
 }