计算机图形学课程设计报告
系 (院): 计算机科学学院
专业班级: 信计11102 姓 名: 吴家兴 学 号: 201106262 指导教师: 严圣华 设计时间: 2014.6.16 - 2014.6.26 设计地点: 10教机房
(此处目录根据自己情况可以调整改动) 一、课程设计目的 ................................................. 错误!未定义书签。 二、课程设计具体要求 ..................................... 错误!未定义书签。 三、需求分析与总体设计 ..................................... 错误!未定义书签。 四、详细设计与实现[含关键代码和实现界面] ... 错误!未定义书签。
五、小结......................................................................................... 错误!未定义书签。
一、 课程设计目的
计算机图形学课程设计是验证、巩固和补充课堂讲授的理论知识的必要环节,通过上机
实验,培养学生的自学能力、动手能力、综合运用知识解决实际问题的能力。要求学生
运用计算机图形学理论与技术设计、编写、调试程序并撰写课程设计报告。
二、 课程设计具体要求
1.独立完成设计并撰写课程设计报告。
2.在规定时间将程序和设计报告用附件(信计111X班XXX 图形学课设报告.RAR)发送到274548837@qq.com,并上交纸质打印稿(A4纸10页左右)。 3. 课程设计报告内容包括:
(1)列出设计者姓名及本人详细信息、所用开发工具; (2)程序的基本功能介绍;
(3)程序实现步骤和关键算法的理论介绍; (4)关键源代码实现说明。(不要打印全部源程序!) (5)程序运行界面截图(3幅左右) (6)课设总结和自我评价。
4.《计算机图形学》课程的知识结构体系:
(1)课设为期两周:总学时为40学时,2学分
(2)学生必须完成二维线画图元和二维填充图元两个大功能。二维裁剪和二维图形变换至少实现两个内容。总共不少于10个算法。
(3)程序应做到:通用性、交互性、界面友好性!
三、需求分析与总体设计
1、Bresenham基本算法(含画圆与画线):
过各行各列象素中心构造一组虚拟网格线。按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列象素中与此交点最近的象素。
设直线方程为:
yi?1?yi?k(xi?1?xi)?yi?k其中k=dy/dx。 因为直线的起始点在象素中心,所以误差项d的初值d0=0。 X下标每增加1,d的值相应递增直线的斜率值k,即d=d+k。一旦d≥1, 就把它减去1,这样保证d在0、1之间。
当d≥0.5时,最接近于当前象素的右上方象素( x i ?1 , y i? 1 ) 当d<0.5时,更接近于右方象素( x i? 1 , y 。 i)
为方便计算,令e=d-0.5,e的初值为-0.5,增量为k。
,y当e≥0时,取当前象素(xi,yi)的右上方象素( x i? 1 i ?1); ,y而当e<0时,更接近于右方象素( x i? 1 i )。 可以改用整数以避免除法。
3. 数值微分(DDA)法 已知过端点 P 0 0 , y ( x 的直线段L:y=kx+b,直线斜率为 ( x0),P11,y1)x 0 开始,向x右端点步进。步长=1(个象素),计算相应的y坐标y=kx+b;从x的左端点
取象素点(x, round(y))作为当前点的坐标
4.中点画线法
当前象素点为(xp, yp) 。下一个象素点为P1 或P2 。
设M=(xp+1, yp+0.5),为p1与p2之中点,Q为理想直线与x=xp+1垂线的交点。将Q与M的y坐标进行比较。
当M在Q的下方,则P2 应为下一个象素点; 当M在Q的上方,应取P1为下一点。
构造判别式:d=F(M)=F(xp+1,yp+0.5)=a(xp+1)+b(yp+0.5)+c,其中a=y0-y1, b=x1-x0, c=x0y1-x1y0。
当d<0,M在L(Q点)下方,取右上方P2为下一个象素; 当d>0,M在L(Q点)上方,取右方P1为下一个象素; 当d=0,选P1或P2均可,约定取P1为下一个象素;
但这样做,每一个象素的计算量是4个加法,两个乘法。
d是xp, yp的线性函数,因此可采用增量计算,提高运算效率。 若当前象素处于d?0情况,则取正右方象素P1 (xp+1, yp), 要判下一个象素位置,应计算d1=F(xp+2, yp+0.5)=a(xp+2)+b(yp+0.5)=d+a; 增量为a。
若d<0时,则取右上方象素P2 (xp+1, yp+1)。要判断再下一象素,则要计算 d2= F(xp+2, yp+1.5)=a(xp+2)+b(yp+1.5)+c=d+a+b ;增量为a+b。
5.几何变换(平移与旋转)以一条直线段为例,完成目标的平移、绕任一点旋
转。
7.多边形剪裁
基本思想是一次用窗口的一条边裁剪多边形,窗口的一条边以及延长线构成裁剪线,改线把平面分成两个部分:可见一侧,不可见一侧。用一条裁剪边多多边形进行裁剪,得到一个顶点序列,作为吓一条裁剪边处理过程的输入点。
对于每一条裁剪边,只是判断点在窗口的哪一测以及求线段与裁剪边的交点算法应随之改变。
仅用一条裁剪边时,逐次多边形裁剪框图
8. 多边形填充算法分析:
确定多边形所占有的最大扫描线数,得到多边形顶点的最小和最大y值(ymin和ymax),从y=ymin 到 y=ymax, 每次用一条扫描进行填充。对一条扫描线填充的过程可分为四个步骤: a.求交b.排序c.交点配对d.区间填色。在CGraphics类中的FillPlogon函数中实现多边形的填充算法。
9.直线段裁剪 10.圆的填充算法
四、详细设计与实现[含各部分代码和实现界面]
用户界面:
1.Bresenham算法代码如下:
void Bresenhamline(int x1, int y1, int x2, int y2,CDC *pDC)
{ //对于所有直线均按照从左至右的方向绘制
int x,y,d,dx,dy,right,rightleft; if(x1>x2){ }
//根据斜率的情况不同而绘制 if(y1==y2){//斜率为0的情况
int tempx,tempy;
tempx=x1;x1=x2;x2=tempx; tempy=y1;y1=y2;y2=tempy;
}
else if(x1==x2){//直线为垂直的情况 } else{
if(y1>y2){ //使直线按从下往上画 }
for(y=y1;y<=y2;y++)
pDC->SetPixel(x1,y,2); int tempy=y1; y1=y2;y2=tempy; for(x=x1;x<=x2;x++)
pDC->SetPixel(x,y1,2);
dy=y2-y1;
dx=x2-x1;
if(abs(dy)==abs(dx)){////斜率为1或 -1时 x=x1;y=y1; if(dy<0){//斜率为1 for(;y>=y2;y--){ x++;
pDC->SetPixel(x,y,2);
}
}//斜率为1 else{//斜率为-1 for(;y<=y2;y++){ x++;
pDC->SetPixel(x,y,2);
}
}//斜率为-1
}
else if(abs(dy)0&&dx>0){//斜率为正时 right=-2*dy; rightleft=2*dx-2*dy; d=dx-2*dy; x=x1;y=y1; while(x<=x2){ pDC->SetPixel(x,y,2); x++; if(d<0){ y++;
d=d+rightleft;
}else{ d=d+right;
}
}
}//斜率为正时
else {//斜率为负时 right=2*dy; rightleft=2*dy-2*dx; d=2*dy-dx; x=x1;y=y1; while(x<=x2){ pDC->SetPixel(x,y,2); x++; if(d<0){ y++;
d=d+rightleft;
}else{ d=d+right;
}
}
}//斜率为负时
}//斜率的绝对值小于1时 else{////斜率的绝对值大于1时 if(dy>0&&dx>0){//斜率为正时 right=2*dx; rightleft=2*dx-2*dy; d=2*dx-dy; x=x1;y=y1; while(y<=y2){ pDC->SetPixel(x,y,2); y++; if(d>=0){ x++;
d=d+rightleft;
}else{ d=d+right;
}
}
}//斜率为正时
else{//斜率为负时
right=-2*dx;