openGL实现中点画线算法、DDA画线算法,Bresenham画线算法,并进行鼠标键盘的交互

首先设置变量用于进行鼠标交互和键盘交互:

int m = 0;
GLdouble m1 =0, m2 = 0;

1.实验入口主函数:

//主函数
int main(int argc, char** argv) {
	glutInit(&argc, argv);//初始化openGl
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowPosition(100, 100);//显示窗口的位置
	glutInitWindowSize(350, 150);//显示窗口的大小
	glutCreateWindow("实验1");//表示用键盘来进行交互的

	init();//自定义的方法
	glutDisplayFunc(display);//绘制函数
	glutKeyboardFunc(myKayBoard);//点击键盘的时候就会调用该方法
	glutMouseFunc(mouseMoton);//鼠标点击时会调用该方法
	glutMainLoop();
	return 0;
}

2.对窗口进行一些初始化:

void init(void) {
	glClearColor(1.0, 1.0, 1.0, 0.0);//申明一个刷新的颜色
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, 500, 0, 500);
	//glShadeModel(GL_FLAT);
}

3.显示函数的编写:

void display(void) {
	glClear(GL_COLOR_BUFFER_BIT);//用颜色刷新
	glColor3f(0.8, 0.5, 0.6);//绘制的颜色
	glPointSize(1);//绘制像素的大小
	if (m==0)
		bresenham(1.08,2.00, 373.80,367.66);
	if (m==1)
		halfzd(99.09,120.08,373.80, 367.66);
	if (m==2)
		myDDA(140.7, 200.3, 373.80, 367.66);
	glFlush();
}

4.关于DDA算法的实现:

void myDDA(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) {
	x1 = x1 + m1;
	y1 = y1 + m2;
	double dx = fabs(x2 - x1);
	double dy = fabs(y2 - y1);
	double steps;
	if (dx > dy)
		steps = dx;
	else
		steps = dy;
	double stepX = dx / steps;
	double stepY = dy / steps;
	glBegin(GL_POINTS);
	for (int i = 0;i < (int)steps;i++) {
		glVertex2f(x1, y1);
		x1 += stepX;
		y1 += stepY;
	}
	glEnd();
}

5.关于中点画线算法的实现:

void halfzd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) {
	double a = y1+m2-y2;
	double b = x2-x1-m1;
	double d = a + a + b;
	double d1 = a + a;
	double d2 = a + b + a + b;
	glBegin(GL_POINTS);
	glVertex2f(x1+m1, y1+m2);
	while (x1+m1 < x2) {
		if (d < 0) {
			x1++;y1++;d += d2;
		}
		else {
			x1++;d += d1;
		}
		glVertex2f(x1+m1, y1+m2);
	}
	glEnd();
}

6.关于Bresenham画线算法的实现:

void bresenham(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) {
	double dx = x2 - x1-m1;
	double dy = y2 - y1-m2;
	double k = dy / dx;
	double e = 0.5;
	glBegin(GL_POINTS);//表示画一个点
	for (int i = 0;i <= dx;i++) {
		glVertex2f(x1+m1, y1+m2);
		x1 = x1 + 1;
		e = e + k;
		if (e >= 0) {
			y1++;
			e = e - 1;
		}
	}
	glEnd();
}

7.对于鼠标点击函数

void mouseMoton(GLint button,GLint state,GLint x,GLint y) {
	//鼠标左点击
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
		m1 = x;
		m2 = y;
		glutPostRedisplay();
	}
	//鼠标滚轮键
	if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) {
		m1 = x;
		m2 = y;
		glutPostRedisplay();
	}
	//鼠标右点击
	if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
		m1 = x;
		m2 = y;
		glutPostRedisplay();
	}
}

8.键盘点击函数:

void myKayBoard(unsigned char key, int x, int y) {//key对应键盘上面的一个键
	switch (key)
	{
	case'z':m = 0;break;
	case'x':m = 1;break;
	case'c':m = 2;break;
	}
	//改变值后我们要使图形重新显示一遍
	glutPostRedisplay();

}

完整版代码如下:

#include 
#include   
#include   
#include   
#include   


int m = 0;
GLdouble m1 =0, m2 = 0;

void bresenham(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) {
	double dx = x2 - x1-m1;
	double dy = y2 - y1-m2;
	double k = dy / dx;
	double e = 0.5;
	glBegin(GL_POINTS);//表示画一个点
	for (int i = 0;i <= dx;i++) {
		glVertex2f(x1+m1, y1+m2);
		x1 = x1 + 1;
		e = e + k;
		if (e >= 0) {
			y1++;
			e = e - 1;
		}
	}
	glEnd();
}

