中点画圆法

圆在计算机生成的算法可以通过中点画圆法实现:

假设圆的方程为:x2+y2=r2

则有函数:F(x,y)=x2+y2-r2

当F(x,y)>0时,对应的点(x,y)在圆外;

当F(x,y)<0时,对应的点(x,y)在圆外;

当F(x,y)=0时,对应的点(x,y)在圆上。



在第一象限上半1/8圆弧,如果已得到圆弧的象素点P(xp,yp),则下一可能的象素点是P1(xp+1,yp)和

P2(xp+1,yp-1)。究竟是P1还是P2 ,由P1和P2的中点M(xp+1,yp-0.5)的函数值F(xm,ym)来决定:


如果F(xm,ym)<0,说明圆弧在P1和M之间,取P1点为下一象素。

且下一象素的F(xp+2,yp-0.5)=F(xp+1,yp-0.5)+2xp+3

如果F(xm,ym)≥0,说明圆弧在P2和M之间,则取P2为下一象素。

且下一象素的F(xp+2,yp-1.5)=F(xp+1,yp-0.5)+2(xp-yp)+5

而F(1,r-0.5) = 1.25-r


计算机生成圆的C语言代码如下:

 

#include 
#include 
#include 
#include 
#include 

void init(void);
void CALLBACK reshape(GLsizei w,GLsizei h);
void CALLBACK display(void);
void MidCircle(int x0, int y0, int r);

void init(void)
{
	glClearColor(0.0f,0.0f,0.0f,0.0f);
	glClear(GL_COLOR_BUFFER_BIT);
}

void CALLBACK reshape(GLsizei w,GLsizei h)
{
	glViewport(0,0,w,h);
}

//画完整圆的子程序
void MidCircle(int x0, int y0, int r)   //圆心为(x0, y0),半径为r
{
	int x,y;
	float f;
	x=0;y=r;f=1.25-r;
	glBegin(GL_POINTS);
	glVertex2d(x0*10,(y0+r)*10);
	glVertex2d(x0*10,(y0-r)*10);
	glVertex2d((x0+r)*10,y0*10);
	glVertex2d((x0-r)*10,y0*10);
	glEnd();
	while(x<=y){
		if(f<0)
			f+=2*x+3;
		else{
			f+=2*(x-y)+5;
			y--;
		}
		x++;
		glBegin(GL_POINTS);
		glVertex2d((x0+x)*10,(y0+y)*10);
		glVertex2d((x0-x)*10,(y0+y)*10);
		glVertex2d((x0+x)*10,(y0-y)*10);
		glVertex2d((x0-x)*10,(y0-y)*10);
		glVertex2d((x0+y)*10,(y0+x)*10);
		glVertex2d((x0-y)*10,(y0+x)*10);
		glVertex2d((x0+y)*10,(y0-x)*10);
		glVertex2d((x0-y)*10,(y0-x)*10);
		glEnd();
	}
}

void CALLBACK display(void)
{
	int i;
	int x0=5 ,y0=5 ,r=3;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(-10.0, 110.0, -10.0, 110.0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	//画10*10的网格
	glColor3f(0.0f,1.0f,0.0f); //绿色
	for(i=0; i<=10; i++) //10条水平线
	{
		glBegin(GL_LINES);
			glVertex2d(  0.0,i*10.0);
			glVertex2d(100.0, i*10.0);
		glEnd();
	}
	glBegin(GL_LINES); //10条竖线
		for(i=0; i<=10; i++)
		{
			glVertex2d(i*10.0,  0.0);
			glVertex2d(i*10.0, 100.0);
		}
	glEnd();

	//把判断出圆的点画在生成的网格上
	glColor3f(1.0f,1.0f,1.0f); //白色
	glPointSize(10.0f); //点的大小
	MidCircle(x0, y0, r);//调用画圆的子程序
	glFlush();
}

void main(void)
{
	auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);
	auxInitPosition(0,0,500,500);
	auxInitWindow("GL_0_2d");
	init();

	auxReshapeFunc(reshape);
	auxMainLoop(display);
}


猜你喜欢

转载自blog.csdn.net/Mr_Grit/article/details/40476313