我一直在尝试编写一个可在Unity中运行的泛洪填充算法。该想法是基于用户选择的颜色对黑白线图的部分进行着色。我已经尝试了泛洪填充算法的几种实现,但是当它们被调用时它们都会导致统一挂起。
非常感谢任何有关这方面的帮助,这是一个重要项目的一部分。任何有关代码修改,算法设计或任何其他方法的建议都将非常感激:)
代码:
// FloodFill function
void FloodFill()
{
// TEST - colour the clicked pixel
//_tex.SetPixel( (int)_pixelUV.x, (int)_pixelUV.y, m_fillColour );
//_tex.SetPixel( _pixelX, _pixelY, m_fillColour );
// FLOOD FILL
// ----------
// Create WestEast
List<Point> m_WestEast;
//get the pixel's colour
Color PC = new Color(_tex.GetPixel(m_StartNode.X, m_StartNode.Y).r, _tex.GetPixel(m_StartNode.X, m_StartNode.Y).g, _tex.GetPixel(m_StartNode.X, m_StartNode.Y).b);
//Record clicked pixel as point
Point node = new Point(m_StartNode.X, m_StartNode.Y);
//if the pixel's colour is boundary colour (black), return.
if(PC == Color.black)
{
return;
}
//else continue
// Create a list Q[]
m_List = new List<Point>();
//add clicked pixel to Q[]
m_List.Add(node);
//for each element in Q[]
for(int i=0; i<m_List.Count; i++)
{
//create new WE[] and add Q[n] to it
m_WestEast = new List<Point>();
m_WestEast.Add(node);
//get pixel 1 to left (w) of Q[n]
Point w = new Point(node.X + 1, node.Y);
//get colour of w
Color wCol = new Color(_tex.GetPixel(w.X, w.Y).r, _tex.GetPixel(w.X, w.Y).g, _tex.GetPixel(w.X, w.Y).b);
while(wCol != Color.black)
{
//add pixel to WE[] and repeat
m_WestEast.Add(w);
//get new w
w = new Point(w.X + 1, w.Y);
//get colour of w
wCol = new Color(_tex.GetPixel(w.X, w.Y).r, _tex.GetPixel(w.X, w.Y).g, _tex.GetPixel(w.X, w.Y).b);
//else if colour is boundary colour
//go to next step
}
//get pixel 1 to right (e) of Q[n]
Point e = new Point(node.X - 1, node.Y);
//get colour of w
Color eCol = new Color(_tex.GetPixel(e.X, e.Y).r, _tex.GetPixel(e.X, e.Y).g, _tex.GetPixel(e.X, e.Y).b);
while(eCol != Color.black)
{
//add pixel to WE[] and repeat
m_WestEast.Add(e);
//get new e
e = new Point(e.X - 1, e.Y);
//get colour of e
eCol = new Color(_tex.GetPixel(e.X, e.Y).r, _tex.GetPixel(e.X, e.Y).g, _tex.GetPixel(e.X, e.Y).b);
//else if colour is boundary colour
//go to next step
}
//for each pixel in WE[]
for(int j=0; j<m_WestEast.Count; j++)
{
//set the pixel to replacement colour
_tex.SetPixel(m_WestEast[j].X, m_WestEast[j].Y, m_fillColour);
//get pixel 1 to north (n) of Q[n]
Point n = new Point(m_WestEast[j].X, m_WestEast[j].Y - 1);
//get colour of n
Color nCol = new Color(_tex.GetPixel(n.X, n.Y).r, _tex.GetPixel(n.X, n.Y).g, _tex.GetPixel(n.X, n.Y).b);
//if colour is not boundary colour
if(nCol != Color.black)
{
//add pixel to Q[]
m_List.Add(n);
}
//get pixel 1 to south (s) of Q[n]
Point s = new Point(m_WestEast[j].X, m_WestEast[j].Y + 1);
//get colour of s
Color sCol = new Color(_tex.GetPixel(s.X, s.Y).r, _tex.GetPixel(s.X, s.Y).g, _tex.GetPixel(s.X, s.Y).b);
//if colour is not boundary colour
if(sCol != Color.black)
{
//add pixel to Q[]
m_List.Add(s);
}
}
}
// ----------
}
答案 0 :(得分:1)
您的算法一遍又一遍地添加相同的像素。它还有其他各种各样的问题,但这就是让它永远运行并消耗掉你所有记忆的原因。我认为你在这里尝试实施第三种算法:http://en.wikipedia.org/wiki/Flood_fill
你明显的区别是维基百科算法有:
11.如果n的北边节点的颜色是目标颜色,则将该节点添加到Q.
12.如果n的南边节点的颜色是目标颜色,则将该节点添加到Q.
...但是,您正在测试边界颜色,而不是目标颜色。你的算法将反复检测相同的像素,每次都注意到它们与边界颜色不同。
您还有其他一些问题: