您的位置:首页 > 其它

区域填充的扫描线算法

2017-02-24 13:38 423 查看
区域填充的扫描线算法适用于内点表示的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



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: