Example #1
0
        public Slider(bool[,] bitmap)
        {
            int width  = bitmap.GetLength(0);
            int height = bitmap.GetLength(1);

            int[] sx = new int[width];
            int[] sy = new int[height];
            sumx = new int[width, height + 1];
            sumy = new int[width + 1, height];
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (bitmap[x, y])
                    {
                        sx[x]++;
                        sy[y]++;
                    }

                    sumx[x, y + 1] = sx[x];
                    sumy[x + 1, y] = sy[y];
                }
            }

            RootBox = new SlideBox();
            CropPicture(RootBox);
        }
Example #2
0
        private SlideBox[] SlideX(SlideBox pb)
        {
            if (hashSlideX.TryGetValue(pb, out var hash))
            {
                return(hash);
            }

            int betterX = 0;
            int minS    = int.MaxValue;

            for (int x = pb.minX; x < pb.maxX;)
            {
                int x1 = x, x2 = x + 1;
                while (x2 < pb.maxX && sumx[x2, pb.minY] == sumx[x2, pb.maxY + 1])
                {
                    x2++;
                }

                int y1 = 0, y2 = 0;
                for (int i = pb.minY; i <= pb.maxY; i++)
                {
                    if (sumy[pb.minX, i] != sumy[x + 1, i])
                    {
                        y1++;
                    }
                }
                for (int i = pb.minY; i <= pb.maxY; i++)
                {
                    if (sumy[x + 1, i] != sumy[pb.maxX + 1, i])
                    {
                        y2++;
                    }
                }

                int S = (x1 - pb.minX + 1) * y1 + (pb.maxX - x2 + 1) * y2;
                if (minS > S)
                {
                    betterX = x;
                    minS    = S;
                }

                x = x2;
            }

            var pbFirst  = new SlideBox(pb.minX, pb.minY, betterX, pb.maxY);
            var pbSecond = new SlideBox(betterX + 1, pb.minY, pb.maxX, pb.maxY);

            CropPicture(pbFirst);
            CropPicture(pbSecond);

            return(minS == int.MaxValue ? null : hashSlideX[pb] = new[] { pbFirst, pbSecond });
        }
Example #3
0
        private SlideBox[] SlideY(SlideBox pb)
        {
            if (hashSlideY.TryGetValue(pb, out var hash))
            {
                return(hash);
            }

            int betterY = 0;
            int minS    = int.MaxValue;

            for (int y = pb.minY; y < pb.maxY;)
            {
                int x1 = 0, x2 = 0;
                for (int i = pb.minX; i <= pb.maxX; i++)
                {
                    if (sumx[i, pb.minY] != sumx[i, y + 1])
                    {
                        x1++;
                    }
                }
                for (int i = pb.minX; i <= pb.maxX; i++)
                {
                    if (sumx[i, y + 1] != sumx[i, pb.maxY + 1])
                    {
                        x2++;
                    }
                }

                int y1 = y, y2 = y + 1;
                while (y2 < pb.maxY && sumy[pb.minX, y2] == sumy[pb.maxX + 1, y2])
                {
                    y2++;
                }

                int S = x1 * (y1 - pb.minY + 1) + x2 * (pb.maxY - y2 + 1);
                if (minS > S)
                {
                    betterY = y1;
                    minS    = S;
                }

                y = y2;
            }

            var pbFirst  = new SlideBox(pb.minX, pb.minY, pb.maxX, betterY);
            var pbSecond = new SlideBox(pb.minX, betterY + 1, pb.maxX, pb.maxY);

            CropPicture(pbFirst);
            CropPicture(pbSecond);

            return(minS == int.MaxValue ? null : hashSlideY[pb] = new[] { pbFirst, pbSecond });
        }
Example #4
0
        public void Slide()
        {
            int      maxS          = 0;
            SlideBox betterPonyBox = null;

            SlideBox[] appendPonyBoxs = null;
            foreach (var pb in RootBox.GetAllBoxes())
            {
                var pbSlideX = SlideX(pb);
                if (pbSlideX != null)
                {
                    var squareEmpty      = hashSquare[pb] - hashSquare[pbSlideX[0]] - hashSquare[pbSlideX[1]];
                    var squareInnerEmpty = hashSquareInner[pb] - hashSquareInner[pbSlideX[0]] - hashSquareInner[pbSlideX[1]];
                    var SqX = Math.Max(squareEmpty, squareInnerEmpty);
                    if (maxS < SqX)
                    {
                        maxS           = SqX;
                        betterPonyBox  = pb;
                        appendPonyBoxs = pbSlideX;
                    }
                }

                var pbSlideY = SlideY(pb);
                if (pbSlideY != null)
                {
                    var squareEmpty      = hashSquare[pb] - hashSquare[pbSlideY[0]] - hashSquare[pbSlideY[1]];
                    var squareInnerEmpty = hashSquareInner[pb] - hashSquareInner[pbSlideY[0]] - hashSquareInner[pbSlideY[1]];
                    var SqY = Math.Max(squareEmpty, squareInnerEmpty);
                    if (maxS < SqY)
                    {
                        maxS           = SqY;
                        betterPonyBox  = pb;
                        appendPonyBoxs = pbSlideY;
                    }
                }
            }
            ;

            if (betterPonyBox != null)
            {
                betterPonyBox.Tree = appendPonyBoxs;
                hashSquare.Remove(betterPonyBox);
                hashSquareInner.Remove(betterPonyBox);
                hashSlideY.Remove(betterPonyBox);
                hashSlideY.Remove(betterPonyBox);
            }
        }
Example #5
0
        private void CropPicture(SlideBox pb)
        {
            int W = sumx.GetLength(0) - 1;
            int H = sumy.GetLength(1) - 1;

            pb.minX = Math.Min(Math.Max(0, pb.minX), W);
            pb.maxX = Math.Min(Math.Max(0, pb.maxX), W);
            pb.minY = Math.Min(Math.Max(0, pb.minY), H);
            pb.maxY = Math.Min(Math.Max(0, pb.maxY), H);

            while (pb.minX <= W && sumx[pb.minX, pb.minY] == sumx[pb.minX, pb.maxY + 1])
            {
                pb.minX++;
            }
            while (pb.minY <= H && sumy[pb.minX, pb.minY] == sumy[pb.maxX + 1, pb.minY])
            {
                pb.minY++;
            }
            while (pb.maxX >= 0 && sumx[pb.maxX, pb.minY] == sumx[pb.maxX, pb.maxY + 1])
            {
                pb.maxX--;
            }
            while (pb.maxY >= 0 && sumy[pb.minX, pb.maxY] == sumy[pb.maxX + 1, pb.maxY])
            {
                pb.maxY--;
            }
            hashSquare[pb] = (pb.maxX - pb.minX + 1) * (pb.maxY - pb.minY + 1);

            int x1 = 0, y1 = 0;

            for (int x = pb.minX; x <= pb.maxX; x++)
            {
                if (sumx[x, pb.minY] != sumx[x, pb.maxY + 1])
                {
                    x1++;
                }
            }
            for (int y = pb.minY; y <= pb.maxY; y++)
            {
                if (sumy[pb.minX, y] != sumy[pb.maxX + 1, y])
                {
                    y1++;
                }
            }
            hashSquareInner[pb] = x1 * y1;
        }