Exemple #1
0
        /// <summary>
        ///     Returns all the intersect <see cref="IHexCoordinate" /> with other <see cref="Region" />.
        /// </summary>
        /// <param name="regions"></param>
        /// <returns>Intersect <see cref="IHexCoordinate" /></returns>
        public IEnumerable <IHexCoordinate> Intersection(params Region[] regions)
        {
            if (Radius < 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            var minX = Center.X - Radius;
            var maxX = Center.X + Radius;
            var minY = Center.Y - Radius;
            var maxY = Center.Y + Radius;
            var minZ = Center.Z - Radius;
            var maxZ = Center.Z + Radius;

            foreach (var pair in regions)
            {
                minX = Math.Max(minX, pair.Center.X - pair.Radius);
                maxX = Math.Min(maxX, pair.Center.X + pair.Radius);
                minY = Math.Max(minY, pair.Center.Y - pair.Radius);
                maxY = Math.Min(maxY, pair.Center.Y + pair.Radius);
                minZ = Math.Max(minZ, pair.Center.Z - pair.Radius);
                maxZ = Math.Min(maxZ, pair.Center.Z + pair.Radius);
            }
            for (var x = minX; x <= maxX; x++)
            {
                for (var y = Math.Max(minY, -x - maxZ); y <= Math.Min(maxY, -x - minZ); y++)
                {
                    yield return(HexCoordinates.Cube(x, y, -x - y));
                }
            }
        }
        /// <summary>
        ///     Use this as a center to rotate other <see cref="HexCoordinate" />.
        /// </summary>
        /// <param name="coordinate">Current <see cref="IHexCoordinate" />.</param>
        /// <param name="target"><see cref="IHexCoordinate" /> to be rotated.</param>
        /// <param name="times">Number of 60°. Positive for clockwise.</param>
        /// <returns>Rotated <see cref="IHexCoordinate" />.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="times" /> &lt; 0. </exception>
        /// <exception cref="ArgumentNullException"><paramref name="coordinate" /> or <paramref name="target" /> is null.</exception>
        public static IHexCoordinate Rotate(this IHexCoordinate coordinate, IHexCoordinate target, int times)
        {
            if (coordinate == null)
            {
                throw new ArgumentNullException("coordinate");
            }
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            if (times < 0)
            {
                throw new ArgumentOutOfRangeException("times");
            }
            times %= 6;
            if (times == 0)
            {
                return(target);
            }
            var vectorPx = target.X - coordinate.X;
            var vectorPy = target.Y - coordinate.Y;
            var vectorPz = target.Z - coordinate.Z;
            var isOdd    = times % 2 == 1;

            times %= 3;
            var isPositive = times > 0;

            times = Math.Abs(times);
            for (var i = 0; i < times; i++)
            {
                int temp;
                if (isPositive)
                {
                    temp     = vectorPx;
                    vectorPx = vectorPz;
                    vectorPz = vectorPy;
                    vectorPy = temp;
                }
                else
                {
                    temp     = vectorPx;
                    vectorPx = vectorPy;
                    vectorPy = vectorPz;
                    vectorPz = temp;
                }
            }
            if (!isOdd)
            {
                return(HexCoordinates.Cube(vectorPx + coordinate.X, vectorPy + coordinate.Y, vectorPz + coordinate.Z));
            }
            vectorPx = -vectorPx;
            vectorPy = -vectorPy;
            vectorPz = -vectorPz;
            return(HexCoordinates.Cube(vectorPx + coordinate.X, vectorPy + coordinate.Y, vectorPz + coordinate.Z));
        }
        private static IHexCoordinate Round(double x, double y, double z)
        {
            var rX    = (int)Math.Round(x);
            var rY    = (int)Math.Round(y);
            var rZ    = (int)Math.Round(z);
            var xDiff = Math.Abs(rX - x);
            var yDiff = Math.Abs(rY - y);
            var zDiff = Math.Abs(rZ - z);

            if (xDiff > yDiff && xDiff > yDiff)
            {
                rX = -rY - rZ;
            }
            else if (yDiff > zDiff)
            {
                rY = -rX - rZ;
            }
            else
            {
                rZ = -rX - rY;
            }
            return(HexCoordinates.Cube(rX, rY, rZ));
        }
        /// <summary>
        ///     <para>
        ///         Returns all <see cref="IHexCoordinate" /> within <paramref name="radius" /> and <paramref name="coordinate" />
        ///         as center.
        ///     </para>
        /// </summary>
        /// <param name="coordinate">Current <see cref="IHexCoordinate" />.</param>
        /// <param name="radius">Radius from <paramref name="coordinate" />. 0 returns <paramref name="coordinate" />.</param>
        /// <returns>All <see cref="IHexCoordinate" /> within <paramref name="radius" />.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="radius" /> &lt; 0. </exception>
        /// <exception cref="ArgumentNullException"><paramref name="coordinate" /> is null.</exception>
        public static IEnumerable <IHexCoordinate> Range(this IHexCoordinate coordinate, int radius)
        {
            if (coordinate == null)
            {
                throw new ArgumentNullException("coordinate");
            }
            if (radius == 0)
            {
                yield return(coordinate);

                yield break;
            }
            if (radius < 0)
            {
                throw new ArgumentOutOfRangeException("radius");
            }
            for (var dx = -radius; dx <= radius; dx++)
            {
                for (var dy = Math.Max(-radius, -dx - radius); dy <= Math.Min(radius, -dx + radius); dy++)
                {
                    yield return(HexCoordinates.Cube(dx, dy, -dx - dy).Add(coordinate));
                }
            }
        }