Оказывается, все оказалось намного проще, чем я ожидал.Я думаю, я пытался сделать вещи слишком сложными.Из-за небольших размеров и того факта, что он не будет работать так часто, скорость на самом деле не является проблемой.
У меня нет доступа к тому, как я это сделал прямо сейчас, но это общая идея.
Каждый пиксель хранится в виде экземпляра SomePixelType.
Существует стек пикселей, который называется visitPixels.Пиксель считается возможным ребром многоугольника, если:
- Он имеет от 2 до 7 (оба включительно) черных соседних пикселей.
- Он отсутствует в коллекции посещенных пикселей.
SomePixelType имеет метод с именем GetNextPixel.
Когда вызывается GetNextPixel, он ищет соседние пиксели (начиная прямо вверх и по часовой стрелке) для возможного ребра многоугольника и возвращает его.Повторный вызов продолжит поиск с последнего матча.Как только все соседние пиксели будут проверены, он вернет ноль.
Когда пиксель установлен, этот метод будет вызван.
public Stack<SomePixelType> GetPolygonEdges(SomePixelType justSetPixel)
{
visitedPixels.Clear();
if(!justSetPixel.IsPossiblePolygon)
return null; // Not a possible edge. No closed polygon could of been completed.
visitedPixels.Push(justSetPixel);
SomePixelType currentPixel = justSetPixel;
while(visitedPixels.Count > 0)
{
currentPixel = currentPixel.GetNextPixel();
if(currentPixel == null) // No possible neighbouring polygon edges.
{
currentPixel = visitedPixels.Pop(); // Backtrack
continue;
}
if(currentPixel == justSetPixel)
return visitedPixels;
visitedPixels.Push(currentPixel);
}
return null; // Not closed.
}
С этого момента его довольно легко заполнить. Каквопрос был о поиске многоугольника, на этом я остановлюсь.