中点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;

}

 

你可能感兴趣的:(res)