区域填充的扫描线算法

区域填充的扫描线算法适用于内点表示的4连通区域。算法的基本过程是:给定种子点(x, y),先填充种子点所在扫描线上的位于给定区域的区段,然后确定与该区段相连通的上下两条扫描线上的位于给定区域的区段,并保存下来。对保存下来的区段,反复这个过程,直到没有要处理的区段为止。

如下图所示:

一个原来是灰色的田字和三角形区域,使用鼠标在区域里面点击一下,就会被填充为青色。

以下是填充函数的主要代码:

typedef struct { int y, xLeft, xRight; } Span;
#define STACK_SIZE 100//max stack size is 100
Span S[STACK_SIZE];
int top = 0;
void SetStackEmpty()
{
 top = 0;
}
bool isStackEmpty()
{
 return top == 0;
}
bool PushStack(Span *pS)
{
 if (top < STACK_SIZE)//stack is not full
 {
  S[top] = *pS;
  top++;
  return true;
 }
 else
  return false;
}
bool PopStack(Span *pS)
{
 if (top > 0)
 {
  top--;
  *pS = S[top];
  return true;
 }
 else
  return false;
}
void ScanLineFill4(HDC hdc, int x, int y, int oldColor, int newColor)
{
 Span span;
 span.y = y;
 span.xLeft = x; 
 while (GetPixel(hdc, span.xLeft, span.y) == oldColor)
 {
  SetPixel(hdc, span.xLeft, span.y, newColor);
  span.xLeft--;
 }
 if (span.xLeft == x)//not a seed point actually
  return;
 else
  span.xLeft++;//compansate
 span.xRight = x + 1;
 while (GetPixel(hdc, span.xRight, span.y) == oldColor)
 {
  SetPixel(hdc, span.xRight, span.y, newColor);
  span.xRight++;
 }
 if (span.xRight == x + 1)//cannot extend to right
  span.xRight = x;
 else
  span.xRight--;//compansate

 SetStackEmpty();
 PushStack(&span);

 while (!isStackEmpty())
 {
  PopStack(&span);
  Span S;//new span
  {
   S.y = span.y + 1;
   S.xLeft = span.xLeft;
   bool xLeftNotSet = false;
   while (GetPixel(hdc, S.xLeft, S.y) == oldColor)
   {
    S.xLeft--;
   }
   if (S.xLeft == span.xLeft)//xLeft is not set
    xLeftNotSet = true;
   else
    S.xLeft++;//compansate
   int i = S.xLeft;
   while (i <= span.xRight)
   {
    while (GetPixel(hdc, i, S.y) == oldColor)
    {
     if (xLeftNotSet)
     {
      S.xLeft = i;
      xLeftNotSet = false;
     }
     SetPixel(hdc, i, S.y, newColor);
     i++;
    }
    if (i > S.xLeft)
    {
     S.xRight = i - 1;
     PushStack(&S);
     xLeftNotSet = true;
    }
    while (i <= span.xRight && GetPixel(hdc, i, S.y) != oldColor)
    {
     i++;
    }
   }
  }
  {//similar to above
   S.y = span.y - 1;
   S.xLeft = span.xLeft;
   bool xLeftNotSet = false;
   while (GetPixel(hdc, S.xLeft, S.y) == oldColor)
   {
    S.xLeft--;
   }
   if (S.xLeft == span.xLeft)//xLeft is not set
    xLeftNotSet = true;
   else
    S.xLeft++;//compansate
   int i = S.xLeft;
   while (i <= span.xRight)
   {
    while (GetPixel(hdc, i, S.y) == oldColor)
    {
     if (xLeftNotSet)
     {
      S.xLeft = i;
      xLeftNotSet = false;
     }
     SetPixel(hdc, i, S.y, newColor);
     i++;
    }
    if (i > S.xLeft)
    {
     S.xRight = i - 1;
     PushStack(&S);
     xLeftNotSet = true;
    }
    while (i <= span.xRight && GetPixel(hdc, i, S.y) != oldColor)
    {
     i++;
    }
   }
  }
 }
}

程序环境VC/GDI,完整的程序从这里下载:http://download.csdn.net/detail/qiuchangyong/9762900



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值