计算机图形学(四)多边形的种子填充算法讲解与源代码

种子填充算法相比较扫描线填充算要容易的多了。理解起来也很简单。

源码下载:点我下载哦

简单的说一下算法的原理:

种子填充算法都是进行区域填充的,而且一般都是指定给某个区域填充某种颜色。然后给出区域的范围,让种子在区域中任选一点,然后按照“4-联通算法”和“8-联通算法”进行填充,而区域填充算法分为区域填充的递归算法和区域填充的扫描线算法。

种子填充算法:

首先填充种子点所在扫描线上的位于给定区域的一个区段;
然后确定与这一区段相连通的上、下两条扫描线上位于给定区域内的区段,并依次保存下来;
反复这个过程,直到填充结束。
 
(1) 初始化:堆栈置空。将种子点(x,y)入栈。
 
(2) 出栈:若栈空则结束。否则取栈顶元素(x,y),以y作为当前扫描线。
 
(3) 填充并确定种子点所在区段:从种子点(x,y)出发,沿当前扫描线向左、右两个方向填充,直到边界。分别标记区段的左、右端点坐标为xl和xr。
 
(4) 并确定新的种子点:在区间[xl,xr]中检查与当前扫描线y上、下相邻的两条扫描线上的象素。若存在非边界、未填充的象素,则把每一区间的最右象素作为种子点压入堆栈,返回第(2)步。
 
上述算法对于每一个待填充区段,只需压栈一次;因此,扫描线填充算法提高了区域填充的效率。

算法的效果图如下:
 

首先创建了一个坐标的结构体Seed和相关的函数。

 

 
  1. class ScanLineFill

  2. {

  3. public:

  4. typedef struct

  5. {

  6. int x;

  7. int y;

  8. }Seed;

  9. stack<Seed>Myseed;

  10. void ScanLineFill4(int x,int y,COLORREF oldcolor,COLORREF newcolor,CDC *pDC,HDC hdc);

  11. ScanLineFill();

  12. virtual ~ScanLineFill();

  13. };

然后给出核心的算法:

 

 
  1. ScanLineFill::ScanLineFill()

  2. {

  3. while(!Myseed.empty())

  4. {

  5. Myseed.pop();

  6. }

  7. }

  8.  
  9. ScanLineFill::~ScanLineFill()

  10. {

  11.  
  12. }

  13. void ScanLineFill::ScanLineFill4(int x,int y,COLORREF oldcolor,COLORREF newcolor,CDC *pDC,HDC hdc)

  14. {

  15. int xl,xr;

  16. bool spanNeedFill;

  17. Seed pt;

  18. pt.x=x;

  19. pt.y=y;

  20. Myseed.push(pt);

  21. while(!Myseed.empty())

  22. {

  23. pt=Myseed.top();

  24. Myseed.pop();

  25. y=pt.y;

  26. x=pt.x;

  27. while(GetPixel(hdc,x,y)==oldcolor)

  28. {

  29. pDC->SetPixel(x,y,newcolor);

  30. x++;

  31. }

  32. xr=x-1;

  33. x=pt.x-1;

  34. while(GetPixel(hdc,x,y)==oldcolor)

  35. {

  36. pDC->SetPixel(x,y,newcolor);

  37. x--;

  38. }

  39. xl=x+1;

  40. x=xl;

  41. y=y+1;

  42. while(x<=xr)

  43. {

  44. spanNeedFill=false;

  45. while(GetPixel(hdc,x,y)==oldcolor)

  46. {

  47. spanNeedFill=true;

  48. x++;

  49. }

  50. if(spanNeedFill)

  51. {

  52. pt.x=x-1;

  53. pt.y=y;

  54. Myseed.push(pt);

  55. spanNeedFill=false;

  56. }

  57. while(GetPixel(hdc,x,y)!=oldcolor&&x<=xr)

  58. x++;

  59. }

  60. x=xl;

  61. y=y-2;

  62. while(x<=xr)

  63. {

  64. spanNeedFill=false;

  65. while(GetPixel(hdc,x,y)==oldcolor)

  66. {

  67. spanNeedFill=true;

  68. x++;

  69. }

  70. if(spanNeedFill)

  71. {

  72. pt.x=x-1;

  73. pt.y=y;

  74. Myseed.push(pt);

  75. spanNeedFill=false;

  76. }

  77. while(GetPixel(hdc,x,y)!=oldcolor&&x<=xr)

  78. x++;

  79. }

  80.  
  81. }

  82. DeleteDC(hdc);

  83. }


算法还是很简单的,主要了解算法的主要工作原理。

然后该打的说一下源码的使用:

1.点击“种子的填充算法”,

2.点击“开始”,在网格中点击那个点,虽然线会自己连接起来,但是最后一个点不要和第一个点试图进行连接,点击“停止”会自动换链接。

3.点击种子颜色进行种子的颜色选择,并按照提示在多边形区域内点击一个点。作为种子。

4.点击“Move”算法边运行起来。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值