感谢@Groo的评论,我意识到我已经有了正确的思路,那就是使用泛洪填充。但是,我一直在考虑如何扫描形状内部以找到边界,这就是我错了的地方。Groo建议始终应该有一个外部点,并从那里开始扫描。
![enter image description here](https://istack.dev59.com/kKtvu.webp)
我使用一个简单的二维布尔数组编写了一个非常基本的测试程序(并复制粘贴了一个相当容易阅读的泛洪算法),这似乎很好地工作。我将这个简单的代码发布为答案,以便帮助像我一样困惑的人,并防止添加另一个措辞不清的“问题”。
class Program
{
static void Main(string[] args)
{
bool[,] grid;
int width;
int height;
Console.Title = "Floodfill Shape Test";
width = 12;
height = 10;
grid = new bool[width, height];
grid[1, 1] = true;
grid[2, 1] = true;
grid[3, 1] = true;
grid[1, 2] = true;
grid[3, 2] = true;
grid[1, 3] = true;
grid[2, 3] = true;
grid[3, 3] = true;
grid[7, 1] = true;
grid[8, 1] = true;
grid[9, 1] = true;
grid[10, 1] = true;
grid[7, 2] = true;
grid[10, 2] = true;
grid[7, 3] = true;
grid[8, 3] = true;
grid[10, 3] = true;
grid[8, 4] = true;
grid[10, 4] = true;
grid[8, 5] = true;
grid[9, 5] = true;
grid[10, 5] = true;
grid[1, 5] = true;
grid[2, 5] = true;
grid[3, 5] = true;
grid[1, 6] = true;
grid[3, 6] = true;
grid[1, 7] = true;
grid[3, 7] = true;
for (int i = 1; i < height - 1; i++)
{
grid[5, i] = true;
}
PrintGrid(grid, width, height);
FloodFill(grid, width, height);
PrintGrid(grid, width, height);
if (Debugger.IsAttached)
{
Console.WriteLine("(Press any key to exit)");
Console.ReadKey(true);
}
}
private static void PrintGrid(bool[,] grid, int width, int height)
{
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
char c;
if (row == 0 || row == height - 1 || col == 0 || col == width - 1)
{
c = 'X';
}
else {
c = grid[col, row] ? '#' : '.';
}
Console.Write(c);
}
Console.WriteLine();
}
Console.WriteLine();
}
static void FloodFill(bool[,] grid, int width, int height)
{
Queue<Point> q = new Queue<Point>();
q.Enqueue(Point.Empty);
while (q.Count > 0)
{
Point n = q.Dequeue();
if (grid[n.X, n.Y])
continue;
Point w = n, e = new Point(n.X + 1, n.Y);
while ((w.X >= 0) && !grid[w.X, w.Y])
{
grid[w.X, w.Y] = true;
if ((w.Y > 0) && !grid[w.X, w.Y - 1])
q.Enqueue(new Point(w.X, w.Y - 1));
if ((w.Y < height - 1) && !grid[w.X, w.Y + 1])
q.Enqueue(new Point(w.X, w.Y + 1));
w.X--;
}
while ((e.X <= width - 1) && !grid[e.X, e.Y])
{
grid[e.X, e.Y] = true;
if ((e.Y > 0) && !grid[e.X, e.Y - 1])
q.Enqueue(new Point(e.X, e.Y - 1));
if ((e.Y < height - 1) && !grid[e.X, e.Y + 1])
q.Enqueue(new Point(e.X, e.Y + 1));
e.X++;
}
}
}
}