当前位置:文档之家› 计算机图形学实验报告

计算机图形学实验报告

《计算机图形学》实验报告姓名:郭子玉学号:2012211632班级:计算机12-2班实验地点:逸夫楼507实验时间:15.04.10 15.04.17实验一1 实验目的和要求理解直线生成的原理;掌握典型直线生成算法;掌握步处理、分析实验数据的能力;编程实现DDA 算法、Bresenham 中点算法;对于给定起点和终点的直线,分别调用DDA 算法和Bresenham 中点算法进行批量绘制,并记录两种算法的绘制时间;利用excel 等数据分析软件,将试验结果编制成表格,并绘制折线图比较两种算法的性能。

2 实验环境和工具开发环境:Visual C++ 6.0实验平台:Experiment_Frame_One (自制平台)3 实验结果3.1 程序流程图(1)DDA 算法是 否 否是 是开始计算k ,b K<=1 x=x+1;y=y+k;绘点 x<=X1y<=Y1绘点y=y+1;x=x+1/k;结束(2)Mid_Bresenham 算法是 否否是 是是 否 是 否开始计算dx,dy dx>dy D=dx-2*dy绘点 D<0y=y+1;D = D +2*dx -2*dy; x=x+1;D = D - 2*dy; x=x+1;x<X1;D=dy-2*dxy<Y1;绘点D<0D = D - 2*dx; y=y+1;x=x+1;D = D + 2*dy -2*dx; y=y+1;结束3.2程序代码//-------------------------算法实现------------------------------// //绘制像素的函数DrawPixel(x, y);(1)DDA算法void CExperiment_Frame_OneView::DDA(int X0, int Y0, int X1, int Y1){//----------请实现DDA算法------------//float k, b;float d;k = float(Y1 - Y0)/float(X1 - X0);b = float(X1*Y0 - X0*Y1)/float(X1 - X0);if(fabs(k)<= 1){if(X0 > X1){int temp = X0;X0 = X1;X1 = temp;}int x;float y;x = (int)X0;y = (float)Y0;while(x <= X1){DrawPixel(x, round(y));x ++;y = y + k;}}else{if(Y0 > Y1){int temp = Y0;Y0 = Y1;Y1 = temp;}float x;int y;x = (float)X0;y = (int)Y0;while(y <= Y1){DrawPixel(round(x), y);y ++;x = x + 1/k;}}return;}(2)Mid_Bresenham算法void CExperiment_Frame_OneView::Mid_Bresenham(int X0, int Y0, int X1, int Y1){//-------请实现Mid_Bresenham算法-------//int D;int dx, dy;int x, y;dx = X1 - X0;dy = Y1 - Y0;x = X0;y = Y0;if(dx > dy){while(x <= X1){DrawPixel(x, y);if(D < 0){y = y +1;D = D + 2*dx - 2*dy;}else{D = D - 2*dy;}x++;}}else{D = dy - 2*dx;while(y <= Y1){DrawPixel(x, y);if(D < 0){D = D + 2*dy - 2*dx;}else{D = D - 2*dx;}y++;}}return;}3.3运行结果(1)DDA算法(2)Mid_Bresenham算法3.4运行结果分析DDA算法直观,实现简单。

但是涉及浮点数运算,不利于硬件实现。

Mid_Bresenham算法比DDA算法简单。

两种算法实现生成的直线也可能会有不同。

4实验心得通过实验,学习掌握了两种直线的扫描转换算法。

不同方法有不同的优点,实现结果也有可能不同。

需要通过比较,确定哪种方法更优,更符合正确结果。

