当前位置:
文档之家› 案例6 多边形有效边表填充算法
案例6 多边形有效边表填充算法
程序代码
(3)填充 BOOL bInFlag=FALSE; //区间内外测试标志,初始值为假表示区间外部 double xb,xe; //扫描线与有效边相交区间的起点和终点坐标 for(pT1=pHeadE;pT1!=NULL;pT1=pT1->pNext) { if(FALSE==bInFlag) { xb=pT1->x;bInFlag=TRUE; } else { xe=pT1->x; for(double x=xb;x<xe;x++) //左闭右开 { pDC->SetPixelV(Round(x),pCurrentB-> ScanLine,RGB(pT1->ps.c.red*255, pT1->ps.c.green*255,pT1->ps.c.blue*255)); }
计算机图形学实践教程(VisualC++版)(第2版)
案例6 多边形有效边表填充算法
孔令德 太原工业学院计算机工程系 2017.1.10
知识点
有效边表和桶表的数据结构。 颜色对话框的调用方法。 动态链表的排序算法。
案例描述
请使用有效边表算法填充示例多边形。该多边形覆盖
了12条扫描线,共有7个顶点和7条边。7个顶点分别为:
FillPolygon()函数。有效边表填充算法是后续填充物体表面模
型的基础,在绘制光滑物体时,常用于填充四边形网格或三 角形网格。
程序代码
(1)定义有效边表类CAET class CAET { public: CAET(); virtual ~CAET(); public: double x; int yMax; double k; CPi2 ps; CPi2 pe; CAET *pNext; };
//当前扫描线与有效边交点的x坐标 //边的最大y值 //斜率的倒数(x的增量) //边的起点 //边的终点
原理算法
(7)从有效边表中取出扫描线上相邻两条边的结点(交点)对进行配对。填充 时设置一个逻辑变量bInFlag(初始值为假),每访问一个结点,把bInFlag值取 反一次,若bInFlag为真,则把从当前结点的x值开始到下一结点的x值结束的区 间用指定颜色填充。 (8)循环下一桶结点,按照xi+1=xi+k(k的值为1/k)修改有效边表,同时合并桶 结点内的新边表,形成新的有效边表。 (9)如果桶结点的扫描线值大于等于有效边表中某个结点的ymax值,则该边成 为无效边。 (10)当桶结点不为空则转(6),否则删除桶表和边表的头结点,算法结束。
效果图
图6-1 色。 (2)根据示例多边形顶点坐标值,计算扫描线的最大值ScanMax和最小值 ScanMin。 (3)用多边形覆盖的扫描线动态建立桶结点。 (4)循环访问多边形的所有顶点,根据边的终点y值比起点y值高或边的终点y 值比起点y值低两种情况(边的终点y值和起点y值相等的情况属于扫描线,不予 考虑),计算每条边的ymin。在桶中寻找与该ymin相对应的桶结点,计算该边表 的x|ymin、yMax、k(代表1/k),并依次链接该边表结点到桶结点。 (5)对每个桶结点链接的边表,根据x|ymin值的大小进行排序,若x|ymin相等, 则按照k(代表1/k)由小到大排序。 (6)循环访问每个桶结点,将桶内每个结点的边表合并为有效边表,并循环访 问有效边表。
P0(1,2),P1(-3,6),P2(-5,1),P3(-3,-5), P4(0,-1), P5(2,-5), P6(6,3)。在1024×768的显示分辨率下,将多边 形顶点放大为P0(50,100),P1(-150,300),P2(-250,50), P3(-150,-250) ,P4(0,-50), P5 (100,-250), P6(300,150)。
程序代码
(3)填充 bInFlag=FALSE; } } for(pT1=pHeadE;pT1!=NULL;pT1=pT1->pNext) pT1->x=pT1->x+pT1->k; } //边的连续性
总结
本案例自定义CAET、CBucket和CFill类来填充示例多边 形。调用MFC提供的CColorDialog类来选择颜色。由于使用 调色板选择的颜色范围是0~255,所以使用CRGB类设置P1 数组的顶点颜色时,全部除以255进行归一化处理,参见
程序代码
(2)定义桶类CBucket 桶表定义了多边形覆盖的扫描线数,以及边在桶上的连接位置。 class CBucket { public: CBucket(); virtual ~CBucket(); public: int ScanLine; //扫描线 CAET *pET; //桶上的边表指针 CBucket *pNext; };