【OpenGL】使用DDA算法画线

来源:互联网 发布:数据控制 编辑:程序博客网 时间:2024/05/18 17:25

DDA(数字微分分析仪...好高大上的样子)算法其实就是利用直线方程来生成直线的算法,给定起点(x0,y0)和终点(xEnd,yEnd),这条直线就唯一确定了,它的斜率是k=(yEnd-y0)/(xEnd-x0)。对于x方向我们取增量为1,那么下一个x值,即xi+1=xi+1,这样一来,y方向的增量就是斜率k,那么yi+1=yi+k。利用这两个加粗的方程,我们就可以遍历这条直线,每到一个地方就把这里的像素点填充上颜色,一条直线就绘制好了,当然,具体的算法实现有一些小细节,放到了注释里。

代码:

/*使用DDA算法画线*/#include<iostream>using namespace std;#include<windows.h>#include<math.h>#include<gl/glut.h>void myDisplay(void);//用这个函数来调用lineDDAvoid setPixel(int x,int y);//教科书里画点的函数,在OpenGL中可以用glVertex来实现int round(const float a);void ChangeSize(GLsizei w, GLsizei h);void lineDDA(int x0,int y0,int xEnd,int yEnd);void myDisplay(void){    //glClear(GL_COLOR_BUFFER_BIT);//好像没这句话也可以啊。。初学好迷=。=lineDDA(50,50,200,200);}void setPixel(int x,int y){//用OpenGL自己的函数实现书上的setPixelglPointSize(5.0f);glBegin(GL_POINTS);glVertex2i(x,y);glEnd();glFlush();}int round(const float a){return int(a+0.5);}//窗口大小改变时调用的登记函数void ChangeSize(GLsizei w, GLsizei h){    if(h==0)     h=1;    glViewport(0,0,w,h);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    if (w <= h)        glOrtho(0.0f,250.0f,0.0f,250.0f*h/w,1.0,-1.0);    else        glOrtho(0.0f,250.0f*w/h,0.0f,250.0f,1.0,-1.0);}void lineDDA(int x0,int y0,int xEnd,int yEnd){glPointSize(3.0f);//设置像素点大小int dx=xEnd-x0,dy=yEnd-y0,steps,k;float xIncrement,yIncrement,x=x0,y=y0;if(abs(dx)>abs(dy))//确定步长,谁大就取谁steps=abs(dx);elsesteps=abs(dy);xIncrement=float(dx)/float(steps);//增量当中有一个会为1,另一个会为斜率kyIncrement=float(dy)/float(steps);setPixel(round(x),round(y));//由于每次都加了小于1的增量,所以需要取整for(k=0;k<steps;k++){/*glBegin(GL_POINTS);glVertex2i((int)x,(int)y);glEnd();glFlush();*/x+=xIncrement;y+=yIncrement;setPixel(round(x),round(y));}}int main(int argc,char* argv[]){glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);glutInitWindowPosition(200,200);glutInitWindowSize(400,400);glutCreateWindow("Daily Practice");glutDisplayFunc(&myDisplay);glutReshapeFunc(ChangeSize);glutMainLoop();return 0;}

运行效果:


DDA简单(好吧我是说在这种二维的情况下,今天老师提了一下三维的情形,感觉还是有点复杂的=。=),但是比较粗糙,取整的误差会累积得越来越大,如果绘制的线比较长,像素点比较多,偏离相对就比较大,第二是算法整体耗时高,因为round和浮点运算比较耗时。

对了,代码里的ChangeSize()函数是在网上找到的(还不懂OPenGL的显示机制),这里参考了:http://blog.csdn.net/u012866328/article/details/52601217,特此说明,谢谢这位博主!

原创粉丝点击