边标志法填充多边形

这里不仔细讲原理,只是把我写的算法发出来,跟大家分享下,如果有错误的话,还请大家告诉我,如果写的不好,也请指出来,一起讨论进步。

基本思想: 先用一种特殊的颜色在帧缓冲器中将多边形的边界(水平边界除外)勾画出来,然后将着色的像素点依x坐标递增的顺序两两配对,再将每一对像素所构成的扫描线区间内的所有像素置为填充色。具体分为两个步骤;

(1) 打标记。对多边形的每条边进行直线扫描转换。

(2) 填充。 对每条与多边形相交的扫描线,依从左到右顺序,按“左闭右开”的原则对扫描线上的像素点进行填充。使用一个布尔量inside来指示当前点的状态,若点在多边形内,则inside为真,否则为假。inside初值为假,第当当前访问像素为被打上标记的点时就把inside取反。对未打标记的像素,inside不变。若访问当前像素时,对inside作必要操作后,inside为真,由把该像素置为填充色。

下面是程序:

/*
*	Date: 11/23/2010
*/
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <vector>
#include <iostream>
#include <fstream>
using std::ofstream;
using std::ifstream;
using std::cout;
using std::endl;
ifstream cin ("polypoints.txt");
typedef struct _Point
{int x;int y;
}Point;typedef struct _PolyPoints
{Point * pPoint;						// Pointer to pointsint		n;							// Number of pointsint		yMax;						// Max y of all pointsint		yMin;						// Min y of all pointsint		xMax;						// Max x of all pointsint		xMin;						// Min x of all points
}PolyPoints;PolyPoints g_polyPoints;				// Storage for points of polygons
bool **	g_pbEdgeFlag;					// Edge flag
void inputPoints (void)
{int n;cin>>n;if (n < 3){cout<<"number of points can not be less than 3"<<endl;exit (0);}g_polyPoints.n = n;g_polyPoints.pPoint = new Point[n];g_polyPoints.yMax = INT_MIN;g_polyPoints.yMin = INT_MAX;g_polyPoints.xMax = INT_MIN;g_polyPoints.xMin = INT_MAX;int x, y;for (int i = 0; i < n; ++i){cin>>x>>y;g_polyPoints.pPoint[i].x = x;g_polyPoints.pPoint[i].y = y;if (g_polyPoints.yMax < y){g_polyPoints.yMax = y;}if (g_polyPoints.yMin > y){g_polyPoints.yMin = y;}if (g_polyPoints.xMax < x){g_polyPoints.xMax = y;}if (g_polyPoints.xMin > x){g_polyPoints.xMin = x;}}int xLen = g_polyPoints.xMax - g_polyPoints.xMin + 1;int yLen = g_polyPoints.yMax - g_polyPoints.yMin + 1;g_pbEdgeFlag = new bool *[yLen];for (int i = 0; i < yLen; ++i){g_pbEdgeFlag[i] = new bool [xLen];memset (g_pbEdgeFlag[i], 0, sizeof (bool) * xLen);}
}
// Free the memory
void destroy (void)
{int yLen = g_polyPoints.yMax - g_polyPoints.yMin + 1;for (int i = 0; i < yLen; ++i){delete g_pbEdgeFlag[i];}delete g_pbEdgeFlag;}
void scanConvertLineAndFlag (const Point & p1, const Point & p2)
{int x1 = p1.x;int y1 = p1.y;int x2 = p2.x;int y2 = p2.y;int x, y, dx, dy, e;// k does not existif (x1 == x2){if (y1 < y2){y = y1;glBegin (GL_POINTS);while (y <= y2){glVertex2i (x1, y);// Flag current pointbool bFlag = g_pbEdgeFlag[y-g_polyPoints.yMin][x1-g_polyPoints.xMin];g_pbEdgeFlag[y-g_polyPoints.yMin][x1-g_polyPoints.xMin] = !bFlag;++ y;}glEnd ();} // if (y1 < y2)else{y = y2;glBegin (GL_POINTS);while (y <= y1){glVertex2i (x1, y);// Flag current pointbool bFlag = g_pbEdgeFlag[y-g_polyPoints.yMin][x1-g_polyPoints.xMin];g_pbEdgeFlag[y-g_polyPoints.yMin][x1-g_polyPoints.xMin] = !bFlag;++ y;}glEnd ();}} // if (x1 == x2)else if (y1 == y2) // k = 0{if (x1 < x2){glBegin (GL_POINTS);x = x1;while (x <= x2){glVertex2i (x, y1);++ x;}glEnd ();} // if (x1 < x2)else {x = x2;glBegin (GL_POINTS);while (x <= x1){glVertex2i (x, y1);++ x;}glEnd ();}}else {if (x1 > x2){int temp = x1;x1 = x2;x2 = temp;temp = y1;y1 = y2;y2 = temp;}x = x1;y = y1;dx = x2 - x1;dy = y2 - y1;// k = 1if (dx == dy){glBegin (GL_POINTS);while (x <= x2){glVertex2i (x, y);// Flag current pointbool bFlag = g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin];g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin] = !bFlag;++ x;++ y;}glEnd ();}else if (dx == -dy) // k = -1{glBegin (GL_POINTS);while (x <= x2){glVertex2i (x, y);// Flag current pointbool bFlag = g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin];g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin] = !bFlag;++ x;-- y;}glEnd ();}else if (dy > dx)	// k > 1{glBegin (GL_POINTS);dx <<= 1;e = - dy;dy <<= 1;y = y1 > y2 ? y2 : y1;int maxY = y1 > y2 ? y1 : y2;while (y <= maxY){glVertex2i (x, y);// Flag current pointbool bFlag = g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin];g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin] = !bFlag;++ y;e += dx;if (e > 0){++ x;e -= dy;}}glEnd ();}else if (dy > 0)	// 0 < k < 1{e = -dx;dx <<= 1;dy <<= 1;glBegin (GL_POINTS);while (x <= x2){glVertex2i (x, y);// Flag current pointbool bFlag = g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin];g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin] = !bFlag;++ x;e += dy;if (e > 0){e -= dx;++ y;}}glEnd ();}else if (-dy < dx)	// 0 > k > -1{e = -dx;dx <<= 1;dy <<= 1;glBegin (GL_POINTS);while (x <= x2){glVertex2i (x, y);// Flag current pointbool bFlag = g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin];g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin] = !bFlag;++ x;e += dy;if (e < 0){-- y;e += dx;}}glEnd ();}else if (-dy > dx) // k < -1{e = dy;dx <<= 1;dy <<= 1;glBegin (GL_POINTS);y = y1 > y2 ? y1 : y2;int minY = y1 > y2 ? y2 : y1;while (y >= minY){glVertex2i (x, y);// Flag current pointbool bFlag = g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin];g_pbEdgeFlag[y-g_polyPoints.yMin][x-g_polyPoints.xMin] = !bFlag;e += dx;-- y;if (e > 0){++ x;e += dy;}}glEnd ();}}
}
void init (void)
{glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
}void flagAllEdges (void)
{Point * pPoint = g_polyPoints.pPoint;int n = g_polyPoints.n;for (int i = 0; i < n; ++ i){scanConvertLineAndFlag (pPoint[i], pPoint[(i+1)%n]);}for (int i = 0; i < n; ++i){int j1 = (i+n-1)%n;int j2 = (i+1)%n;if (pPoint[j1].y > pPoint[i].y && pPoint[j2].y > pPoint[i].y ||pPoint[j1].y < pPoint[i].y && pPoint[j2].y < pPoint[i].y){g_pbEdgeFlag[pPoint[i].y - g_polyPoints.yMin][pPoint[i].x - g_polyPoints.xMin] = false;}else{g_pbEdgeFlag[pPoint[i].y - g_polyPoints.yMin][pPoint[i].x - g_polyPoints.xMin] = true;}}
}void edgeFlagFillPolygon (void)
{int xLen = g_polyPoints.xMax - g_polyPoints.xMin + 1;int yLen = g_polyPoints.yMax - g_polyPoints.yMin + 1;int nScanLine = g_polyPoints.yMin;glBegin (GL_POINTS);for (int i = 0; i < yLen; ++i, ++ nScanLine){bool bFlag = false;int nHorizontal = g_polyPoints.xMin;for (int j = 0; j < xLen; ++j, ++ nHorizontal){if (g_pbEdgeFlag[i][j]){bFlag = !bFlag;}while (bFlag){glVertex2i (nHorizontal, nScanLine);++ j;++ nHorizontal;if (g_pbEdgeFlag[i][j]){bFlag = !bFlag;}}}}glEnd ();}void display (void)
{glClear (GL_COLOR_BUFFER_BIT);glLoadIdentity ();glColor3f (1.0f, 0.0f, 0.0f);//flagAllEdges ();// Fill a polygonedgeFlagFillPolygon ();glutSwapBuffers ();
}void reshape (int w, int h)
{glViewport (0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode (GL_PROJECTION);glLoadIdentity ();if (w <= h){gluOrtho2D (-600.0, 600.0, -600.0 * (GLfloat) h / (GLfloat) w, 600.0 * (GLfloat) h / (GLfloat) w);}else{gluOrtho2D (-600.0 * (GLfloat) w / (GLfloat) h,600.0 * (GLfloat) w / (GLfloat) h, -600.0, 600.0);}glMatrixMode (GL_MODELVIEW);glLoadIdentity ();
}
void keyboard (unsigned char key, int x, int y)
{switch (key){case 27: // 'VK_ESCAPE'exit (0);break;default:break;}
}
int main (int argc, char ** argv)
{glutInit (&argc, argv);glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);glutInitWindowSize (600, 600);glutCreateWindow ("Bresenham line");init ();inputPoints ();flagAllEdges ();glutReshapeFunc (reshape);glutDisplayFunc (display);glutKeyboardFunc (keyboard);glutMainLoop ();destroy ();return 0;
}
polypoints.txt中的示例内容如下:
7
30 120
10 70
30 10
60 50
80 10
120 90
70 80


转载于:https://www.cnblogs.com/ghl_carmack/archive/2010/12/04/1896644.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/495677.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA将html[动态]页面转成图片

近日项目上接到一个任务&#xff0c;设计并编写住院病案首页页面&#xff0c;然后将其转换成图片显示给医生查看。 天哪&#xff0c;住院病案内容那么多&#xff0c;光编写这个页面就已经够呛了&#xff0c;转图片我也没弄过&#xff0c;于是百度了一下&#xff0c;花了两天时间…

王爽 汇编语言第三版 课程设计 1

From&#xff1a;https://www.cnblogs.com/Since-natural-ran/p/6938133.html 汇编语言-课程设计1: https://www.cnblogs.com/tsembrace/p/3267158.html 王爽课程设计1(汇编语言编写): https://www.imooc.com/article/18785 王爽《汇编语言》课程设计1: https://blog.csdn.net/…

挑战权威还是偏离主流?颠覆性研究或将证明神经信号是机械波

来源&#xff1a;科研圈 翻译 马骁骁 编辑 魏潇 廖红艳就职于哥本哈根尼尔斯玻尔研究所&#xff08;Niels Bohr Institute&#xff09;的托马斯亨伯格&#xff08;Thomas Heimburg&#xff09;&#xff0c;是一位研究量子力学和生物物理的物理学家。然而&#xff0c;他却希…

史上最全的女人坐月子注意事項

希望男人们要精心照顾好妻子&#xff0c;让妻子平安度过这一时期&#xff0c;为了宝宝&#xff0c;为了你们的幸福&#xff0c;因为你爱她就要呵护她&#xff0c;她好你也好&#xff0c;她平安就是你们全家的幸福&#xff0c;精致女人把祝福送给你们&#xff01; 传统上人们将产…

java安全解压文件

方法一 public class Decompression {private static final Logger LOGGER Logger.getLogger(Decompression.class);private static final int BUFFER 512;private static final int TOO_BIG 0x6400000;private static final int TOO_MANY 1024;private Decompression() {…

汇编语言 test 和 cmp 区别

From&#xff1a;https://blog.csdn.net/zz709196484/article/details/77755243 看过破解教程&#xff0c;都知道 test&#xff0c;cmp 是比较关键&#xff0c;可是我一直不清楚它们究竟是怎么比较的&#xff0c;最后下决心找了很多资料&#xff0c;和大家一起把它们弄清楚. 首…

斯坦福大学、DARPA与硅谷公司共同分析前沿科技发展趋势

来源&#xff1a;科技日报 作者&#xff1a;张梦然日前&#xff0c;斯坦福大学研究团队、美国国防部高级研究计划局&#xff08;DARPA&#xff09;以及硅谷创投公司和米资本的专家们&#xff0c;共同研讨了技术将如何重塑行业和社会等问题。他们分析了现今全球前沿科技的未来…

利用cookie的跨域单点登录的简单实现

Configuration:1. Web.Config在两个站点的配置配置文件machine节点上相同的validationKey, decryptionKey and validation的值&#xff0c;如<machineKey validationKey"282487E295028E59B8F411ACB689CCD6F39DDD21E6055A3EE480424315994760ADF21B580D8587DB675FA02F791…

小甲鱼 OllyDbg 教程系列 (一) :二进制破解科普系列之 ReverseMe

小甲鱼 视频教程&#xff08; 4、5 集 &#xff09;&#xff1a;https://www.bilibili.com/video/av6889190?p4 实验程序 reverseME.exe 下载地址&#xff1a;https://pan.baidu.com/s/18NDV3rQ_yV_qzUrNRYmqjA 提取码&#xff1a;e91j http://www.360doc.com/content/1…

java将字符串生成图片

java将字符串保存为图片 因为最近接触到的需求是要将指定的字符串内容保存为图片&#xff0c;我知道肯定要用awt相关的东西&#xff0c;但是以前没有接触过awt&#xff0c;所以只能去网上学习相关的东西和找有关的资料&#xff0c;好在最后可以解决&#xff0c;直接上代码&…

开源的关系型数据持久化组件

Apache Empire-db 是一个开源的关系型数据持久化组件&#xff0c;能够实现数据库无关的动态查询定义&#xff0c;简便的数据读取和更新。与其它持久化组件相比 如&#xff1a;Hibernate、TopLink、iBATIS或JPA实现&#xff0c;Empire-db更注重编译期类型安全&#xff0c;减少冗…

AI 综述专栏 | 超长综述让你走近深度人脸识别

来源&#xff1a;人工智能前沿讲习班 作者&#xff1a; 葛政相信做机器学习或深度学习的同学们回家总会有这样一个烦恼&#xff1a;亲朋好友询问你从事什么工作的时候&#xff0c;如何通俗地解释能避免尴尬&#xff1f;我尝试过很多名词来形容自己的工作&#xff1a;机器学习&…

祝各位网友儿童节快乐!

儿童节就要到了&#xff0c;借此机会&#xff0c;给自己的童心放个假吧。 如果你不知道如何度过&#xff0c;可以参考以下建议&#xff1a; 建议一&#xff1a;在自己的房间开心的裸爬&#xff1b; 建议二&#xff1a;穿着鞋在自己的床上狂蹦&#xff1b; 建议三&#xff1a;披…

机器人也能拥有人类情感:“情感计算”让机器人学会“读心术”

来源&#xff1a;《情感计算与情感机器人系统》作者&#xff1a;吴敏&#xff0c;刘振焘&#xff0c;陈略峰著随着机器人进入日常生活中的各个方面&#xff0c;人们对其提出了更高的要求&#xff0c;希望它们具有感知人类情感、意图的能力&#xff0c;这类机器人称为情感机器人…

C 语言 函数调用栈

From&#xff1a;https://www.cnblogs.com/clover-toeic/p/3755401.html https://www.cnblogs.com/clover-toeic/p/3756668.html 程序的执行过程可看作连续的函数调用。当一个函数执行完毕时&#xff0c;程序要回到调用指令的下一条指令(紧接call指令)处继续执行。函数调用过…

SQL脚本:监控当前重做日志文件使用情况

这个脚本可以用来分析当前重做日志文件(redo logfile)已被用到了什么位置(position)、还剩余多少空间和已使用的百分比: set linesize 200 pagesize 1400; select le.leseq "Current log sequence No",100 * cp.cpodr_bno / le.lesiz "Percent Full",(cpod…

Apache HttpClient 详解

1、简介 HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中&#xff0c;比如 Apache Jakarta 上很著名…

寒武纪创始人兼CEO陈天石博士的公开信

来源&#xff1a;来源&#xff1a;寒武纪科技摘要&#xff1a;2018年5月3日&#xff0c;寒武纪已在中国上海发布了首款云端智能芯片MLU100及相应的板卡产品。作为寒武纪的创始人和CEO&#xff0c;我非常自豪地与大家分享一个消息&#xff1a;2018年5月3日&#xff0c;寒武纪已在…

压栈, 跳转,执行,返回:从汇编看函数调用

From&#xff1a;https://www.jianshu.com/p/594357dff57e C函数调用过程原理及函数栈帧分析&#xff1a;https://blog.csdn.net/zsy2020314/article/details/9429707 从本篇开始&#xff0c;我们讨论一些高级语言中的基础设施&#xff1a;堆栈&#xff0c;函数调用&#xff0…