所以我有WPF c#app有画布要绘制(绘图正在改变矩形的填充,例如有128x128矩形)泛洪填充alghoritm,如果有大量的矩形而不是某些值,它会导致StackOverflow(例如.128x128)。我想升级此脚本以适用于任何大小的绘图区域。我读了一些像这样的问题,但我仍然不知道如何修复它,我需要帮助这个特定的脚本因为这里的绘图与普通绘图有点不同(这是Pixel Art的创建者)。所以这是我的alghoritm。
public static void FloodFIll(int x, int y, Brush color, Brush colorToReplace)
{
if (selectedTool == AvailableTools.FillBucket)
{
if (x < 1 || x > PixiManager.drawAreaSize) return;
if (y < 1 || y > PixiManager.drawAreaSize) return;
if (PixiManager.FieldCords(x, y).Fill != color)
{
if (PixiManager.FieldCords(x, y).Fill == colorToReplace)
{
PixiManager.FieldCords(x, y).Fill = color;
FloodFIll(x, y - 1, color, colorToReplace);
FloodFIll(x + 1, y, color, colorToReplace);
FloodFIll(x, y + 1, color, colorToReplace);
FloodFIll(x - 1, y, color, colorToReplace);
}
}
}
}
答案 0 :(得分:3)
这是你算法的非递归版本。
public static void FloodFIll(int x, int y, Brush color, Brush colorToReplace)
{
if (selectedTool != AvailableTools.FillBucket)
{
return;
}
var stack = new Stack<Tuple<int, int>>();
stack.Push(Tuple.Create(x, y));
while(stack.Count > 0)
{
var point = stack.Pop();
if (point.Item1 < 1 || point.Item1 > PixiManager.drawAreaSize) continue;
if (point.Item2 < 1 || point.Item2 > PixiManager.drawAreaSize) continue;
if (PixiManager.FieldCords(point.Item1, point.Item2).Fill == color) continue;
if (PixiManager.FieldCords(point.Item1, point.Item2).Fill == colorToReplace)
{
PixiManager.FieldCords(point.Item1, point.Item2).Fill = color;
stack.Push(Tuple.Create(point.Item1, point.Item2 - 1));
stack.Push(Tuple.Create(point.Item1 + 1, point.Item2));
stack.Push(Tuple.Create(point.Item1, point.Item2 + 1));
stack.Push(Tuple.Create(point.Item1 - 1, point.Item2));
}
}
}
虽然您可以创建自己的类而不是使用Tuple
。
答案 1 :(得分:2)
我建议不要从每个像素分支,而是在分支之前一次填充整个扫描线。使用这样的逻辑: