代码部分(MFC里的view类里实现的,使用栈需要添加头文件#include<iostream>)
void CSimpleDrawView::Seed_FillPolygon(int x, int y, COLORREF bcolor, COLORREF ncolor, CDC* pDC)
{
CRect rect;
GetClientRect(rect);
std::stack<CPoint> s;
CPoint p;
int left, right;
s.push(CPoint(x, y));
if (fill_polynum == -1) return;
find_maxmin_xy(fill_pts, fill_polynum1);
while (!s.empty())
{
//栈顶元素出栈
p = s.top();
s.pop();
//向左填充
for (left = p.x; pDC->GetPixel(left, p.y) != bcolor&&left>minx; left--)
pDC->SetPixel(left, p.y, ncolor);
//向右填充
for (right = p.x + 1; pDC->GetPixel(right, p.y) != bcolor&&right< maxx; right++)//以边界点为区间点
pDC->SetPixel(right, p.y, ncolor);
//在当前行的下一行寻找确定新的种子点
if(p.y-1>miny)
FindNewSeed(s, left, right, p.y - 1, bcolor, ncolor, pDC);
//在当前行的上一行寻找确定新的种子点
if(p.y+1<maxy)
FindNewSeed(s, left, right, p.y + 1, bcolor, ncolor, pDC);
}
}
void CSimpleDrawView::FindNewSeed(std::stack<CPoint>& s, int left, int right, int y, COLORREF bcolor, COLORREF ncolor, CDC* pDC)
{
for (int i = left + 1; i < right; i++)
{
if (pDC->GetPixel(i, y) != bcolor && pDC->GetPixel(i, y) != ncolor)
{
int j = i + 1;
while (pDC->GetPixel(j, y) != bcolor && j < right && pDC->GetPixel(j, y) != ncolor)
//while (pDC->GetPixel(j, y) != bcolor && pDC->GetPixel(j, y) != ncolor)
j++;
i = --j;
s.push(CPoint(j, y));
}
}
}
?边填充算法
在已经以颜色bcolor画出了多边形的情况下:
说明: pts为多边形点数组,num为点的数目,注意遍历的时候要看你的起点是否存了两次,即最后一个点是不是存了起点(因为多边形是闭合的)。
find_maxmin_xy(pts,num);用于找到多边形的边界,即边填充只在多边形的外接矩形区域进行,减少不必要的访问。
void CSimpleDrawView::sidefill(CPoint pts[], int num)
{
CDC* pDC = GetDC();
find_maxmin_xy(pts,num);
for (int i = 0; i < num-1; i++)
{
/*if (i == num - 1)
{
sideright_xor(pts[num - 1], pts[0], pDC);
}
else*/
{
sideright_xor(pts[i], pts[i + 1], pDC);
}
}
}
int CSimpleDrawView::sideright_xor(CPoint p1, CPoint p2, CDC* pDC)
{
if(p1.y==p2.y) return 0;
if (p1.y > p2.y)
{
CPoint temp;
temp = p1;p1 = p2;p2 = temp;
}
double m = (1.0 * p1.x - p2.x) / (p1.y-p2.y);
int y = p1.y;double x = p1.x;
while (y < p2.y)
{
x += m;
y++;
for (int right = maxx; right > x; right--)
{
pDC->SetROP2(R2_NOTXORPEN);
pDC->SetPixel(right, y, RGB(100, 149, 237));
}
}
return 1;
}
?
void CSimpleDrawView::find_maxmin_xy(CPoint p[], int num)
{
int x1 = p[0].x, y1 = p[0].y, x2 = p[0].x, y2 = p[0].y;
for (int i = 1; i < num; i++)
{
x1 = max(x1, p[i].x);
y1 = max(y1, p[i].y);
x2 = min(x2, p[i].x);
y2 = min(y2, p[i].y);
}
maxx = x1, maxy = y1, minx = x2, miny = y2;
}