Bresenham画椭圆算法

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

算法步骤:

(1) 输入椭圆的长半轴a和短半轴b。

(2) 计算初始值d = b*b + a * a * (-b + 0.25),  x = 0, y = b。

(3) 绘制点 (x, y)及其在四分象限上的另外3个对称点。

(4) 判断d的符号。若d <= 0,则先将d更新为d + b * b * (2 * x + 3),再将 (x, y)更新为(x+1, y);否则先将d更新为d + b * b * (2 * x + 3) + a * a (-2 * y + 2),再将(x, y)更新为(x+1, y-1)。

(5) 当b*b * (x+1) < a * a * (y - 0.5)时,重复步骤(3)和(4),否则转到步骤(6)。

(6) 用上半部分计算的最后点(x, y)来计算下半部分中d的初值: d = b * b * (x + 0.5) * (x + 0.5) + a * a * (y - 1) * (y - 1) - a * a * b * b。

(7) 绘制点(x, y)及其在四分象限上的另外3个对称点。

(8) 判断d的符号。若d <= 0,则先将d更新为d + b * b * (2 * xi + 2) + a * a * (-2 * yi + 3), 再将(x, y)更新为(x+1, y-1);否则先将d更新为d + a * a * (-2 * yi + 3),再将(x, y)更新为(x, y-1)。

(9) 当y >= 0, 重复步骤(7)和(8),否则结束。

下面是算法:

 

#include <GL/freeglut.h>

void init (void)

{

	glClearColor (0.0f, 0.0f, 0.0f, 1.0f);

}



void drawEllipse (int a, int b, int xLoc, int yLoc)

{

	glPushMatrix ();

	int x, y;

	float d1, d2, aa, bb;

	aa = a * a;

	bb = b * b;

	d1 = bb + aa * (-b + 0.25);

	glTranslatef ((GLfloat) xLoc, (GLfloat) yLoc, 0.0f);

	x = 0; 

	y = b;

	glBegin (GL_POINTS);

	glVertex2i ( x,  y);

	glVertex2i (-x,  y);

	glVertex2i (-x, -y);

	glVertex2i ( x, -y);

	while (bb * (x + 1) < aa * (y - 0.5))

	{

		if (d1 <= -0.000001)

		{

			d1 += bb * ((x << 1) + 3);



		}

		else

		{

			d1 += bb * ((x << 1) + 3) + aa * (2 - (y << 1));

			-- y;

		}

		++ x;

		glVertex2i ( x,  y);

		glVertex2i (-x,  y);

		glVertex2i (-x, -y);

		glVertex2i ( x, -y);

	}

	d2 = bb * (0.25 * x) + aa * (1 - (y << 1));

	while (y > 0)

	{

		if (d2 <= -0.000001)

		{

			++ x;

			d2 += bb * ((x + 1) << 1) + aa * (3 - (y << 1));

		}

		else

		{

			d2 += aa * (3 - (y << 1));

		}

		-- y;

		glVertex2i ( x,  y);

		glVertex2i (-x, -y);

		glVertex2i (-x,  y);

		glVertex2i ( x, -y);

	}

	glEnd ();

	glPopMatrix ();

}



void display (void)

{

	glClear (GL_COLOR_BUFFER_BIT);

	glLoadIdentity ();

	glColor3f (1.0f, 0.0f, 0.0f);

	// draw a ellipse

	drawEllipse (200, 300, 50, 50);

	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 ellipse");

	init ();

	glutReshapeFunc (reshape);

	glutDisplayFunc (display);

	glutKeyboardFunc (keyboard);

	glutMainLoop ();

	return 0;

}

 

你可能感兴趣的:(res)