实验二1 实验目的和要求理解多边形扫描转换的原理;掌握典型多边形扫描转换算法;掌握步处理、分析实验数据的能力;编程实现基本X-扫描线转换算法(必做);2 实验环境和工具开发环境:Visual C++ 6.0实验平台:Polygon_Conversion (自制平台)3 实验结果3.1 程序流程图 X-扫描线转换算法是 否是开始计算xmax,ymax扫描线与各线段是否有交点交点是否为线段的第一个顶点判断不同类型的顶点,记录根据公式求交点,记录x 排序绘点3.2 程序代码/************************************************* ********************功能:X-扫描线转换算法参数说明:vertices[][2]---顶点列表VertexNum ---顶点数目备注:DrawPixel(int x, int y) --绘制像素点(x, y)************************************************** ********************/voidCPolygon_ConversionView::X_Scan_Line_Conersion(int Vertices[][2], int VertexNum){int ymax, ymin,count;float k;ymax=Vertices[0][1];ymin=Vertices[0][1];for(int p =0 ; p < VertexNum; p++){ //求y的最高点和最低点if(Vertices[p][1] > ymax) ymax=Vertices[p][1];if(Vertices[p][1] < ymin) ymin=Vertices[p][1];}int Xn[100], i, ymax2, ymin2, temp;for( i = ymin ; i <= ymax ; i++){ //求交点count=0;for( int j = 0; j < VertexNum; j++){if(j == (VertexNum-1) ){ //最后一个点和第一个点的线段if(Vertices[j][1] > Vertices[0][1]){ //线段的y最大值与最小值ymax2=Vertices[j][1];ymin2=Vertices[0][1];}else{ymax2=Vertices[0][1];ymin2=Vertices[j][1];}if((i<ymax2) && (i>ymin2)){ //判断交点是否在线段上k= (float) ( (float)(Vertices[j][0]-Vertices[0][0]) / (float)(Vertices[j][1]-Vertices[0][1]) );Xn[count]=(int) ( (k * (float)i - k *(float) Vertices[0][1] + (float)Vertices[0][0]) + 0.5);count++;}else if( i == Vertices[j][1] ){ //扫描线经过线段顶点,只算前一个顶点if( (Vertices[j-1][1] > i) && (Vertices[0][1] > i)){Xn[count]=Vertices[j][0];count++;Xn[count]=Vertices[j][0];count++;}else if( ((Vertices[j-1][1] < i) && (Vertices[0][1] > i)) || ((Vertices[j-1][1] > i) && (Vertices[0][1] < i)) ) {Xn[count]=Vertices[j][0];count++;}}}else{ //其他线段交点if(Vertices[j][1] > Vertices[j+1][1]){ymax2=Vertices[j][1];ymin2=Vertices[j+1][1];}else{ymax2=Vertices[j+1][1];ymin2=Vertices[j][1];}if((i<ymax2) && (i>ymin2)){k= (float) ( (float) (Vertices[j][0]-Vertices[j+1][0]) / (float) (Vertices[j][1]-Vertices[j+1][1]) );Xn[count]=(int) ( (k *(float) i - k * (float)Vertices[j+1][1] + Vertices[j+1][0]) + 0.5);count++;}else if( i == Vertices[j][1] ){ //扫描线经过线段顶点,只算前一个顶点if(j != 0){ //交点不为第一和最后一点if( (Vertices[j-1][1] > i) && (Vertices[j+1][1] > i)){Xn[count]=Vertices[j][0];count++;Xn[count]=Vertices[j][0];count++;}else if( ((Vertices[j-1][1] < i) && (Vertices[j+1][1] > i)) || ((Vertices[j-1][1] > i) && (Vertices[j+1][1] < i)) ){Xn[count]=Vertices[j][0];count++;}else{}}else{//交点为第一点if( (Vertices[VertexNum-1][1] > i) && (Vertices[j+1][1] > i)){Xn[count]=Vertices[j][0];count++;Xn[count]=Vertices[j][0];count++;}else if( ((Vertices[VertexNum-1][1] < i) && (Vertices[j+1][1] > i)) || ((Vertices[VertexNum-1][1] > i) && (Vertices[j+1][1] < i)) ) {Xn[count]=Vertices[j][0];count++;}}}}}for( int m = 0; m < count-1; m++ ){ //交点x坐标排序for( int n = m+1; n < count; n++ ){if( Xn[m] > Xn[n] ){temp=Xn[m];Xn[m]=Xn[n];Xn[n]=temp;}}}for( int a = 0; a < count; a+=2 ){ //绘制像素点for( int b = Xn[a]; b < Xn[a+1]; b++){DrawPixel(b, i);}}}return;}3.3 运行结果3.4 运行结果分析从运行结果看可以实现任意多边形的区域填充。

相关主题