基于Opengl的画直线—BresenhamLine算法

画直线基本思想:

假设直线的斜率0

1.画起点(x0, y0).

2.准备画下一个点,X坐标加1,判断如果达到终点,则完成。否则找下一个点,由图可知要画的点要么为当前点的右邻接点,要么是当前点的右上邻接点。

  2.1.如果线段ax+by+c=0与x=x1+1的交点y坐标大于(y+*y+1))/2则选右上那个点

  2.2.否则选右下那个点。

3.画点

4.跳回第2步

5.结束

基于Opengl的画直线—BresenhamLine算法_第1张图片

具体的思路网上很多更详细的解释,在这里我主要提供的是基于鼠标操作的画直线程序:

详细可以参考:http://www.cnblogs.com/gamesky/archive/2012/08/21/2648623.html

 

代码如下:

#include
#include
#include
#include

using namespace std;
int m0,m1,n0,n1;//声明全局变量,起始坐标和终止坐标
int winwidth=1024,winheight=720;//窗口长宽
void DrawLine();
void MidpointLine(int,int,int,int);
void BresenhamLine(int ,int,int,int);
void DrawLine(){
//	MidpointLine(m0,n0,m1,n1);//中心划线法
	BresenhamLine(m0,n0,m1,n1);//BresenhamLine算法

}
/*中心画线法*/
void MidpointLine (int x0,int y0,int x1, int y1)
{  
//	glClear(GL_COLOR_BUFFER_BIT);//清除窗口显示内容
    int a, b, d1, d2, d, x, y;
    a=y0-y1, b=x1-x0, d=2*a+b;
    d1=2*a, d2=2* (a+b);
    x=x0, y=y0;
	glBegin(GL_POINTS);
    glVertex2i(x, y);
    while (x0.0)
	{
		p=2*dy-dx;
		while(x=1的情况
	if(k>=1.0)
	{
		p=dy;
		while(yk>-1的情况
	if(k>-1&&k<0)
	{
		p=2*dy+dx;
		while(x=0)
				p+=twoDy;
			else
			{
				y--;
				p+=twoSum;
			}
			setPixel(x,y);
		}
	}
	//k<-1的情况
	if(k<=-1)
	{
		p=2*dx-dy;
		while(y>y2)
		{
			y--;
			if(p>=0)
				p-=twoDx;
			else 
			{
				x++;   
				p-=twoSum;
			}
			setPixel(x,y);
		}
	}
}
//鼠标拖动
void dragmouse(int x,int y){
		m1=x;
		n1=y;
		printf("%d %d %d %d\n",m0,n0,m1,n1);//把两个坐标打印出来
		DrawLine();//画线
		glFlush();

}

//鼠标监听,画点
void mymouse(int button,int state,int x,int y){
	if(button==GLUT_LEFT_BUTTON && state==GLUT_UP){
		m1=x;
		n1=y;
		printf("%d %d %d %d\n",m0,n0,m1,n1);//把两个坐标打印出来
		DrawLine();//画线
		glFlush();

	}
	if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN){
		m0=x;
		n0=y;
	}

}




void init(){
	glClearColor(1,1,1,1);//设置绘制窗口颜色为白色
	glClear(GL_COLOR_BUFFER_BIT);//清除窗口内容
	glPointSize(5.0f);//设置点的大小
	/*设置为投影类型模式和其他观察参数*/
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0,winwidth,winheight,0);
	glColor3f(0,1,0);//设置画点的颜色
}

int main(int argc,char** argv){
	glutInit(&argc,argv);//初始化
//	scanf("%d%d",&m0,&n0);
//	m1=m0,n1=n0;//让起始点与目标点重合

	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置绘制模式
	glutInitWindowPosition(500,300);//设置窗口出现的位置
	glutInitWindowSize(winwidth,winheight);//设置窗口大小
	glutCreateWindow("画直线");//创建窗口
	init();

	glutDisplayFunc(DrawLine);//绘制回调函数,glut机制,它觉得需要重新绘制的时候就会执行
	glutMouseFunc(mymouse);//鼠标监听回调函数
	glutMotionFunc(dragmouse);//鼠标拖动
	glutMainLoop();

}

运行结果:

基于Opengl的画直线—BresenhamLine算法_第2张图片

命令窗口的数字分别是x1,y1,x2,y2坐标。

 

鼠标移动的每一帧,我都读取它的坐标,然后重新绘制直线,顺便把之前绘制过的直线删除,最后的效果就是实现了画图上的直线功能。

 

在下一章我会提供画圆的鼠标操作的程序与思路。

 

(上述代码中,有一部分中心画线法的代码,这部分代码只在斜率为0


你可能感兴趣的:(计算机图形学,opengl,函数,图形学)