zoukankan      html  css  js  c++  java
  • 改进的Bresenham算法

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

    算法步骤:

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

    (2) 计算初始值dx, dy, e = -dx, x = x0, y = y0。

    (3) 绘制点 (x, y)。

    (4) e更新为e+2 * dy。判断e的符号,若e > 0, 则(x, y)更新为(x+1, y+1), 同时将e更新为e-2*dx;否则(x, y)更新为(x+1, y)。

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

    水平、垂直和|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 x, y, dx, dy, e;
    	// k does not exist
    	if (x1 == x2)
    	{
    		if (y1 < y2)
    		{
    			y = y1;
    			glBegin (GL_POINTS);
    			while (y <= y2)
    			{
    				glVertex2i (x1, y);
    				++ y;
    			}
    			glEnd ();
    		} // if (y1 < y2)
    		else
    		{
    			y = y2;
    			glBegin (GL_POINTS);
    			while (y <= y1)
    			{
    				glVertex2i (x1, y);
    				++ y;
    			}
    			glEnd ();
    		}
    	} // if (x1 == x2)
    	else if (y1 == y2) // k = 0
    	{
    		if (x1 < x2)
    		{
    			x = x1;
    			glBegin (GL_POINTS);
    			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 = 1
    		if (dx == dy)
    		{
    			glBegin (GL_POINTS);
    			while (x <= x2)
    			{
    				glVertex2i (x, y);
    				++ x;
    				++ y;
    			}
    			glEnd ();
    		}
    		else if (dx == -dy) // k = -1
    		{
    			glBegin (GL_POINTS);
    			while (x <= x2)
    			{
    				glVertex2i (x, y);
    				++ 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);
    				++ 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);
    				++ 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);
    				++ 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);
    				-- y;
    				e += dx;
    				if (e > 0)
    				{
    					++ x;
    					e += dy;
    				}
    			}
    			glEnd ();
    		}
    	}
    }
    
    void display (void)
    {
    	glClear (GL_COLOR_BUFFER_BIT);
    	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 (-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 ("optimized Bresenham line");
    	init ();
    	glutReshapeFunc (reshape);
    	glutDisplayFunc (display);
    	glutKeyboardFunc (keyboard);
    	glutMainLoop ();
    	return 0;
    }
    
  • 相关阅读:
    NOI-1.1-04输出保留3位小数的浮点数
    百练7619-合影效果-2015正式D题-简单排序&输出格式
    百练6376-二维数组右上左下遍历-2015正式C题
    C++ 开发环境配置
    go语言 http学习
    Git 命令及分支管理学习
    配置go语言编辑环境
    DNS的过程
    Split Array into Consecutive Subsequences
    组委会正在为美团点评CodeM大赛的决赛设计新赛制
  • 原文地址:https://www.cnblogs.com/ghl_carmack/p/1896565.html
Copyright © 2011-2022 走看看