Ну, я получаю план (путь) здания.И есть проблема.Когда я перебираю его пиксели, я проверяю, является ли текущий пиксель белым, чтобы начать обнаруживать его стены.
Что происходит с этим?Когда обнаружение заканчивается, оно начинается снова и снова, потому что следующий повторяющийся пиксель также белый.Вот почему мне нужно использовать алгоритм заливки (чтобы указать, что текущая сборка завершена).
Хорошо, я уже реализовал его, но у меня есть проблемы.
public static void FloodFill(ref Color[] source, Point pt, int width, int height, Color targetColor, Color replacementColor)
{
Stack<Point> pixels = new Stack<Point>();
targetColor = source[P(pt.x, pt.y, width, height)];
pixels.Push(pt);
while (pixels.Count > 0)
{
Point a = pixels.Pop();
if (source[P(a.x, a.y, width, height)] == targetColor)
{
source[P(a.x, a.y, width, height)] = replacementColor;
if (a.x > 0)
pixels.Push(new Point(a.x - 1, a.y));
if (a.x < width)
pixels.Push(new Point(a.x + 1, a.y));
if (a.y > 0)
pixels.Push(new Point(a.x, a.y - 1));
if (a.y < height)
pixels.Push(new Point(a.x, a.y + 1));
}
}
}
Извлеченоfrom: https://simpledevcode.wordpress.com/2015/12/29/flood-fill-algorithm-using-c-net/
Проблема здесь в том, что по какой-то причине ключевое слово ref не вступает в силу.
Моя реализация:
private IEnumerator MainGenerationDebug(Color[] source, Color32[] target, int width, int height)
{
// (1)
for (int i = 0; i < source.Length; Interlocked.Increment(ref i))
{
// (2)
Color c = source[i];
// (3)
int x = i % width,
y = i / width;
// (4) & (5)
yield return IntMapIteration(source, target, width, c, i, exceptions, (s, t) =>
{
source = s;
target = t;
});
// (6)
if (c == Color.white)
{
F.FloodFill(ref source, new Point(x, y), width, height, Color.white, Color.red);
}
}
}
Процессследующее:
- Я зацикливаю все пиксели, потому что я в другом потоке, я использую Interlocked.Increment.
- Я получаю текущий цвет
- Я получаютекущие x, y (2D) из индекса (1D)
- Из-за того, что я нахожусь в сопрограмме (я отлаживаю, поэтому мне нужно посмотреть, что происходит), я использую yielding
- КогдаIEnumerator заканчивает, я называю Действие.(Я использую IEnumerators, потому что я вызываю сопрограмму в Unity3D)
- После того, как все закончится, если текущий пиксель будет белым, я начну заполнять массив.
Я думаювсе правильно.Возможно, я что-то упустил.
Что вы можете сказать по этому поводу?