计算机图形学实验报告班级:软件1102姓名:夏明轩学号:201109020221中点算法的线段光栅化一、设计思想和算法流程1.假定直线斜率0K1假定直线斜率0K1,且已确定点亮象素点P(Xp,Yp),则下一个与直线最接近的像素只能是P1点或P2点。设M为中点,Q为交点,现需确定下一个点亮的象素。当M在Q的下方-P2离直线更近更近-取P2。M在Q的上方-P1离直线更近更近-取P1M与Q重合,P1、P2任取一点。问题:如何判断M与Q点的关系?由常识知:若y=kx+b;F(x,y)=y-kx-b;则有点在直线下方0,点在直线上方0,点在直线上面0,yxFyxFyxF假设直线方程为:ax+by+c=0(y=(-a/b)x-c/b)通过两点不能唯一确定a,b,c,取a=y0-y1,b=x1-x0,c=x0y1-x1y0F(x,y)=ax+by+c=b(y-(-a/b)x-c/b);点在直线下方0,点在直线上方0,点在直线上面0,yxFyxFyxF则有∴欲判断M点是在Q点上方还是在Q点下方,只需把M代入F(x,y),并检查它的符号。构造判别式:d=F(M)=F(xp+1,yp+0.5)=a(xp+1)+b(yp+0.5)+c当d0,M在直线(Q点)下方,取右上方P2;当d0,M在直线(Q点)上方,取右方P1;当d=0,选P1或P2均可,约定取P1;能否采用增量算法呢?若d0----M在直线上方-取P1;此时再下一个象素的判别式为d1=F(xp+2,yp+0.5)=a(xp+2)+b(yp+0.5)+c=a(xp+1)+b(yp+0.5)+c+a=d+a;增量为a若d0------M在直线下方-取P2;此时再下一个象素的判别式为d2=F(xp+2,yp+1.5)=a(xp+2)+b(yp+1.5)+c=a(xp+1)+b(yp+0.5)+c+a+b=d+a+b;P=(xp,yp)QP2P1P=(xp,yp)QP2P1增量为a+b画线从(x0,y0)开始,d的初值d0=F(x0+1,y0+0.5)=a(x0+1)+b(y0+0.5)+c=F(x0,y0)+a+0.5b=a+0.5b由于只用d的符号作判断,为了只包含整数运算,可以用2d代替d来摆脱小数,提高效率。2.斜率不在[0,1]的直线的处理设起点和终点分别为(x0,y0)和(x1,y1)若k1则(y0,x0)和(y1,x1)所确定的直线斜率k€[0,1],适用于前面讨论的情形。对(y0,x0)和(y1,x1)所确定的直线进行扫描转换,每确定一组(x,y),输出(y,x)。若-1k0先对(x0,-y0)和(x1,-y1)所确定的直线进行扫描转换,每确定一组(x,y),输出(x,-y)。若k-1对(-y0,x0)和(-y1,x1)所确定的直线进行扫描转换,每确定一组(x,y),输出(y,-x)。二、编程实现#includegl/glut.h#includestdlib.h#includestdio.h#includeiostreamusingnamespacestd;inta1,a2,b1,b2,x,y,m;voidmain(intargc,char**argv){cout第一个点横坐标:;cina1;cout第二个点横坐标:;cina2;cout第一个点纵坐标:;cinb1;cout第二个点纵坐标:;cinb2;glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(500,500);glutInitWindowPosition(100,100);glutCreateWindow(201109020221夏明轩光栅直线);glClearColor(0.0,0.0,0.0,0.0);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,500.0,0.0,500.0);if(a1a2&&b1b2){x=2*(b2-b1);y=2*(b2-b1)-2*(a2-a1);m=2*(b2-b1)-(a2-a1);}elseif(a1a2&&b1b2){x=2*(b1-b2);y=2*(b1-b2)-2*(a2-a1);m=2*(b1-b2)-(a2-a1);}elseif(a1a2&&b1b2){x=2*(b2-b1);y=2*(b2-b1)-2*(a1-a2);m=2*(b2-b1)-(a1-a2);}elseif(a1a2&&b1b2){x=2*(b1-b2);y=2*(b1-b2)-2*(a1-a2);m=2*(b1-b2)-(a1-a2);}do{glColor3f(1.0,1.0,1.0);glBegin(GL_POINTS);glVertex2i(x,y);if(a1a2&&b1b2){a1++;if(m0)m=m+x;elsem=m+y;b1++;}elseif(a1a2&&b1b2){a1++;if(m0)m=m+x;elsem=m+y;b1--;}elseif(a1a2&&b1b2){a1--;if(m0)m=m+x;elsem=m+y;b1++;}elseif(a1a2&&b1b2){a1--;if(m0)m=m+x;elsem=m+y;b1--;}elseif(a1=a2&&b1b2){b1++;}else{b1--;}}while(a1!=a2|b1!=b2);glEnd();glutMainLoop();}三、运行结果四、结论这次试验有很大收获,首先加深了对书上几种算法画直线、画圆的理解;其次,对OpenGL的运用熟练了很多,清楚了OpenGL写程序的大致框架,一些典型OpenGL语句的意义及运用都熟悉了很多。在这次的图形学作业中,使我了解了图形界面的编程基础,也对VC中的MFC有了一定的了解,这会使得我能继续深入的了解VC中的其它的部分,使我了解编写图形界面也会带来乐趣。