• 中点Bresenham 算法及实现


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

    只写出0<=k<=1时的Bresenham算法绘图过程

    (1) 输入直线的两端点,P0(x0, y0)和P1(x1, y1).

    (2) 计算初始值dx, dy, d = dx - 2 * dy, x = x0, y = y0.

    (3) 绘制点(x, y), 判断d的符号。若d < 0, 则(x, y)更新为(x+1, y+1), d更新为d + 2 * dx - 2 * dy;否则(x, y)更新为(x+1, y), d 更新为d - 2 * dy

    (4)当直线没有画完时,重复步骤 (3),否则结束。

    水平、垂直和|k| = 1的直线可以直接装入帧缓冲存储器而无须进行画线处理,我的程序也处理了下。下面我把自己写的程序写下来,与大家分享,如有错误还请指出,只是粗略得测试了下没发下错误。

    #include <GL/freeglut.h>
    void init (void)
    {
    	glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
    }
    
    void drawLine (int x1, int y1, int x2, int y2)
    {
    	int dx, dy, d, upInc, downInc, leftInc, rightInc, x, y;
    	if (x1 == x2)
    	{
    		// 斜率 k 不存在
    		if (y1 < y2)
    		{
    			y = y1;	
    			glBegin (GL_POINTS);
    			do 
    			{
    
    				glVertex2i (x1, y);
    				++ y;
    			}while (y <= y2);
    			glEnd ();
    
    		}
    		else
    		{
    			y = y2;
    			glBegin (GL_POINTS);
    			do 
    			{
    				glVertex2i (x1, y);
    				++ y;
    			}while (y <= y1);
    			glEnd ();
    		}
    
    	}
    	else if (y1 == y2)
    	{
    		// k = 0
    		if (x1 < x2)
    		{	
    			glBegin (GL_POINTS);
    
    			x = x1;
    			do
    			{
    				glVertex2i (x, y1);
    				++ x;
    			}while (x <= x2);	
    			glEnd ();
    
    		}
    		else
    		{
    			glBegin(GL_POINTS);
    			x = x2;
    			do
    			{
    				glVertex2i (x, y1);
    				++ x;
    			}while (x <= x1);
    			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 == 1
    		if (dx == dy)
    		{
    
    			glBegin (GL_POINTS);
    			do 
    			{
    				glVertex2i (x, y);
    				++ x;
    				++ y;
    			}while (x <= x2);
    			glEnd ();
    		}
    		// k == -1
    		else if (dx == -dy)
    		{
    			glBegin (GL_POINTS);
    			do
    			{
    				glVertex2i (x, y);
    				++ x;
    				-- y;
    			}while (x <= x2);
    			glEnd ();
    		}
    		else 
    		{
    			
    			if (dy > 0)
    			{	
    				// 0 <k < 1
    				if (dy < dx)
    				{
    					dy <<= 1;
    					d = dx - dy;
    					dx <<= 1;
    					upInc = dx - dy;
    					downInc = -dy;	
    					glBegin (GL_POINTS);
    
    					while (x <= x2)
    					{	
    						glVertex2i (x, y);
    						++ x;
    						if (d < 0)
    						{
    							++ y;
    							d += upInc;
    						}
    						else
    						{
    							d += downInc;
    						}
    					}
    					glEnd ();
    
    				}
    				else 
    				{
    					// k > 1
    					dx <<= 1;
    					d =  dx - dy;
    					dy <<= 1;
    					rightInc = dx - dy;
    					leftInc = dx;
    					glBegin (GL_POINTS);
    					while (y <= y2)
    					{
    						glVertex2i (x, y);
    						++ y;
    						if (d > 0)
    						{
    							++ x;
    							d += rightInc;
    						}
    						else 
    						{
    							d += leftInc;
    						}
    					} // while 
    					glEnd ();
    
    				}
    			} // if (dy > 0)
    			else
    			{
    				// 0 > k > -1
    				if (-dy < dx)
    				{
    					dy <<= 1;
    					d = -dx - dy;
    					dx <<= 1;
    					downInc = -dx - dy;
    					upInc = -dy;
    					glBegin (GL_POINTS);
    					while (x <= x2)
    					{
    						glVertex2i (x, y);
    						++ x;
    						if (d > 0)
    						{
    							d += downInc;
    							-- y;
    						}
    						else
    						{
    							d += upInc;
    						}
    					}	// while
    					glEnd ();
    				} // if (-dy > dx)
    				else
    				{
    					// k < -1
    					dx <<= 1;
    					d = -dx - dy;
    					dy <<= 1;
    					leftInc = - dx;
    					rightInc = -dx - dy;
    					glBegin (GL_POINTS);
    					while (y >= y2)
    					{
    						glVertex2i (x, y);
    						-- y;
    						if (d < 0)
    						{
    							d += rightInc;
    							++ x;
    						}
    						else
    						{
    							d += leftInc;
    						}
    					}
    					glEnd ();
    				}
    			}
    		}
    	}
    }
    
    void display (void)
    {
    	glClear (GL_COLOR_BUFFER_BIT  | GL_DEPTH_BUFFER_BIT);
    	glLoadIdentity ();
    	glColor3f (1.0f, 0.0f, 0.0f);
    	// Vertical line
    	drawLine (0, -200, 0, 200);
    	// Horizontal line
    	drawLine (-200, 0, 200, 0);
    	// k = 1 line
    	drawLine (-200, -200, 200, 200);
    	// k = -1 line
    	drawLine (-200, 200, 200, -200);
    	// k = 1/2 line
    	drawLine (200, 100, -200, -100);
    	// k = 2 line
    	drawLine (-100, -200, 100, 200);
    	// k = -1/2 line
    	drawLine (-200, 100, 200, -100);
    	// k = -2 line
    	drawLine (-100, 200, 100, -200);
    
    	drawLine (30, 120, 10, 70);
    
    	drawLine (10, 70, 30, 10);
    
    	drawLine (30, 10, 60, 50);
    
    	drawLine (60, 50, 80, 10);
    
    	drawLine (80, 10, 120, 80);
    
    	drawLine (120, 80, 70, 80);
    
    	drawLine (70, 80, 30, 120);
    	glutSwapBuffers ();
    }
    
    void reshape (int w, int h)
    {
    	glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    	glMatrixMode (GL_PROJECTION);
    	glLoadIdentity ();
    	if (w <= h)
    	{
    		gluOrtho2D (-200.0, 200.0, -200.0 * (GLfloat) h / (GLfloat) w, 200.0 * (GLfloat) h / (GLfloat) w);
    	}
    	else
    	{
    		gluOrtho2D (-200.0 * (GLfloat) w / (GLfloat) h,200.0 * (GLfloat) w / (GLfloat) h, -200.0, 200.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 | GLUT_DEPTH);
    	glutInitWindowSize (600, 600);
    	glutCreateWindow ("Bresenham line");
    	init ();
    	glutReshapeFunc (reshape);
    	glutDisplayFunc (display);
    	glutKeyboardFunc (keyboard);
    	glutMainLoop ();
    	return 0;
    }
    
  • 相关阅读:
    Nginx 相关配置文件修改
    LNMP平台构建实验 +bbs社区搭建
    CSGO项目
    创世战车项目
    IGXE搬砖项目
    11_samba服务器的搭建
    26_django内置static标签
    06_git添加远程仓库并向远程仓库中推送代码
    23_添加apps到项目的搜索路径
    23_django日志器的配置和其使用方法
  • 原文地址:https://www.cnblogs.com/ghl_carmack/p/1896553.html
Copyright © 2020-2023  润新知