计算机图形学实战——Bresenham八分法画圆

Bresenham算法完成八分法画圆

圆光栅化算法
简单方程产生圆弧
圆的函数方程与极坐标方程在此不再赘述
算法原理为离散计算,表示出圆;
计算机图形学实战——Bresenham八分法画圆_第1张图片
但这种算法计算比较复杂,需要改进。
若采用极坐标画法则有
计算机图形学实战——Bresenham八分法画圆_第2张图片

利用圆的八方对称性画圆

采用递推的方法:

void Bresenham_drawcircle(GLint R) {    //默认原点是0,0 bresenham算法画圆
	GLint x = 0;
	GLint y = R;
	GLint d = 3 - 2 * R;
	glBegin(GL_POINTS);
	glPointSize(pointsize);
	while (x < ((int)(R*1.0 / (sqrt(2)))))
	{
		glVertex2i(x, y);         //八分画圆
		glVertex2i(-x, -y);
		glVertex2i(-x, y);
		glVertex2i(x, -y);
		glVertex2i(y, -x);
		glVertex2i(-y, -x);
		glVertex2i(-y, x);
		glVertex2i(y, x);
		x = x + 1;
		if (d >= 0) {
			y = y - 1;
			d = d + 4 * (x - y) + 10;
		}
		else {
			d = d + 4 * x + 6;

		}
	}
		glEnd();//结束

		glFlush();

}

完整代码如下所示:


#include <GL/glut.h> 
#include<iostream>
#include<math.h>
using namespace std;
GLfloat pointsize = 1.0f;
void init(void)
{

	glClearColor(0.0, 0.0, 0.0, 0.0);//设置背景颜色为黑色

	glShadeModel(GL_SMOOTH);//设置为光滑明暗模式
	gluOrtho2D(-300.0, 300.0, -300.0, 300.0);///*设定映射区域,参数为(minX,maxX,minY,maxY),(minX,minY为原点);(maxX, maxY)为右上角的点* /
}
double D2R(double deg) {
	return deg / 180.0 * 3.14159265;
}
void Bresenham_drawOneLine(GLint xs, GLint ys, GLint xe, GLint ye) {
	GLint  x = xs;
	GLint  y = ys;
	int  flag;//用以表示是否发生了交换
	GLint dx = abs(xe - xs);
	GLint dy = abs(ye - ys);
	GLint sx = ((xe > xs)?1:-1);
	GLint sy = ((ye > ys)?1:-1);
	if (dy > dx)
	{
		swap(dx, dy);
		flag = 1;
	}
	else
	{
		flag = 0;
	}
	cout << flag;
	GLfloat Nerror =2*dy - dx;//开始在光栅点处,d=0,下一个点处d=k
	for (int i = 1; i < dx; i++)
	{
		glBegin(GL_LINES);
		//glColor3f(1.0f, 0.0f, 0.0f);
		//cout << x << y << endl;
		glVertex2i(x, y);
		if (Nerror>=0)
		{
			if (flag)
			{
				x = x + sx;
			}
			else
			{
				y = y + sy;
			}
			Nerror = Nerror - 2*dx;	
		}
		if (flag)
		{
			y = y + sy;
		}
		else
		{
			x = x + sx;
		}
		Nerror = Nerror + 2*dy;
	}
	glEnd();//结束

	glFlush();

	/*OpenGL指令不是立即执行的。它们首先被送到指令缓冲区,然后才被送到硬件执行。

	glFlush都是强制将命令缓冲区的内容提交给硬件执行。*/
}
void Bresenham_drawcircle(GLint R) {    //默认原点是0,0 bresenham算法画圆
	GLint x = 0;
	GLint y = R;
	GLint d = 3 - 2 * R;
	glBegin(GL_POINTS);
	glPointSize(pointsize);
	while (x < ((int)(R*1.0 / (sqrt(2)))))
	{
		glVertex2i(x, y);         //八分画圆
		glVertex2i(-x, -y);
		glVertex2i(-x, y);
		glVertex2i(x, -y);
		glVertex2i(y, -x);
		glVertex2i(-y, -x);
		glVertex2i(-y, x);
		glVertex2i(y, x);
		x = x + 1;
		if (d >= 0) {
			y = y - 1;
			d = d + 4 * (x - y) + 10;
		}
		else {
			d = d + 4 * x + 6;

		}
	}
		glEnd();//结束

		glFlush();

}
void Bresenham_circle()
{

	glClear(GL_COLOR_BUFFER_BIT);			//清除所有的像素
	glEnable(GL_LINE_STIPPLE);				//点画线模式
	glColor3f(1.0, 1.0, 1.0);					//使用白色绘制该线段
	for (int i = -300; i <= 300; i = i + 10)
	{
		Bresenham_drawOneLine(i, 300, i, -300);
	}
	for (int j = 300; j >= -300; j = j - 10)
	{
		Bresenham_drawOneLine(-300, j, 300, j);
	}
	glColor3f(1.0, 0.0, 1.0);
	Bresenham_drawcircle(50);
	glColor3f(0.0, 1.0, 1.0);
	Bresenham_drawcircle(75);
	glColor3f(1.0, 1.0, 0.0);
	Bresenham_drawcircle(100);
	glColor3f(1.0, 0.5, 0.5);
	Bresenham_drawcircle(125);
	glColor3f(0.0, 0.5, 1.0);
	Bresenham_drawcircle(150);
	glColor3f(1.0, 1.0, 1.0);
	Bresenham_drawcircle(175);

	glFlush();
}
int main(int argc, char ** argv)

{

	/*初始化*/

	glutInit(&argc, argv);

	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//单缓冲、RGB模式

	glutInitWindowSize(800, 800);

	glutInitWindowPosition(200, 200);

	glutCreateWindow("Bresenham直线光栅化算法");//窗口标题

	init();

	/*绘制与显示*/

	//glutReshapeFunc(myReshape);//窗口大小发生改变时采取的行为

	glutDisplayFunc(Bresenham_circle);//将图传递给显示窗口,参数是描述的一个程序,即调用这个函数再送到显示窗口
	glutMainLoop();//循环

	return(0);//去掉这个函数,程序窗口一打开就马上关闭了

}


运行结果为
计算机图形学实战——Bresenham八分法画圆_第3张图片

你可能感兴趣的:(【计算机图形学】课设代码详解,c++,图形学,opengl,算法)