Esempio n. 1
0
        public static ITopoArray <T> Rotate <T>(ITopoArray <T> original, int rotateCw, bool reflectX = false, TileRotate <T> tileRotate = null)
        {
            if (rotateCw == 0 && !reflectX)
            {
                return(original);
            }

            ValueTuple <int, int> MapCoord(int x, int y)
            {
                return(RotateVector(x, y, rotateCw, reflectX));
            }

            return(RotateInner(original, MapCoord, tileRotate));
        }
Esempio n. 2
0
        private static ITopoArray <T> RotateInner <T>(ITopoArray <T> original, Func <int, int, ValueTuple <int, int> > mapCoord, TileRotate <T> tileRotate = null)
        {
            // Find new bounds
            var(x1, y1) = mapCoord(0, 0);
            var(x2, y2) = mapCoord(original.Topology.Width - 1, 0);
            var(x3, y3) = mapCoord(original.Topology.Width - 1, original.Topology.Height - 1);
            var(x4, y4) = mapCoord(0, original.Topology.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   = original.Topology.Depth;

            var mask     = new bool[width * height * depth];
            var topology = new Topology(original.Topology.Directions, width, height, original.Topology.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 < original.Topology.Depth; z++)
            {
                for (var y = 0; y < original.Topology.Height; y++)
                {
                    for (var x = 0; x < original.Topology.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 && original.Topology.ContainsIndex(original.Topology.GetIndex(x, y, z));
                    }
                }
            }

            return(new TopoArray3D <T>(values, topology));
        }
Esempio n. 3
0
        public static ITopoArray <T> HexRotate <T>(ITopoArray <T> original, int rotateCw, bool reflectX, TileRotate <T> tileRotate = null)
        {
            if (rotateCw == 0 && !reflectX)
            {
                return(original);
            }

            var microRotate = rotateCw % 3;
            var rotate180   = rotateCw % 2 == 1;

            // Actually do a reflection/rotation
            ValueTuple <int, int> MapCoord(int x, int y)
            {
                return(HexRotateVector(x, y, microRotate, rotate180, reflectX));
            }

            return(RotateInner(original, MapCoord, tileRotate));
        }
Esempio n. 4
0
        public static ITopoArray <T> HexRotate <T>(ITopoArray <T> original, Rotation rotation, TileRotate <T> tileRotate = null)
        {
            if (rotation.IsIdentity)
            {
                return(original);
            }

            var microRotate = (rotation.RotateCw / 60) % 3;
            var rotate180   = (rotation.RotateCw / 60) % 2 == 1;

            // Actually do a reflection/rotation
            ValueTuple <int, int> MapCoord(int x, int y)
            {
                return(HexRotateVector(x, y, microRotate, rotate180, rotation.ReflectX));
            }

            return(RotateInner(original, MapCoord, tileRotate));
        }
Esempio n. 5
0
        public static ITopoArray <T> SquareRotate <T>(ITopoArray <T> original, Rotation rotation, TileRotate <T> tileRotate = null)
        {
            if (rotation.IsIdentity)
            {
                return(original);
            }

            ValueTuple <int, int> MapCoord(int x, int y)
            {
                return(SquareRotateVector(x, y, rotation));
            }

            return(RotateInner(original, MapCoord, tileRotate));
        }
Esempio n. 6
0
        public static ITopoArray <T> Rotate <T>(ITopoArray <T> original, Rotation rotation, TileRotate <T> tileRotate = null)
        {
            var type = original.Topology.Directions.Type;

            if (type == DirectionSetType.Cartesian2d ||
                type == DirectionSetType.Cartesian3d)
            {
                return(SquareRotate(original, rotation, tileRotate));
            }
            else if (type == DirectionSetType.Hexagonal2d)
            {
                return(HexRotate(original, rotation, tileRotate));
            }
            else
            {
                throw new Exception($"Unknown directions type {type}");
            }
        }