计算机图形学期末编程大作业
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
我们选择圆心在(350,220)的位置,半径取200像素值。图形效果如下图6。
图1-6圆形的绘制
2.程序算法说明.
1)直线的绘制
a.数值微分法DDA(Digital Differential Analyzer简称DDA)
对任何沿直线给定的x的增量△x,可以从下式中计算出y的增量△y:
同样,可以得出对应于指定的△y的x增量△x:
对斜率绝对值|k|<1的线段,即与水平夹角小于45°时,让x从起点到终点变化,每步递增(或递减)1:令△x=±1,则△y=±k。若前一次的直线上像素点坐标为(xi,yi),这一次的直线上像素点坐标为(xi+1,yi+1),则xi+l=xi±1,yi+1=yi±k随后输出该像素的颜色值即可。
对于斜率绝对值|k|>1的线段,让y从起点到终点变化,每步递增(或递减)1,计算对应的x增量,△x=±1/k。若前一次的直线上像素点坐标为(xi,yi),这一次的直线上像素点坐标为(xi+1,yi+1),则xi+1=xi±1/k,yi+l=yi±1随后输出该像素的颜色值即可。
b.直线的绘制
图1-3直线参数对话框
鼠标左键点选菜单栏中的 菜单,会弹出下拉菜单,其中提供2种直线绘制的经典算法,包括DDA算法和Bresenham算法。我们可随意选择一种,例如Bresenham算法。
说表左键单击选定后,便会弹出参数输入对话框,如图3。
注意:由于在计算机的图形显示时,屏幕坐标默认以屏幕左上角点为(0,0)点,X轴方向水平指向右侧,Y轴方向竖直指向下侧。与我们实际中熟悉的坐标系不同,输入点坐标时要注意。例如直线的起止点坐标分别为(0,0)、(100,100),绘制结果如图5。
if(Xe>1024||Ye>644)
MessageBox("图像超出范围,将显示不完全!");
dx = Xe - Xs;dy = Ye - Ys; e = (fabs(dx)>fabs(dy)) ? fabs(dx):fabs(dy);dx /= e;dy /= e;x = Xs;y = Ys;
for(int i=1; i<=e; i++)
if(dlgDDAline.DoModal()==IDOK)
{Xs=dlgDDAline.m_Xs;
Ys=dlgDDAline.m_Ys;
Xe=dlgDDAline.m_Xe;
Ye=dlgDDAline.m_Ye;}
if(Xe>700||Ye>428)
MessageBox("图像超出范围,请在全屏下运行,否则将显示不完全!");
b. Bresenham算法
1965年,Bresenham提出了一种更好的直线生成算法,称为Bresenham算法。此算法的一个主要思想是借助于一个决策变量dk,来确定下一个该点亮的像素点。对于直线斜率k在0~1之间的情况,从给定线段的左端点(x1,y1)开始,逐步处理每个后续列(x位置),并在扫描线y值最接近线段的像素上绘出一点。
完成下列程序的设计、调试与及设计说明书:
一、实现直线、圆的生成
要求:(1)算法不限;(2)直线的端点、圆的圆心、半径由用户实时输入;(3)用所实现的直线、圆的生成程序实现一个任意图形的绘制。
二、实现区域填充(多边形区域)或影线填充
要求:(1)区域自行指定,至少应有一个内环(2)算法:计算机相关专业的要求实现图案填充,机械相关专业的要求实现影线填充。
if(Xs==Xe)
{if(Ys<Ye)
{for ( int i=Ys; i<=Ye; i++)
dc.SetPixel(Xs,i,m_clr);}
else
{for ( int i=Ye; i<=Ys; i++)
{dc.SetPixel(Xs,i,m_clr);}}
return;
}
BOOL m=(fabs(Ye-Ys)<=fabs(Xe-Xs));
2)Bresenham画圆算法
Bresenham画法与中点画法一样,也考虑从(0,R)到(R/ ,R/ )的八分之一圆周。取(0,R)为起点,按顺时针方向生成圆。从这段圆弧的任意一点出发,按顺时针方向生成圆时,为了最佳逼近该圆,下一像素的取法只有三种可能的选择:正右方像素,右下方像素和正下方像素。这三个像素中,与理想圆弧最近者为所求像素。
{// TODO: Add your command handler code here
CClientDC dc(this);
CDlg_LinePoint dlgBresenhamline;
int Xs=1;int Ys=1;int Xe=1;int Ye=1;int x,y,p;int dx,dy;
if(Xe>1024||Ye>644)
MessageBox("图像超出范围,将显示不完全!");
//斜率绝对值小于等于1
if(m)
{//情况一:Y递增
if(Ys<=Ye)
{p=(dy<<1)-dx;
while(x<=Xe)
{dc.SetPixel(x,y,m_clr);
if(p<0)
{x++;p=p+(dy<<1);}
else
{x++;y++;p=p+((dy-dx)<<1);}}
}
//情况二:Y递减
else
{ p=dx-(dy<<1);
while(x<=Xe)
{dc.SetPixel(x,y,m_clr);
if(p<0)
{x++;p=p-(dy<<1);}
else
{x++;y--;p=p-((dy=dx)<<1);}}
图1-5绘制结果
如果输入的坐标值超出了设定的范围,将弹出提示对话框,如下图所示:
c.圆的绘制
鼠标左键点选菜单栏中的 菜单,会弹出下拉菜单,Bresenham算法。
则弹出对话框如图5。
图1-5圆参数输入界面
根据对话框的要求,填入元的基本参数值:圆心坐标值和半径值。
注意:界面上对输入的数值的要求。程序的默认窗体中,图形显示空间为宽度大小为700个像素值,高为428个像素值。全屏条件下,图形显示空间为宽度大小为1024个像素值,高为644个像素值。
要求:(1)算法不限;(2)直线的端点、圆的圆心、半径由用户实时输入;(3)用所实现的直线、圆的生成程序实现一个任意图形的绘制。
1.程序使用说明.
1)概述
该程序以Visual C++6.0作为编程开发工具,利用其中的MFC(Microsoft Foundation Classes)库作为应用程序的框架,进行图形的编程绘制,有良好的用户操作界面和简洁的操作方法。
三、直线段裁剪算法的实现
要求:完成对一个指定图形(见图)的裁剪,先在图形区显示原始图形及窗口位置,然后将裁剪后图形的显示在图形区的另一侧。
四、凸多面体消隐的实现(外法线法)
要求:立体数据自定。
五、样条曲线的实现
要求:实现B样条曲线,并能通过交互输入点的形式完成曲线绘制。
注意:要反求控制点
六、平时成绩(30分)
/**************Bresenham画法*************/
void CAView::OnBresenhamCircle()
{// TODO: Add your command handler code here
int X0=1;
int Y0=1;
int R=1;
int x,y,p;
if(dlgBresenhamline.DoModal()==IDOK)
{Xs=dlgBresenhamline.m_Xs;
Ys=dlgBresenhamline.m_Ys;
Xe=dlgBresenhamline.m_Xe;
Ye=dlgBresenhamline.m_Ye;}
//使传入的端点坐标X值相等
{
dc.SetPixel((int)(x+0.5),(int)(y+0.5),m_clr);
x+=dx;
y+=dy;
}
}
/****************算法结束*********************/
/**********Bresenham直线算法**************/
void CAView::OnBresenhamLine()
for(;x<=y;x++)
{dc.SetPixel( x+X0, y+Y0, m_clr);
dc.SetPixel(-x+X0, y+Y0,百度文库m_clr);
dc.SetPixel( x+X0,-y+Y0, m_clr);
dc.SetPixel(-x+X0,-y+Y0, m_clr);
dc.SetPixel( y+X0, x+Y0, m_clr);
执行该程序,界面如下图。
图1-1程序运行界面
图形绘制功能的实现,主要是通过点选菜单栏中的对应菜单项来实现。主要功能有:图形颜色的选择、绘制直线、绘制圆。
2)具体操作说明:
a.颜色的选择.
鼠标左键单击 菜单项,便会弹出颜色编辑对话框,如图2。
图1-2颜色编辑对话框
可以通过鼠标左键点选对话框中的颜色实例,或者是自行编辑颜色值,来确定用户想要生成图形的颜色。下面的绘图过程,我们以黑色为例。
3.主要程序段
/**********DDA直线算法*************/
void CAView::OnDDALine()
{// TODO: Add your command handler code here
CClientDC dc(this);CDlg_LinePoint dlgDDAline;int Xs=1; double dx; double e;int Ys=1; double dy;int Xe=1; double x;int Ye=1; double y;
题目二:实现区域填充(多边形区域)或影线填充
要求:(1)区域自行指定,至少应有一个内环(2)算法:计算机相关专业的要求实现图案填充,机械相关专业的要求实现影线填充。
要求:
1、语言不限,可以是所熟悉的如何一种语言。
2、须提交的内容包括:源程序(电子版)、可执行程序,设计说明书(电子版及打印版)。
3、程序须经教师运行测试通过。
4、设计说明书B5页面打印,内容包括:算法与数据结构,程序流程说明及变量,程序运行情况分析及结果截图,程序使用说明。
题目一:实现直线、圆的生成
else
{p=(dx<<1)+dy;
while(y>=Ye)
{dc.SetPixel(x,y,m_clr);
if(p<0)
{y--;p=p+(dx<<1);}
else
{x++;y--;p=p+((dx+dy)<<1);}}
}
}
}
/*************算法结束*****************/
CClientDC dc(this);
CDlg_SetCircle dlgMidPointcircle;
if(dlgMidPointcircle.DoModal()==IDOK)
{X0=dlgMidPointcircle.m_X0;
Y0=dlgMidPointcircle.m_Y0;
R=dlgMidPointcircle.m_R ;}
//如果Xs大于Xe的值,交换坐标值
if(Xs>Xe)
{p=Xs;Xs=Xe;Xe=p;
p=Ys;Ys=Ye;Ye=p;}
x=Xs; y=Ys;
dx = Xe - Xs;
dy = Ye - Ys;
if(Xe>700||Ye>428)
MessageBox("图像超出范围,请在全屏下运行,否则将显示不完全!");
}
}
//斜率绝对值大于1
else
{//情况三:Y递增
if(Ys<=Ye)
{p=(dx<<1)-dy;
while(y<=Ye)
{dc.SetPixel(x,y,m_clr);
if(p<0)
{y++;p=p+(dx<<1);}
else
{x++;y++;p=p+((dx-dy)<<1);}
}
}
//情况四:Y递减
if(X0+R>700||Y0+R>428||X0-R<0||Y0-R<0)
MessageBox("图像超出范围,请在全屏下运行,否则将显示不完全!");
if(X0+R>1024||Y0+R>644||X0-R<0||Y0-R<0)
MessageBox("图像超出范围,将显示不完全!");
x=0;y=R; p=3-(R<<1);
dc.SetPixel(-y+X0, x+Y0, m_clr);
dc.SetPixel( y+X0,-x+Y0, m_clr);
dc.SetPixel(-y+X0,-x+Y0, m_clr);
if(p<0)
p+=((x<<2)+6);
else
{p+=(((x-y)<<2)+10);
y--;}
}
}
/**************算法结束*****************/
图1-6圆形的绘制
2.程序算法说明.
1)直线的绘制
a.数值微分法DDA(Digital Differential Analyzer简称DDA)
对任何沿直线给定的x的增量△x,可以从下式中计算出y的增量△y:
同样,可以得出对应于指定的△y的x增量△x:
对斜率绝对值|k|<1的线段,即与水平夹角小于45°时,让x从起点到终点变化,每步递增(或递减)1:令△x=±1,则△y=±k。若前一次的直线上像素点坐标为(xi,yi),这一次的直线上像素点坐标为(xi+1,yi+1),则xi+l=xi±1,yi+1=yi±k随后输出该像素的颜色值即可。
对于斜率绝对值|k|>1的线段,让y从起点到终点变化,每步递增(或递减)1,计算对应的x增量,△x=±1/k。若前一次的直线上像素点坐标为(xi,yi),这一次的直线上像素点坐标为(xi+1,yi+1),则xi+1=xi±1/k,yi+l=yi±1随后输出该像素的颜色值即可。
b.直线的绘制
图1-3直线参数对话框
鼠标左键点选菜单栏中的 菜单,会弹出下拉菜单,其中提供2种直线绘制的经典算法,包括DDA算法和Bresenham算法。我们可随意选择一种,例如Bresenham算法。
说表左键单击选定后,便会弹出参数输入对话框,如图3。
注意:由于在计算机的图形显示时,屏幕坐标默认以屏幕左上角点为(0,0)点,X轴方向水平指向右侧,Y轴方向竖直指向下侧。与我们实际中熟悉的坐标系不同,输入点坐标时要注意。例如直线的起止点坐标分别为(0,0)、(100,100),绘制结果如图5。
if(Xe>1024||Ye>644)
MessageBox("图像超出范围,将显示不完全!");
dx = Xe - Xs;dy = Ye - Ys; e = (fabs(dx)>fabs(dy)) ? fabs(dx):fabs(dy);dx /= e;dy /= e;x = Xs;y = Ys;
for(int i=1; i<=e; i++)
if(dlgDDAline.DoModal()==IDOK)
{Xs=dlgDDAline.m_Xs;
Ys=dlgDDAline.m_Ys;
Xe=dlgDDAline.m_Xe;
Ye=dlgDDAline.m_Ye;}
if(Xe>700||Ye>428)
MessageBox("图像超出范围,请在全屏下运行,否则将显示不完全!");
b. Bresenham算法
1965年,Bresenham提出了一种更好的直线生成算法,称为Bresenham算法。此算法的一个主要思想是借助于一个决策变量dk,来确定下一个该点亮的像素点。对于直线斜率k在0~1之间的情况,从给定线段的左端点(x1,y1)开始,逐步处理每个后续列(x位置),并在扫描线y值最接近线段的像素上绘出一点。
完成下列程序的设计、调试与及设计说明书:
一、实现直线、圆的生成
要求:(1)算法不限;(2)直线的端点、圆的圆心、半径由用户实时输入;(3)用所实现的直线、圆的生成程序实现一个任意图形的绘制。
二、实现区域填充(多边形区域)或影线填充
要求:(1)区域自行指定,至少应有一个内环(2)算法:计算机相关专业的要求实现图案填充,机械相关专业的要求实现影线填充。
if(Xs==Xe)
{if(Ys<Ye)
{for ( int i=Ys; i<=Ye; i++)
dc.SetPixel(Xs,i,m_clr);}
else
{for ( int i=Ye; i<=Ys; i++)
{dc.SetPixel(Xs,i,m_clr);}}
return;
}
BOOL m=(fabs(Ye-Ys)<=fabs(Xe-Xs));
2)Bresenham画圆算法
Bresenham画法与中点画法一样,也考虑从(0,R)到(R/ ,R/ )的八分之一圆周。取(0,R)为起点,按顺时针方向生成圆。从这段圆弧的任意一点出发,按顺时针方向生成圆时,为了最佳逼近该圆,下一像素的取法只有三种可能的选择:正右方像素,右下方像素和正下方像素。这三个像素中,与理想圆弧最近者为所求像素。
{// TODO: Add your command handler code here
CClientDC dc(this);
CDlg_LinePoint dlgBresenhamline;
int Xs=1;int Ys=1;int Xe=1;int Ye=1;int x,y,p;int dx,dy;
if(Xe>1024||Ye>644)
MessageBox("图像超出范围,将显示不完全!");
//斜率绝对值小于等于1
if(m)
{//情况一:Y递增
if(Ys<=Ye)
{p=(dy<<1)-dx;
while(x<=Xe)
{dc.SetPixel(x,y,m_clr);
if(p<0)
{x++;p=p+(dy<<1);}
else
{x++;y++;p=p+((dy-dx)<<1);}}
}
//情况二:Y递减
else
{ p=dx-(dy<<1);
while(x<=Xe)
{dc.SetPixel(x,y,m_clr);
if(p<0)
{x++;p=p-(dy<<1);}
else
{x++;y--;p=p-((dy=dx)<<1);}}
图1-5绘制结果
如果输入的坐标值超出了设定的范围,将弹出提示对话框,如下图所示:
c.圆的绘制
鼠标左键点选菜单栏中的 菜单,会弹出下拉菜单,Bresenham算法。
则弹出对话框如图5。
图1-5圆参数输入界面
根据对话框的要求,填入元的基本参数值:圆心坐标值和半径值。
注意:界面上对输入的数值的要求。程序的默认窗体中,图形显示空间为宽度大小为700个像素值,高为428个像素值。全屏条件下,图形显示空间为宽度大小为1024个像素值,高为644个像素值。
要求:(1)算法不限;(2)直线的端点、圆的圆心、半径由用户实时输入;(3)用所实现的直线、圆的生成程序实现一个任意图形的绘制。
1.程序使用说明.
1)概述
该程序以Visual C++6.0作为编程开发工具,利用其中的MFC(Microsoft Foundation Classes)库作为应用程序的框架,进行图形的编程绘制,有良好的用户操作界面和简洁的操作方法。
三、直线段裁剪算法的实现
要求:完成对一个指定图形(见图)的裁剪,先在图形区显示原始图形及窗口位置,然后将裁剪后图形的显示在图形区的另一侧。
四、凸多面体消隐的实现(外法线法)
要求:立体数据自定。
五、样条曲线的实现
要求:实现B样条曲线,并能通过交互输入点的形式完成曲线绘制。
注意:要反求控制点
六、平时成绩(30分)
/**************Bresenham画法*************/
void CAView::OnBresenhamCircle()
{// TODO: Add your command handler code here
int X0=1;
int Y0=1;
int R=1;
int x,y,p;
if(dlgBresenhamline.DoModal()==IDOK)
{Xs=dlgBresenhamline.m_Xs;
Ys=dlgBresenhamline.m_Ys;
Xe=dlgBresenhamline.m_Xe;
Ye=dlgBresenhamline.m_Ye;}
//使传入的端点坐标X值相等
{
dc.SetPixel((int)(x+0.5),(int)(y+0.5),m_clr);
x+=dx;
y+=dy;
}
}
/****************算法结束*********************/
/**********Bresenham直线算法**************/
void CAView::OnBresenhamLine()
for(;x<=y;x++)
{dc.SetPixel( x+X0, y+Y0, m_clr);
dc.SetPixel(-x+X0, y+Y0,百度文库m_clr);
dc.SetPixel( x+X0,-y+Y0, m_clr);
dc.SetPixel(-x+X0,-y+Y0, m_clr);
dc.SetPixel( y+X0, x+Y0, m_clr);
执行该程序,界面如下图。
图1-1程序运行界面
图形绘制功能的实现,主要是通过点选菜单栏中的对应菜单项来实现。主要功能有:图形颜色的选择、绘制直线、绘制圆。
2)具体操作说明:
a.颜色的选择.
鼠标左键单击 菜单项,便会弹出颜色编辑对话框,如图2。
图1-2颜色编辑对话框
可以通过鼠标左键点选对话框中的颜色实例,或者是自行编辑颜色值,来确定用户想要生成图形的颜色。下面的绘图过程,我们以黑色为例。
3.主要程序段
/**********DDA直线算法*************/
void CAView::OnDDALine()
{// TODO: Add your command handler code here
CClientDC dc(this);CDlg_LinePoint dlgDDAline;int Xs=1; double dx; double e;int Ys=1; double dy;int Xe=1; double x;int Ye=1; double y;
题目二:实现区域填充(多边形区域)或影线填充
要求:(1)区域自行指定,至少应有一个内环(2)算法:计算机相关专业的要求实现图案填充,机械相关专业的要求实现影线填充。
要求:
1、语言不限,可以是所熟悉的如何一种语言。
2、须提交的内容包括:源程序(电子版)、可执行程序,设计说明书(电子版及打印版)。
3、程序须经教师运行测试通过。
4、设计说明书B5页面打印,内容包括:算法与数据结构,程序流程说明及变量,程序运行情况分析及结果截图,程序使用说明。
题目一:实现直线、圆的生成
else
{p=(dx<<1)+dy;
while(y>=Ye)
{dc.SetPixel(x,y,m_clr);
if(p<0)
{y--;p=p+(dx<<1);}
else
{x++;y--;p=p+((dx+dy)<<1);}}
}
}
}
/*************算法结束*****************/
CClientDC dc(this);
CDlg_SetCircle dlgMidPointcircle;
if(dlgMidPointcircle.DoModal()==IDOK)
{X0=dlgMidPointcircle.m_X0;
Y0=dlgMidPointcircle.m_Y0;
R=dlgMidPointcircle.m_R ;}
//如果Xs大于Xe的值,交换坐标值
if(Xs>Xe)
{p=Xs;Xs=Xe;Xe=p;
p=Ys;Ys=Ye;Ye=p;}
x=Xs; y=Ys;
dx = Xe - Xs;
dy = Ye - Ys;
if(Xe>700||Ye>428)
MessageBox("图像超出范围,请在全屏下运行,否则将显示不完全!");
}
}
//斜率绝对值大于1
else
{//情况三:Y递增
if(Ys<=Ye)
{p=(dx<<1)-dy;
while(y<=Ye)
{dc.SetPixel(x,y,m_clr);
if(p<0)
{y++;p=p+(dx<<1);}
else
{x++;y++;p=p+((dx-dy)<<1);}
}
}
//情况四:Y递减
if(X0+R>700||Y0+R>428||X0-R<0||Y0-R<0)
MessageBox("图像超出范围,请在全屏下运行,否则将显示不完全!");
if(X0+R>1024||Y0+R>644||X0-R<0||Y0-R<0)
MessageBox("图像超出范围,将显示不完全!");
x=0;y=R; p=3-(R<<1);
dc.SetPixel(-y+X0, x+Y0, m_clr);
dc.SetPixel( y+X0,-x+Y0, m_clr);
dc.SetPixel(-y+X0,-x+Y0, m_clr);
if(p<0)
p+=((x<<2)+6);
else
{p+=(((x-y)<<2)+10);
y--;}
}
}
/**************算法结束*****************/