Алгоритм заливки области

fld.gif

Закрасить ограниченную линиями область.

Для того, чтобы залить некую область будем использовать обход клетчатого графа в ширину. Для каждой точки с координатами (x, y) закрасим точки с координатами (x + 1, y), (x - 1, y), (x, y - 1), (x, y + 1), если выполняется условие того, что они не выходят за границы окна и окрашены в тот же цвет, что и стартовая точка.

class pt {
public: 
  int x, y;
  pt(LPARAM lParam) : x(LOWORD(lParam)), y(HIWORD(lParam)) {}
  pt(int a, int b) : x(a), y(b) {}
};
 
pt a(0,0);
bool draw = false;
std::vector<pt> v;
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  int wmId, wmEvent;
  PAINTSTRUCT ps;
  HDC hdc;
 
  switch (message) 
  {
    case WM_COMMAND:
      wmId    = LOWORD(wParam); 
      wmEvent = HIWORD(wParam); 
      break;
    case WM_PAINT:
      hdc = BeginPaint(hWnd, &ps);
      {
        if (v.size() > 2) {
          int i;
          for (i = 0; i + 1 != v.size(); ++i) {
            MoveToEx(hdc, v[i].x, v[i].y, 0);
            LineTo(hdc, v[i + 1].x, v[i + 1].y);
          }
          MoveToEx(hdc, v[i].x, v[i].y, 0);
          LineTo(hdc, v[0].x, v[0].y);
        }
        if (draw) {
          draw = false;
          RECT rc;
          std::queue<pt> q;
          q.push(a);
          COLORREF col = GetPixel(hdc, a.x, a.y);
          GetClientRect(hWnd, &rc);
 
          while (!q.empty()) {
            pt t = q.front();
            q.pop();
 
            if (t.x > 0 && GetPixel(hdc, t.x - 1, t.y) == col) {
              q.push(pt(t.x - 1, t.y));
              SetPixel(hdc, t.x - 1, t.y, RGB(255, 0, 0));
            }
            if (t.x < rc.right && GetPixel(hdc, t.x + 1, t.y) == col) {
              q.push(pt(t.x + 1, t.y));
              SetPixel(hdc, t.x + 1, t.y, RGB(255, 0, 0));
            }
            if (t.y > 0 && GetPixel(hdc, t.x, t.y - 1) == col) {
              q.push(pt(t.x, t.y - 1));
              SetPixel(hdc, t.x, t.y - 1, RGB(255, 0, 0));
            }
            if (t.y < rc.bottom && GetPixel(hdc, t.x, t.y + 1) == col) {
              q.push(pt(t.x, t.y + 1));
              SetPixel(hdc, t.x, t.y + 1, RGB(255, 0, 0));
            }
          }
        }
 
      }
      EndPaint(hWnd, &ps);
      break;
    case WM_LBUTTONUP:
      v.push_back(pt(lParam));
      InvalidateRect(hWnd, 0, true);
      break;
    case WM_RBUTTONUP:
      draw = true;
      a = pt(lParam);
      InvalidateRect(hWnd, 0, true);
      break;
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

Ключевые слова: 
Заливка, Клетчатый граф, обход в ширину, bfs
ВложениеРазмер
flood.rar26.17 кб