/// <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" /> < 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" /> < 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)); } } }