Пример #1
0
        public void Remove(BinaryMap input)
        {
            BinaryMap sw2ne = new BinaryMap(input.Size);
            BinaryMap se2nw = new BinaryMap(input.Size);
            BinaryMap positions = new BinaryMap(input.Size);
            BinaryMap squares = new BinaryMap(input.Size);

            while (true)
            {
                sw2ne.Copy(input, new RectangleC(0, 0, input.Width - 1, input.Height - 1), new Point());
                sw2ne.And(input, new RectangleC(1, 1, input.Width - 1, input.Height - 1), new Point());
                sw2ne.AndNot(input, new RectangleC(0, 1, input.Width - 1, input.Height - 1), new Point());
                sw2ne.AndNot(input, new RectangleC(1, 0, input.Width - 1, input.Height - 1), new Point());

                se2nw.Copy(input, new RectangleC(0, 1, input.Width - 1, input.Height - 1), new Point());
                se2nw.And(input, new RectangleC(1, 0, input.Width - 1, input.Height - 1), new Point());
                se2nw.AndNot(input, new RectangleC(0, 0, input.Width - 1, input.Height - 1), new Point());
                se2nw.AndNot(input, new RectangleC(1, 1, input.Width - 1, input.Height - 1), new Point());

                positions.Copy(sw2ne);
                positions.Or(se2nw);
                if (positions.IsEmpty())
                    break;

                squares.Copy(positions);
                squares.Or(positions, new RectangleC(0, 0, positions.Width - 1, positions.Height - 1), new Point(1, 0));
                squares.Or(positions, new RectangleC(0, 0, positions.Width - 1, positions.Height - 1), new Point(0, 1));
                squares.Or(positions, new RectangleC(0, 0, positions.Width - 1, positions.Height - 1), new Point(1, 1));

                input.AndNot(squares);
            }
            Logger.Log(input);
        }
Пример #2
0
        public BinaryMap Thin(BinaryMap input)
        {
            BinaryMap intermediate = new BinaryMap(input.Size);
            intermediate.Copy(input, new RectangleC(1, 1, input.Width - 2, input.Height - 2), new Point(1, 1));

            BinaryMap border = new BinaryMap(input.Size);
            BinaryMap skeleton = new BinaryMap(input.Size);
            bool removedAnything = true;
            for (int i = 0; i < MaxIterations && removedAnything; ++i)
            {
                removedAnything = false;
                for (int j = 0; j < 4; ++j)
                {
                    border.Copy(intermediate);
                    switch (j)
                    {
                        case 0:
                            border.AndNot(intermediate, new RectangleC(1, 0, border.Width - 1, border.Height), new Point(0, 0));
                            break;
                        case 1:
                            border.AndNot(intermediate, new RectangleC(0, 0, border.Width - 1, border.Height), new Point(1, 0));
                            break;
                        case 2:
                            border.AndNot(intermediate, new RectangleC(0, 1, border.Width, border.Height - 1), new Point(0, 0));
                            break;
                        case 3:
                            border.AndNot(intermediate, new RectangleC(0, 0, border.Width, border.Height - 1), new Point(0, 1));
                            break;
                    }
                    border.AndNot(skeleton);

                    for (int odd = 0; odd < 2; ++odd)
                        Parallel.For(1, input.Height - 1, delegate(int y)
                        {
                            if (y % 2 == odd)
                                for (int xw = 0; xw < input.WordWidth; ++xw)
                                    if (border.IsWordNonZero(xw, y))
                                        for (int x = xw << BinaryMap.WordShift; x < (xw << BinaryMap.WordShift) + BinaryMap.WordSize; ++x)
                                            if (x > 0 && x < input.Width - 1 && border.GetBit(x, y))
                                            {
                                                uint neighbors = intermediate.GetNeighborhood(x, y);
                                                if (IsRemovable[neighbors]
                                                    || IsEnding[neighbors] && IsFalseEnding(intermediate, new Point(x, y)))
                                                {
                                                    removedAnything = true;
                                                    intermediate.SetBitZero(x, y);
                                                }
                                                else
                                                    skeleton.SetBitOne(x, y);
                                            }
                        });
                }
            }

            Logger.Log(skeleton);
            return skeleton;
        }