计算机图形学实验报告.docx
《计算机图形学实验报告.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验报告.docx(15页珍藏版)》请在冰豆网上搜索。
计算机图形学实验报告
《计算机图形学》实验报告
姓名:
郭子玉
学号:
2012211632
班级:
计算机12-2班
实验地点:
逸夫楼507
实验时间:
15.04.1015.04.17
实验一
1实验目的和要求
理解直线生成的原理;掌握典型直线生成算法;掌握步处理、分析实验数据的能力;
编程实现DDA算法、Bresenham中点算法;对于给定起点和终点的直线,分别调用DDA算法和Bresenham中点算法进行批量绘制,并记录两种算法的绘制时间;利用excel等数据分析软件,将试验结果编制成表格,并绘制折线图比较两种算法的性能。
2实验环境和工具
开发环境:
VisualC++6.0
实验平台:
Experiment_Frame_One(自制平台)
3实验结果
3.1程序流程图
(1)DDA算法
是否
否
是是
(2)Mid_Bresenham算法
是否
否
是是
是否
是否
3.2程序代码
//-------------------------算法实现------------------------------//
//绘制像素的函数DrawPixel(x,y);
(1)DDA算法
voidCExperiment_Frame_OneView:
:
DDA(intX0,intY0,intX1,intY1)
{
//----------请实现DDA算法------------//
floatk,b;
floatd;
k=float(Y1-Y0)/float(X1-X0);
b=float(X1*Y0-X0*Y1)/float(X1-X0);
if(fabs(k)<=1)
{
if(X0>X1)
{
inttemp=X0;
X0=X1;
X1=temp;
}
intx;
floaty;
x=(int)X0;
y=(float)Y0;
while(x<=X1)
{
DrawPixel(x,round(y));
x++;
y=y+k;
}
}
else
{
if(Y0>Y1)
{
inttemp=Y0;
Y0=Y1;
Y1=temp;
}
floatx;
inty;
x=(float)X0;
y=(int)Y0;
while(y<=Y1)
{
DrawPixel(round(x),y);
y++;
x=x+1/k;
}
}
return;
}
(2)Mid_Bresenham算法
voidCExperiment_Frame_OneView:
:
Mid_Bresenham(intX0,intY0,intX1,intY1)
{
//-------请实现Mid_Bresenham算法-------//
intD;
intdx,dy;
intx,y;
dx=X1-X0;
dy=Y1-Y0;
x=X0;
y=Y0;
if(dx>dy)
{
D=dx-2*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)
{
x=x+1;
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实验环境和工具
开发环境:
VisualC++6.0
实验平台:
Polygon_Conversion(自制平台)
3实验结果
3.1程序流程图
X-扫描线转换算法
是
否
是
3.2程序代码
/*********************************************************************
功能:
X-扫描线转换算法
参数说明:
vertices[][2]---顶点列表
VertexNum---顶点数目
备注:
DrawPixel(intx,inty)--绘制像素点(x,y)
**********************************************************************/
voidCPolygon_ConversionView:
:
X_Scan_Line_Conersion(intVertices[][2],intVertexNum)
{
intymax,ymin,count;
floatk;
ymax=Vertices[0][1];
ymin=Vertices[0][1];
for(intp=0;pif(Vertices[p][1]>ymax)ymax=Vertices[p][1];
if(Vertices[p][1]}
intXn[100],i,ymax2,ymin2,temp;
for(i=ymin;i<=ymax;i++){//求交点
count=0;
for(intj=0;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((iymin2)){//判断交点是否在线段上
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++;
}
elseif(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++;
}
elseif(((Vertices[j-1][1]i))||((Vertices[j-1][1]>i)&&(Vertices[0][1]
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((iymin2)){
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++;
}
elseif(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++;
}
elseif(((Vertices[j-1][1]i))||((Vertices[j-1][1]>i)&&(Vertices[j+1][1]
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++;
}
elseif(((Vertices[VertexNum-1][1]i))||((Vertices[VertexNum-1][1]>i)&&(Vertices[j+1][1]
Xn[count]=Vertices[j][0];
count++;
}
}
}
}
}
for(intm=0;mfor(intn=m+1;nif(Xn[m]>Xn[n]){
temp=Xn[m];
Xn[m]=Xn[n];
Xn[n]=temp;
}
}
}
for(inta=0;afor(intb=Xn[a];bDrawPixel(b,i);
}
}
}
return;
}
3.3运行结果
3.4运行结果分析
从运行结果看可以实现任意多边形的区域填充。
4实验心得
通过这个实验,学习掌握了X-扫描线转换算法,实现了区域填充。
编写算法过程中,不断改进算法,在同学帮助下解决困难。
但是还有改进的有效边表算法没有去编写实现,程序在不断改进中不断优化,我们也可以从中学到许多知识。