计算机图形学实验报告实验一Word格式文档下载.docx
《计算机图形学实验报告实验一Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验报告实验一Word格式文档下载.docx(13页珍藏版)》请在冰豆网上搜索。
P1(x1,y1)及P0(x0,y0),
则直线斜率为:
直线方程为:
当|k|<
=1,x每增加1,y最多增加1(或增加小于1)。
当|k|>
1,y每增加1,x最多增加1(或增加小于1)。
算法分析:
复杂度:
加法+取整
优点:
避免了y=kx+b方程中的浮点乘法,比直接用点斜式画线快。
缺点:
需浮点数加法及取整运算,不利于硬件实现。
中点画线法
设0<
k<
1
中点M在直线下方,下一点取p1点;
中点M在直线上方取p2点。
中点算法用整数加法及比较代替了DDA中的浮点数加法及取整运算,效率大大提高。
假设直线的起点、终点分别为:
(X0,Y0),(X1,Y1),直线将二维空间划分为三个区域:
直线方程:
F(x,y)=ax+by+c=0
其中:
a=-(y1-y0),b=(x1-x0),c=-B(x1-x0)
如F(x,y)=0,则(x,y)在直线上
如F(x,y)<
0,则(x,y)在直线下方
如F(x,y)>
0,则(x,y)在直线上方
因此,可将中点M的坐标(Xp+1,Yp+0.5)代入直线方程,并判断其符号即可确定象素点的选取。
定义决策变量:
d=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c
如果d>
0,则M在理想直线上方,选正右方P2点;
如果d<
0,则M在理想直线下方,选右上方P1点;
如果d=0,则M在理想直线上,选P1/P2点。
由于d是xi和yi的线性函数,可采用增量计算提高运算效率。
1.如由pi点确定在是正右方P2点(d>
0).,则新的中点M仅在x方向加1,新的d值为:
dnew=F(xi+2,yi+0.5)=a(xi+2)+b(yi+0.5)+c
而dold=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c
dnew=dold+a=dold-dy
2.如由pi点确定是右上方P1点(d<
0),则新的中点M在x和y方向都增加1,新的d值为
dnew=F(xi+2,yi+1.5)=a(xi+2)+b(yi+1.5)+c
dnew=dold+a+b=dold-dy+dx
在每一步中,根据前一次第二迭中计算出的d值的符号,在正右方和右上方的两个点中进行选择。
d的初始值:
d0=F(x0+1,y0+0.5)=F(x0,y0)+a+b/2=a+b/2=-dy+dx/2
F(x0,y0)=0,(x0,y0)在直线上。
为了消除d的分数,重新定义F(x,y)=2(ax+by+c)
则每一步需要计算的dnew是简单的整数加法
dy=y1-y0,dx=x1-x0
d0=-2dy+dx
dnew=dold-2*dy,当dold>
=0
dnew=dold-2(dy-dx),当dold<
Bresenham画线算法
与DDA算法相似,Bresenham画线算法也要在每列象素中找到与理想直线最逼近的象素点。
根据直线的斜率来确定变量在x或y方向递增一个单位。
另一个方向y或x的增量为0或1,它取决于实际直线与最接近网格点位置的距离。
这一距离称为误差。
算法的巧妙构思,使每次只需检查误差项(增量)的符号即可。
定义决策变量:
d=d+k(0<
1)
1,如直线上的一点为(x,y),则下一点为:
(x+1,y)(d<
0.5)或(x+1,y+1)(d>
=0.5)
当d>
1时,让d=d-1,以保证0<
=d<
1,d0=0
令e=d-0.5(0<
1),则e0=-0.5
则下一点为:
(x+1,y),(e<
0)
(x+1,y+1)(e>
=0)
当e>
0时,让e=e-1,(重新初始化误差项)
由于算法只用到误差项的符号,为了改用整数以避免除法,可以作如下替换:
e=2*e*dx
定义决策变量e=2*e*dx,则e0=-dx,e=e+2*dy
(x+1,y),(e<
(x+1,y+1)(e>
=0)
0时,让e=e-dx,(重新初始化误差项)
实验环境
硬件平台:
PC
软件(推荐):
Windows平台,VisualC++,matlab
实验步骤
1.掌握算法原理;
2.依据算法,编写源程序并进行调试;
3.对运行结果进行保存与分析;
4.把源程序以文件的形式提交;
5.按格式书写实验报告。
实验内容
实验源程序如下:
voidCLineDlg:
:
OnRadioPlus()//缺省选择
{
//TODO:
Addyourcontrolnotificationhandlercodehere
Algorithm=0;
//算法选择
}
OnRadio()
Algorithm=2;
OnRadio1()
Algorithm=1;
OnLinedraw()
CWnd*pWnd=GetDlgItem(IDC_STATIC);
CDC*pControlDC=pWnd->
GetDC();
pWnd->
Invalidate();
UpdateWindow();
pControlDC->
SetViewportOrg(0,0);
MoveTo(0,0);
pControlDC->
LineTo(0,335);
LineTo(400,0);
inti,j;
for(i=0;
i<
=400;
i+=10)
for(j=0;
j<
=335;
j++)
pControlDC->
SetPixel(i,j,RGB(200,200,200));
SetPixel(j,i,RGB(200,200,200));
intx1,y1,x0,y0;
UpdateData(true);
x1=m_x1;
x0=m_x0;
y1=m_y1;
y0=m_y0;
switch(Algorithm)
{
case0:
{
inta,b,d1,d2,d,x,y;
floatdy,dx,m;
dx=float(x1-x0);
dy=float(y1-y0);
m=dy/dx;
if(m<
=1)
a=y0-y1;
b=x1-x0;
d=2*a+b;
d1=2*a;
d2=2*(a+b);
x=x0;
y=y0;
pControlDC->
SetPixel(x,y,RGB(0,255,0));
while(x<
x1)
{
if(d<
{x++;
y++;
d+=d2;
else
d+=d1;
pControlDC->
}
}
else
a=x0-x1;
b=y1-y0;
x=y0;
y=x0;
y1)
{x++;
y++;
d+=d2;
d+=d1;
SetPixel(y,x,RGB(0,255,0));
break;
}
case1:
floatdy,dx,m;
dx=float(x1-x0);
m=dy/dx;
if(m<
{
intx;
floaty;
y=float(y0);
for(x=x0;
x<
=x1;
x++)
{
SetPixel(x,(int)(y+0.5),RGB(0,0,255));
y=y+m;
}
else
inty;
floatx;
x=float(x0);
for(y=y0;
y<
=y1;
y++)
SetPixel((int)(x+0.5),y,RGB(0,0,255));
x=x+1/m;
break;
}
case2:
intx,y,dx,dy,e,i;
floatd1y,d1x,m;
d1x=float(x1-x0);
d1y=float(y1-y0);
m=d1y/d1x;
dx=x1-x0;
dy=y1-y0;
e=-dx;
for(i=0;
=dx;
i++)
SetPixel(x,y,RGB(255,0,0));
x++;
e=e+2*dy;
if(e>
=0){y++;
e=e-2*dx;
dx=y1-y0;
dy=x1-x0;
e=-dy;
SetPixel(y,x,RGB(255,0,0));