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