private static ITopoArray <T> RotateInner <T>(ITopoArray <T> original, Func <int, int, ValueTuple <int, int> > mapCoord, TileRotate <T> tileRotate = null) { var originalTopology = original.Topology.AsGridTopology(); // Find new bounds var(x1, y1) = mapCoord(0, 0); var(x2, y2) = mapCoord(originalTopology.Width - 1, 0); var(x3, y3) = mapCoord(originalTopology.Width - 1, originalTopology.Height - 1); var(x4, y4) = mapCoord(0, originalTopology.Height - 1); var minx = Math.Min(Math.Min(x1, x2), Math.Min(x3, x4)); var maxx = Math.Max(Math.Max(x1, x2), Math.Max(x3, x4)); var miny = Math.Min(Math.Min(y1, y2), Math.Min(y3, y4)); var maxy = Math.Max(Math.Max(y1, y2), Math.Max(y3, y4)); // Arrange so that co-ordinate transfer is into the rect bounced by width, height var offsetx = -minx; var offsety = -miny; var width = maxx - minx + 1; var height = maxy - miny + 1; var depth = originalTopology.Depth; var mask = new bool[width * height * depth]; var topology = new GridTopology(originalTopology.Directions, width, height, originalTopology.Depth, false, false, false, mask); var values = new T[width, height, depth]; // Copy from original to values based on the rotation, setting up the mask as we go. for (var z = 0; z < originalTopology.Depth; z++) { for (var y = 0; y < originalTopology.Height; y++) { for (var x = 0; x < originalTopology.Width; x++) { var(newX, newY) = mapCoord(x, y); newX += offsetx; newY += offsety; int newIndex = topology.GetIndex(newX, newY, z); var newValue = original.Get(x, y, z); bool hasNewValue = true; if (tileRotate != null) { hasNewValue = tileRotate(newValue, out newValue); } values[newX, newY, z] = newValue; mask[newIndex] = hasNewValue && originalTopology.ContainsIndex(originalTopology.GetIndex(x, y, z)); } } } return(new TopoArray3D <T>(values, topology)); }
/// <summary> /// Constructs an <see cref="ITopoArray{T}"/> by invoking f at each location in the topology. /// </summary> public static ITopoArray <T> CreateByPoint <T>(Func <Point, T> f, GridTopology topology) { var array = new T[topology.Width, topology.Height, topology.Depth]; for (var z = 0; z < topology.Depth; z++) { for (var y = 0; y < topology.Height; y++) { for (var x = 0; x < topology.Width; x++) { var index = topology.GetIndex(x, y, z); if (topology.ContainsIndex(index)) { array[x, y, z] = f(new Point(x, y, z)); } } } } return(Create(array, topology)); }