void halfzd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) {
	double a = y1+m2-y2;
	double b = x2-x1-m1;
	double d = a + a + b;
	double d1 = a + a;
	double d2 = a + b + a + b;
	glBegin(GL_POINTS);
	glVertex2f(x1+m1, y1+m2);
	while (x1+m1 < x2) {
		if (d < 0) {
			x1++;y1++;d += d2;
		}
		else {
			x1++;d += d1;
		}
		glVertex2f(x1+m1, y1+m2);
	}
	glEnd();
}

void myDDA(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) {
	x1 = x1 + m1;
	y1 = y1 + m2;
	double dx = fabs(x2 - x1);
	double dy = fabs(y2 - y1);
	double steps;
	if (dx > dy)
		steps = dx;
	else
		steps = dy;
	double stepX = dx / steps;
	double stepY = dy / steps;
	glBegin(GL_POINTS);
	for (int i = 0;i < (int)steps;i++) {
		glVertex2f(x1, y1);
		x1 += stepX;
		y1 += stepY;
	}
	glEnd();
}

//键盘点击函数
void myKayBoard(unsigned char key, int x, int y) {//key对应键盘上面的一个键
	switch (key)
	{
	case'z':m = 0;break;
	case'x':m = 1;break;
	case'c':m = 2;break;
	}
	//改变值后我们要使图形重新显示一遍
	glutPostRedisplay();

}

//鼠标点击函数
void mouseMoton(GLint button,GLint state,GLint x,GLint y) {
	//鼠标左点击
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
		m1 = x;
		m2 = y;
		glutPostRedisplay();
	}
	//鼠标滚轮键
	if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) {
		m1 = x;
		m2 = y;
		glutPostRedisplay();
	}
	//鼠标右点击
	if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
		m1 = x;
		m2 = y;
		glutPostRedisplay();
	}
}

void display(void) {
	glClear(GL_COLOR_BUFFER_BIT);//用颜色刷新
	glColor3f(0.8, 0.5, 0.6);//绘制的颜色
	glPointSize(1);//绘制像素的大小
	if (m==0)
		bresenham(1.08,2.00, 373.80,367.66);
	if (m==1)
		halfzd(99.09,120.08,373.80, 367.66);
	if (m==2)
		myDDA(140.7, 200.3, 373.80, 367.66);
	glFlush();
}



void init(void) {
	glClearColor(1.0, 1.0, 1.0, 0.0);//申明一个刷新的颜色
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, 500, 0, 500);
	//glShadeModel(GL_FLAT);
}

//主函数
int main(int argc, char** argv) {
	glutInit(&argc, argv);//初始化openGl
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowPosition(100, 100);//显示窗口的位置
	glutInitWindowSize(350, 150);//显示窗口的大小
	glutCreateWindow("实验1");//表示用键盘来进行交互的

	init();//自定义的方法
	glutDisplayFunc(display);//绘制函数
	glutKeyboardFunc(myKayBoard);//点击键盘的时候就会调用该方法
	glutMouseFunc(mouseMoton);//鼠标点击时会调用该方法
	glutMainLoop();
	return 0;
}

实验结果:

在实验中我同时写入了ADD划线算法,中点画线算法、Bresenham画线算法可以通过键盘的输入来控制不同算法的显示窗口的显示,跟人进行交互:

运行后的窗口图形如下,为默认的Bresenham画线算法

openGL实现中点画线算法、DDA画线算法,Bresenham画线算法,并进行鼠标键盘的交互_第1张图片

 当我们键盘输入x时,该窗口的显示切换到中点画线算法会出现下图所示:

openGL实现中点画线算法、DDA画线算法,Bresenham画线算法,并进行鼠标键盘的交互_第2张图片

当我们从键盘键入c时,该窗口的显示切换到中点画线算法会出现如下所示:

openGL实现中点画线算法、DDA画线算法,Bresenham画线算法,并进行鼠标键盘的交互_第3张图片

在我们的每一个图形窗口可以通过鼠标左键,或者鼠标右键,或者滚动鼠标轮,我们可以自由切换任意的线段方向。也就是可以处理任意方向和任意斜率的直线端,也对非整数坐标进行了处理。比如如下:

openGL实现中点画线算法、DDA画线算法,Bresenham画线算法,并进行鼠标键盘的交互_第4张图片

你可能感兴趣的:(计算机图形学实验,c++,visual,studio,code)