【计算机图形学】-多边形扫描转换实验 (code included)

1. 问题描述:

理解示范程序的整个框架结构;在示范程序“DrawPolygon”中实现DrawPolygonOpenGL函数,该函数用OpenGL绘制多边形方法绘制多边形。在示范程序“DrawPolygon”中实现DrawPolygon函数,该函数实现多边形扫描转换算法。


2. 算法描述:

1) DrawPolygonOpenGL算法:

下面展示一些 伪代码

void DrawPolygonOpenGL(int g_iCtrlPntNum, wcPt2D g_pCtrlPoints[])
{
	 赋予颜色,光滑明暗处理
	 glBegin(GL_POLYGON);
	 for (遍历g_pCtrlPoints数组){
		 glVertex2f(g_pCtrlPoints[i].x, g_pCtrlPoints[i].y);
	 }
	 glEnd();
	 glFlush();
}

2) DrawPolygon算法:

(1) 初始化ET:将多边形各条边按照该边的ymin 值存放至ymin 所对应的ET存储桶中。
(2) 初始化AET为空表。
(3) 将y值设置成ET中所列的最小y值,即第-一个非空存储桶的y值。
(4) 重复执行以下各步,直至AET和ET都为空。
① 当扫描线的y值开始大于或等于ET中某个y桶的值时,将该桶的所有结点加入AET中(同时要从ET中删去),并将AET中的记录按x值排序。
② 对于扫描线y,在一对交点之间填充所需要的像素值。
③ 删去AET中y>ymax的项。
④ 更新AET中所有剩余结点的x值,用x+1/m代替x.当一个结点是在本轮循环中才进入AET时,它记录的x值为xmin⑤对AET中的各结点按x值重新排序。
⑥ y增1后进入下一轮循环。

下面展示一些 伪代码

// 数据结构:
struct vertex {
    float ver_x;
    float ver_y;
};
typedef struct XET {
    float x;
    float dx, ymax;
    XET* next;
}AET, NET;

vertex* ver;

// 函数:
void DrawPolygon(int g_iCtrlPntNum, wcPt2D  g_pCtrlPoints[])
{
    for(各条扫描线 i)
    {
        初始化 新边表头指针NET[i];
        把y(min)=i 的边放进新边表NET[i];       
    }
    y=最低扫描线号;
    初始化活性边表AET为空;
    for(各条扫描线i)
{
	 处理传入的顶点g_pCtrlPoints[],如果超出限定值则赋予限定值以保证点不会超出范围; 
初始化AET表,即初始化活跃边表; 初始化NET表,即初始化边表;
        把新边表NET[i]中的边结点用插入排序法插入活性边表AET中;
        遍历活性边表AET,将新边表中的活性边按照从左到右的顺序排序,删掉扫描线高度等同于ymax的废弃点,并以 x 坐标的值升序排列;
        对多边形进行填充;
    }
}


测试结果:

1) DrawPolygonOpenGL算法:

实际运行结果:
在这里插入图片描述

2) DrawPolygon算法:

实际运行结果:
在这里插入图片描述


分析与评论:

1) DrawPolygonOpenGL算法:

DrawPolygonOpenGL算法的思路很简单,只需在glBegin(GL_POLYGON)后用glVertex2f(x, y)进行描点即可完成对多边形的填充,体现出了OpenGL库函数的强大于便利;因为调用了库函数,所以时间复杂度不明;

2) DrawPolygon算法:

对比OpenGL库函数,DrawPolygon算法才是真正考验对多边形扫描转换的理解是否到位;首先,要构建活性边表AET和新边表NET,然后初始化AET表,即初始化活跃边表; 初始化NET表,即初始化边表;把新边表NET[i]中的边结点用插入排序法插入活性边表AET中;遍历活性边表AET,将新边表中的活性边按照从左到右的顺序排序,删掉扫描线高度等同于ymax的废弃点,并以 x 坐标的值升序排列;对多边形进行填充;
从空间复杂度上看,仅使用了大小为n的ver数组;
从时间复杂度上看,O((ymax-ymin)*边数);

评论:

DrawPolygonOpenGL算法画不出凸多边形与自相交多边形,而DrawPolygon算法可以通过软件的特性,不用CPU就可以画出凸多边形与自相交多边形,但是本次实验我仅实现了非自交多边形的绘制;

附录: Source Code(in C)

链接: 多边形扫描转换实验.rar

(代码仅供参考)

没有币的同学来Gitee吧!记得留下Star噢~
Jack-lllll 的Gitee仓库

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多边形扫描转换的扫描线算法是计算机图形学中常用的一种算法,它主要用于绘制一个给定多边形的内部区域。该算法的基本思路是将多边形分割成多个相邻的三角形,然后对每个三角形进行扫描线处理,最后将所有三角形的结果合并起来即可得到多边形的内部区域。 具体实现流程如下: 1. 对多边形进行三角剖分,将多边形分解成若干个相邻的三角形。 2. 对每个三角形,确定其三个顶点的坐标,并计算出三角形的边界框(Bounding Box)。 3. 对每个三角形的边界框,按照从上到下的顺序,生成一条扫描线,并将其分成若干个线段。 4. 对于每条扫描线,确定其与三角形的交点,并将这些交点按照从左到右的顺序排序。 5. 在相邻两个交点之间的区域内,填充颜色,得到该条扫描线的结果。 6. 将所有扫描线的结果合并起来,得到整个多边形的内部区域。 需要注意的是,在实际实现中,为了提高效率,可以使用一些优化技巧,例如: 1. 在确定扫描线与三角形的交点时,先判断该扫描线是否与三角形相交,如果不相交,则直接跳过该扫描线,以减少计算量。 2. 在排序交点时,可以使用快速排序等高效的算法,以减少排序时间。 3. 在填充颜色时,可以使用线段填充算法等高效的算法,以减少填充时间。 总之,多边形扫描转换的扫描线算法是一种常用的计算机图形学算法,它能够有效地处理多边形的内部区域,为图形渲染、图像处理等领域提供了重要的技术支持。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值