学习文档仅供参考
实验一直线、圆弧及曲线的生成算法
一、实验目的
1、几种直线生成算法的比较,特别掌握用Brenham直线生成算法。
2、几种圆弧生成算法的比较,掌握Brenham圆弧生成算法。
3、掌握用像素点法直接生成其它曲线的方法。
二、基本要求
1、用不同的生成算法在屏幕上绘制出直线的图形,对不同的算法可设置不同的线形或
颜色表示区别。
2、用Brenham生成算法在屏幕上绘制出圆弧的图形,用动画的方式表演图形的生成。
三、算法提示
1、有关直线生成算法有:DDA〔数值微分〕直线算法、逐点比较法、直线Brenham
生成算法。
直线Brenham生成算法思想如下〔第一象限,且斜率k<1的情况图2-1a中的1a〕:
1)画点〔x
1
,y
1
〕,dx=x
2
-x
1
,dy=y
2
-y
1
,计算误差初值P
1
=2dy-dx,i=1;
2)求直线下一点位置x
i+1
=x
i
+1如果P
i
>0,则y
i+1
=y
i
+1,否则y
i+1
=y
i
;
3)画点〔x
i+1
,y
i+1
〕;
4)求下一个误差P
i+1
点,如果P
i
>0,则P
i+1
=P
i
+2dy-2dx,否则P
i+1
=P
i
+2dy;
5)i=i+1,如果i
Brenham生成算法的优点如下;
1〕不必计算直线的斜率,因此不做除法。
2〕不用浮点数,只用整数。
3〕只做整数加减运算和乘2运算,而乘2运算可以用移位操作实现。
Brenham算法的速度很快,并适于用硬件实现。
对于图2-1a中的2a,只需将x
i+1
=x
i
+1改为x
i+1
=x
i
-1。
对于图2-1a中的1b,斜率k>1的情况,可交换变量x和y,y每次长1个单位。对P
i
进行判断,x
i+1
=x
i
或x
i+1
=x
i
+1。
2、有关圆弧生成算法有:逐点比较法、DDA〔数值微分〕直线算法、圆的Brenham
生成算法。
圆的生成算法一般将圆划分为8等份,只需计算(900,450)的八分之一圆弧,其它用对称法
求得(参见图2-1b)。
Brenham生成算法思想如下〔第一象限,且斜率k<1的情况〕:
1)计算误差初值P
1
=3-2r,i=1,画点〔0,r〕;
2)求下一个光栅点位置x
i+1
=x
i
+1如果P
i
<0,则y
i+1
=y
i
,否则y
i+1
=y
i
-1;
3)画点〔x
i+1
,y
i+1
〕;
学习文档仅供参考
4〕求下一个误差P
i+1
点,如果P
i
<0,则P
i+1
=P
i
+2x
i
+6,否则P
i+1
=P
i
+4(x
i
-y
i
)+10;
5)i=i+1,如果x=y则结束操作,否则转步骤2。
圆Brenham算法的算式简单,只需做加减法和乘4运算
3.对屏幕布局的考虑
适当选取坐标,将屏幕分成几个区域性,在每个区域内实现一种算法,生成一个图形。
也可用delay实现延时实现动画。
四、上机作业题及思考题
1、用正负法编程绘制圆弧
2、用直线Brenham生成算法绘制直线。
3、用Brenham生成算法绘制圆。
五、参考源程序
1、数值微分法生成斜率小于90的直线
/*DDAline数值微分法生成斜率小于90的直线*/
#include
#include"display.h"
main()
{
intxo,yo,xa,ya,i,j;
intdx,dy,c;
floatddx,ddy,x,y;
Initialize();
printf("inputstartx,y(x=0-640,y=0-480)n");
scanf("%d,%d",&xo,&yo);/*输入直线的两个点*/
printf("xa:%d--639",xo);
scanf("%d",&xa);
printf("ya:0..%d",yo);
scanf("%d",&ya);
printf("redlineissystem,yellowiscreaten");
if(xa>=xo&&xa<=639&&ya>=0&&ya<=yo)
/*数值微分法生成直线算法*/
o
1b
2b
2a
3a
3b
4b
4a
1a
3b
4b
3a
2a
o
4a
1a
1b
2b
图2-1a直线方向的8个象限
图2-1b圆心在(0,0)点圆周
(y,x)(-y,x)
(x,y)
(y,-x)
(-y,-x)
(-x,-y)
(-x,y)
生成时的对称变换
(x,y)
11
(x,y)
22
(x,-y)
学习文档仅供参考
{
outtextxy(xo,yo+5,"o");
outtextxy(xa,ya-10,"a");
dx=xa-xo;
dy=yo-ya;
if(dx>dy)c=dx;
elc=dy;
ddx=dx*1.0/c;
ddy=dy*1.0/c;
x=xo*1.0;
y=yo*1.0;
tcolor(12);
line(xo,yo,xa,ya);
getch();
while(c>=0)
{i=round(x);
j=round(y);
putpixel(i,j,14);
x=x+ddx;
y=y-ddy;
c=c-1;
}
}
elprintf("dataerror");
getch();
clograph();
}
intround(ff)
floatff;
{intk;
if((ff-(int)ff)>0.5)k=(int)ff+1;
elk=(int)ff;
k=(int)ff;
return(k);
}
2、逐点插补法生成圆弧源程序
/*STEPCIRCLE逐点插补法生成圆弧*/
#include
#include"display.h"
main()
{
intxo,yo,xa,ya,r,l,f;
Initialize();
printf("inputx,y,r");/*输入圆心和半径*/
学习文档仅供参考
scanf("%d,%d,%d",&xo,&yo,&r);
xa=xo+r;
ya=yo;
tcolor(12);
circle(xo,yo,r);
line(xo-r,yo,xo+r,yo);
line(xo,yo-r,xo,yo+r);
line(xo,yo,xo+140,yo-140);
l=r*1.414/2;
f=0;
while(l!=0)
{
putpixel(xa,ya,14);
putpixel(xa,2*yo-ya,14);
putpixel(2*xo-xa,ya,14);
putpixel(2*xo-xa,2*yo-ya,14);
putpixel(xo+ya-yo,yo+xa-xo,14);
putpixel(xo+ya-yo,yo-xa+xo,14);
putpixel(xo-ya+yo,yo+xa-xo,14);
putpixel(xo-ya+yo,yo-xa+xo,14);
getch();
if(f>=0)
{
xa=xa-1;
f=f-2*(xa-xo)+1;
}
el
{
ya=ya-1;
f=f+2*(yo-ya)+1;
l=l-1;
}
}
getch();
clograph();
}
3、椭圆的生成算法
/*elip生成椭圆*/
#include
#include"display.h"
main()
{
Initialize();
draw_ett(180,100,14);
学习文档仅供参考
getch();
clograph();
}
draw_ett(a,b,color)
inta,b,color;
{intx,y,xo,yo;
intl;
floatf,ff;
xo=300;
yo=200;
x=0;
y=b;
f=1.0*b*b+a*a*(-b+0.25);
putpixel(xo,yo,12);
while(1.0*b*b*(x+1)<=a*a*(y-0.5))
{
putpixel(x+xo,yo-y,color);
if(f<0)
{
f=f+1.0*b*b*(2*x+3);
x=x+1;}
el{
f=f+1.0*b*b*(2*x+3)+1.0*a*a*(-2*y+2);
x=x+1;
y=y-1;
}
}
f=1.0*b*b*(x+0.5)*(x+0.5)+1.0*a*a*(y-1)*(y-1)-1.0*a*b*a*b;
while(y>0)
{
putpixel(x+xo,yo-y,color);
if(f<0)
{
f=f+1.0*b*b*(2*x+2)+1.0*a*a*(-2*y+3);
x=x+1;
y=y-1;}
el{
f=f+1.0*a*a*(-2*y+3);
y=y-1;
}
}
}
学习文档仅供参考
电脑图形学实验报告一
实验名称直线、圆弧及曲线的生成算法评分
实验日期年月日指导教师
专业班级学号
一、实验目的
二、实验要求
三、关键算法及实现原理
四、程序调试中的问题
五、程序运行结果或数据
六、实验收获及体会
七、参考源程序(可附页)
学习文档仅供参考
实验二二维图形的几何变换
一、实验目的
1、复习不同的二维坐标变换公式。
2、掌握二维坐标变换公式的使用方法。
3、对二维坐标组合变换的灵活运用。
二、基本要求
1、在屏幕上绘制出较简单的几何图形。
2、对1的图形进行平移变换,绘制出变换后的几何图形,并在下边标注出实施x,y
各多少的平称坐标变换。
3、对1的图形进行旋转变换,绘制出变换后的几何图形,并在下边标注出实施多少度
的旋转坐标变换。
4、对1的图形进行对称变换,绘制出变换后的几何图形,并在下边标注出实施对什么
坐标进行的对称变换。
5、对1的图形进行错切变换,绘制出变换后的几何图形,并在下边标注出实施对何种
坐标进行的错切变换。
6、对1的图形进行比例变换,绘制出变换后的几何图形,并在下边标注出实施的多少
比例坐标变换。
7、为了进行比较,适当选择坐标,可将原图〔变换前〕及经过不同变换后的图形绘制
在同一个屏幕上,设置不同的线形或颜色加以区分各种变换。
三、算法提示
1、二维图形的变换实际上是一个变换矩阵,平面图形是由假设干个二维点(x
i
,y
i
)组成,
经过变换后的二维点(x’
i
,y’
i
),其变换公式为:
对应于不同的变换,都是用矩阵乘法来计算坐标,只需改变变换矩阵即可。因此对每一
种坐标变换编成一个子程序。
2、编程时的技巧
用数组将二维图形的特征坐标点〔顶点〕保存,将由特征坐标点〔顶点〕绘制出二维图
形的命令编一个绘图子程序,调用绘图子程序绘制出变换以前的图形,根据不同的两维几何
变换,选用相应二维坐标变换公式〔调用相应的子程序〕将二维坐标进行坐标变换;再调用
绘图子程序将变换后的坐标值在屏幕上绘制变换后的几何将图形,可选用不同的颜来区分各
种不同几何变换的图形。
四、上机作业题
1
0
0a
1
1......
1......
1
1
1
1......
1......
1
1
22
21
''
'
2
'
2
'
1
'
1
lm
dc
b
yx
yx
yx
yx
yx
yx
nn
nn
学习文档仅供参考
1、编写一个能对任何直线能实现对称变换的子程序。
2、作出右边的图形,并作以下变换,用不
同颜色作出变换后的图形。
1)作平移〔50,-150〕。
2)旋转–90度。
3)对X=Y直线作对称变换。
4)沿Y方向作错切变换。
五、参考实例源程序
下面是对四边形能完成单项二维变换
〔平移、比例、错切〕的源程序
#include
#include
#include
#include
doublexmax=639.0,ymax=399.0;
doublef[3][3],xx,yy;
intscx(doublexj)
{
intx;
x=(int)(xj+xmax/2);
return(x);
}
intscy(doubleyj)
{
inty;
y=ymax-(int)(yj+ymax/2);
return(y);
}
voidparallel(doubledx,doubledy)
{
f[0][0]=1.0;f[0][1]=0.0;f[0][2]=0.0;
f[1][0]=0.0;f[1][1]=1.0;f[1][2]=0.0;
学习文档仅供参考
f[2][0]=dx;f[2][1]=dy;f[2][2]=1.0;
}
voidscale(doubles)
{
f[0][0]=s;f[0][1]=0.0;f[0][2]=0.0;
f[1][0]=0.0;f[1][1]=s;f[1][2]=0.0;
f[2][0]=0.0;f[2][1]=0.0;f[2][2]=1.0;
}
voidtaisho_y()
{
f[0][0]=-1.0;f[0][1]=0.0;f[0][2]=0.0;
f[1][0]=0.0;f[1][1]=1.0;f[1][2]=0.0;
f[2][0]=0.0;f[2][1]=0.0;f[2][2]=1.0;
}
voidaxis()
{
line(scx(0.0),scy(-ymax/2),scx(0),scy(ymax/2));
line(scx(-xmax/2),scy(0.0),scx(xmax/2),scy(0.0));
}
voidtuoq(doublea,doubleb)
{
f[0][0]=1.0;f[0][1]=b;f[0][2]=1.0;
f[1][0]=a;f[1][1]=1.0;f[1][2]=0.0;
f[2][0]=0.0;f[2][1]=0.0;f[2][2]=1.0;
}
doubleaffinex(doublex,doubley,doubled)
{
xx=x*f[0][0]+y*f[1][0]+d*f[2][0];
return(xx);
}
学习文档仅供参考
doubleaffiney(doublex,doubley,doubled)
{
yy=x*f[0][1]+y*f[1][1]+d*f[2][1];
return(yy);
}
voiddrawtu(x2,y2)
doublex2[5],y2[5];
{
inti;
for(i=0;i<=3;i++)
{
line(scx(x2[i]),scy(y2[i]),scx(x2[i+1]),scy(y2[i+1]));
}
}
voidmain()
{intdrive=DETECT,mode;
staticdoublex1[]={50.0,60.0,150.0,160.0,50.0};
staticdoubley1[]={0.0,50.0,50.0,-10.0,0.0};
staticdoublex2[5],y2[5];
inti;
doublex,y,xx,yy,yt;
initgraph(&drive,&mode,"c:tc3bgi");
tcolor(RED);
axis();
for(i=0;i<=3;i++)
{
line(scx(x1[i]),scy(y1[i]),scx(x1[i+1]),scy(y1[i+1]));
}
/*parallel(100,-100)*/
getch();
学习文档仅供参考
x=100;y=-100;
parallel(x,y);
tcolor(BLUE);
for(i=0;i<=4;i++)
{
x2[i]=affinex(x1[i],y1[i],1.0);
y2[i]=affiney(x1[i],y1[i],1.0);
}
drawtu(x2,y2);
yt=scy(y2[0])+10;
outtextxy(scx(x2[0]),yt,"parallel(100,-100)");
/*taisho_y()*/
getch();
taisho_y();
tcolor(YELLOW);
for(i=0;i<=4;i++)
{
x2[i]=affinex(x1[i],y1[i],1.0);
y2[i]=affiney(x1[i],y1[i],1.0);
}
drawtu(x2,y2);
yt=scy(y2[0])+10;
outtextxy(scx(x2[0]),yt,"taisho_y");
/*touq(2,0)*/
getch();
tuoq(2,0);
tcolor(LIGHTBLUE);
for(i=0;i<=4;i++)
{
x2[i]=affinex(x1[i],y1[i],1.0);
学习文档仅供参考
y2[i]=affiney(x1[i],y1[i],1.0);
}
drawtu(x2,y2);
yt=scy(y2[0])+10;
outtextxy(scx(x2[0]),yt,"tuoq(2,0)");
/*scale(2)*/
getch();
scale(2);
tcolor(LIGHTRED);
for(i=0;i<=4;i++)
{
x2[i]=affinex(x1[i],y1[i],1.0);
y2[i]=affiney(x1[i],y1[i],1.0);
}
drawtu(x2,y2);
yt=scy(y2[0])+10;
outtextxy(scx(x2[0]),yt,"scale2");
getch();
clograph();
}
学习文档仅供参考
电脑图形学实验报告二
实验名称二维图形的几何变换评分
实验日期年月日指导教师
专业班级学号
一、实验目的
二、实验要求
三、关键算法及实现原理
四、程序调试中的问题
五、程序运行结果或数据
六、实验收获及体会
七、参考源程序(可附页)
学习文档仅供参考
实验三进行多边形的裁剪及填充
一、实验目的
1、复习编码裁剪法和矢量裁剪法。
2、复习多边形区域填充和种子填充的原理和算法。
3、掌握编码裁剪法的编程方法和步骤。
4、多边形逐边裁剪法的编程方法实现编程。
5、掌握种子填充算法的基本原理和编程方法。
二、基本要求
1、在屏幕上绘制出一个矩形作为裁剪边界,再用不同的颜色绘出几个由线段组成的简
单几何图形,它们和裁剪边界可相交或不相交。按一个键,实现一条线段的裁剪,裁剪后的
线段可用另一种颜色绘制,继续按键,直至全部线段裁剪完。
2、在屏幕上绘制用线、矩形、圆、多边形等绘制一些简单的几何图形,选择合适的种子
坐标,用种子填充方法将它填充。对于被划分为多个区域的几何图形,注意观察改变种子坐
标点的位置,所填充的区域不同。
三、算法提示
1、Sutherland-Cohen(编码)裁剪算法
用数组保存裁剪边界的坐标值和被裁剪边界的坐标值;根据逐边裁剪方法对被裁剪边界
进裁剪,计算出裁剪后的坐标;再将裁剪后的直线用不同颜色绘制到屏幕上。
2、Sutherland-Hodgman多边形裁剪算法
多边形裁剪算法的关键在于,通过裁剪,不仅要保留窗口内多边形的边界部分,而且要
将窗框有关部分按一定的次序插入多边形保留边界之间,从而使多边形的边仍然保持封闭状
态。
Sutherland-Hodgman多边形裁剪算法:令多边形的顶点按边线逆时针走向排序P
1
、P
2
、…、
P
n
,多边形各边先与上窗框求交。求交后删去多边形一窗框之上的部分,并插入窗边及延长
线与多边形的交点之间的部分,从而形成一个新多边形。然后,新的多边形按相同的方法与
右窗框相剪裁。如此重重,直至多边形与各窗框都裁剪完毕。
3、种子填充算法
种子填充算法采用的边界定义是区域边界上所有像素均具有某个特定值,区域内部所有
像素均不取这一特定颜色。用函数getpixel(edx,edy)取出种子坐标点(edx,edy)的像素
点的颜色,如果它的颜色值不等于边界指定的颜色值,则对它用指定的颜色进行填充。用四
向连通方法是指从区域上一点(种子坐标点)出发,可通过上、下、左、右四个方向(沿X,Y
坐标正负方向各前进一个单位)作为新的种子点进行填充。编程时宜采用递归方式进行。
四、上机作业题
1、编写编码裁剪算法源程序,并实现对一些图形的裁剪
2、用种子填充算法编程实现对几个二维图形的填充。
五、实例源程序
1.Sutherland-Hodglman多边形裁剪算法源程序,用一个矩形作为裁剪边界裁剪一个多
学习文档仅供参考
边形,要求数据结构的链表学得较好。
/*Sutherland-Hodgman算法*/
#defineLENsizeof(structnode)
#include
#include"display.h"
structnode{
intdx,dy;
structnode*next;
};
structnode*creat()
{structnode*h,*q,*r;
intp[8][2]={100,120,160,50,180,100,200,80,240,160,210,220,170,160,140,190};
inti;
tcolor(12);
for(i=0;i<7;i++)line(p[i][0],p[i][1],p[i+1][0],p[i+1][1]);
line(p[0][0],p[0][1],p[7][0],p[7][1]);
rectangle(120,200,230,70);
h=NULL;
for(i=0;i<8;i++)
{q=(structnode*)malloc(LEN);
q->dx=p[i][0];q->dy=p[i][1];
if(h==NULL)h=q;
elr->next=q;
r=q;
}
r->next=NULL;
return(h);
}
structnode*builx(h,x)
structnode*h;
intx;
{ints[2],j[2];
structnode*hh,*p,*r,*q;
intmax,min;
p=h;hh=NULL;
s[0]=p->dx;s[1]=p->dy;
p=p->next;
while(p!=NULL)
{j[0]=x;
j[1]=s[1]+(p->dy-s[1])*(x-s[0])/(p->dx-s[0]);
max=s[0];min=p->dx;
if(s[0]
if((j[0]>=min)&&(j[0]<=max))
{q=(structnode*)malloc(LEN);
学习文档仅供参考
q->dx=j[0];q->dy=j[1];
if(hh==NULL)hh=q;
elr->next=q;
r=q;
}
if(p->dx>=x)
{q=(structnode*)malloc(LEN);
q->dx=p->dx;q->dy=p->dy;
if(hh==NULL)hh=q;
elr->next=q;
r=q;
}
s[0]=p->dx;s[1]=p->dy;
p=p->next;
}
p=h;
j[0]=x;j[1]=s[1]+(p->dy-s[1])*(x-s[0])/(p->dx-s[0]);
max=s[0];min=p->dx;
if(s[0]
if((j[0]>=min)&&(j[0]<=max))
{q=(structnode*)malloc(LEN);
q->dx=j[0];q->dy=j[1];
if(hh==NULL)hh=q;
elr->next=q;
r=q;
}
if(p->dx>=x)
{q=(structnode*)malloc(LEN);
q->dx=p->dx;q->dy=p->dy;
if(hh==NULL)hh=q;
elr->next=q;
r=q;
}
r->next=NULL;
return(hh);
}
structnode*builxx(h,x)
structnode*h;
intx;
{ints[2],j[2];
structnode*hh,*p,*r,*q;
intmax,min;
p=h;
学习文档仅供参考
hh=NULL;
s[0]=p->dx;
s[1]=p->dy;
p=p->next;
while(p!=NULL)
{
j[0]=x;
j[1]=s[1]+(p->dy-s[1])*(x-s[0])/(p->dx-s[0]+0.1);
max=s[0];
min=p->dx;
if(s[0]
min=s[0];
}
if((j[0]>=min)&&(j[0]<=max))
{q=(structnode*)malloc(LEN);
q->dx=j[0];
q->dy=j[1];
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
}
if(p->dx<=x)
{q=(structnode*)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
}
s[0]=p->dx;
s[1]=p->dy;
p=p->next;
}
p=h;
j[0]=x;
j[1]=s[1]+(p->dy-s[1])*(x-s[0])/(p->dx-s[0]+0.1);
max=s[0];
min=p->dx;
if(s[0]
min=s[0];
}
if((j[0]>=min)&&(j[0]<=max))
学习文档仅供参考
{q=(structnode*)malloc(LEN);
q->dx=j[0];
q->dy=j[1];
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
}
if(p->dx<=x)
{q=(structnode*)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
}
r->next=NULL;
return(hh);
}
structnode*buily(h,y)
structnode*h;
inty;
{ints[2],j[2];
structnode*hh,*p,*r,*q;
intmax,min;
p=h;
hh=NULL;
s[0]=p->dx;
s[1]=p->dy;
p=p->next;
while(p!=NULL)
{
j[1]=y;
j[0]=s[0]+(p->dx-s[0])*(y-s[1])/(p->dy-s[1]+0.1);
max=s[1];
min=p->dy;
if(s[1]
min=s[1];
}
if((j[1]>=min)&&(j[1]<=max))
{q=(structnode*)malloc(LEN);
q->dx=j[0];
学习文档仅供参考
q->dy=j[1];
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
}
if(p->dy>=y)
{q=(structnode*)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
}
s[0]=p->dx;
s[1]=p->dy;
p=p->next;
}
p=h;
j[1]=y;
j[0]=s[0]+(p->dx-s[0])*(y-s[1])/(p->dy-s[1]+0.1);
max=s[1];
min=p->dy;
if(s[1]
min=s[1];
}
if((j[1]>=min)&&(j[1]<=max))
{q=(structnode*)malloc(LEN);
q->dx=j[0];
q->dy=j[1];
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
}
if(p->dy>=y)
{q=(structnode*)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
学习文档仅供参考
}
r->next=NULL;
return(hh);
}
structnode*builyy(h,y)
structnode*h;
inty;
{ints[2],j[2];
structnode*hh,*p,*r,*q;
intmax,min;
p=h;
hh=NULL;
s[0]=p->dx;
s[1]=p->dy;
p=p->next;
while(p!=NULL)
{
j[1]=y;
j[0]=s[0]+(p->dx-s[0])*(y-s[1])/(p->dy-s[1]+0.1);
max=s[1];
min=p->dy;
if(s[1]
min=s[1];
}
if((j[1]>=min)&&(j[1]<=max))
{q=(structnode*)malloc(LEN);
q->dx=j[0];
q->dy=j[1];
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
}
if(p->dy<=y)
{q=(structnode*)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
}
s[0]=p->dx;
学习文档仅供参考
s[1]=p->dy;
p=p->next;
}
p=h;
j[1]=y;
j[0]=s[0]+(p->dx-s[0])*(y-s[1])/(p->dy-s[1]+0.1);
max=s[1];
min=p->dy;
if(s[1]
min=s[1];
}
if((j[1]>=min)&&(j[1]<=max))
{q=(structnode*)malloc(LEN);
q->dx=j[0];
q->dy=j[1];
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
}
if(p->dy<=y)
{q=(structnode*)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if(hh==NULL)
hh=q;
elr->next=q;
r=q;
}
r->next=NULL;
return(hh);
}
main()
{
intmax,min;
structnode*head,*r,*q;
inti;
ints[2];
Initialize();
head=creat();
q=head;
while(q->next!=NULL)
{putpixel(q->dx,q->dy,14);
q=q->next;
学习文档仅供参考
}
putpixel(q->dx,q->dy,14);
q=builx(head,120);
head=q;
while(q->next!=NULL)
{putpixel(q->dx,q->dy,15);
q=q->next;
}
putpixel(q->dx,q->dy,15);
q=buily(head,70);
head=q;
while(q->next!=NULL)
{putpixel(q->dx,q->dy,2);
q=q->next;
}
putpixel(q->dx,q->dy,2);
q=builxx(head,230);
head=q;
while(q->next!=NULL)
{putpixel(q->dx,q->dy,1);
q=q->next;
}
putpixel(q->dx,q->dy,1);
q=builyy(head,200);
head=q;
s[0]=q->dx;
s[1]=q->dy;
q=q->next;
tcolor(14);
while(q!=NULL)
{line(s[0],s[1],q->dx,q->dy);
s[0]=q->dx;
s[1]=q->dy;
q=q->next;
}
q=head;
line(s[0],s[1],q->dx,q->dy);
getch();
}
2.四向连通种子填充算法子程序
Fill4(intedx,intedy,intcolor)
{intfill;
fill=getpixel(edx,edy);
if(fill!=color)
学习文档仅供参考
{
putpixel(edx,edy,color);
Fill4(edx+1,edy,color);
Fill4(edx-1,edy,color);
Fill4(edx,edy+1,color);
Fill4(edx,edy-1,color);
}
}
学习文档仅供参考
电脑图形学实验报告三
实验名称进行多边形的裁剪及填充评分
实验日期年月日指导教师
专业班级学号
一、实验目的
二、实验要求
三、关键算法
四、程序调试中的问题
五、程序运行结果或数据
六、实验收获及体会
七、参考源程序(可附页)
学习文档仅供参考
实验四绘制三维图形
一、实验目的
1、复习用二维图来表示三维立体图形,三视图的表示及的三视图的变换矩阵
2、掌握用C语言编程实现三维简单立体的三视图的绘制
二、基本要求
1、在屏幕上绘制出一个长方体或简单几何体的三视图投影图形,要求在图形下方标出
是什么投影图形。
2、在屏幕上绘制出一个长方体或简单几何体的透视投影图形。
三、算法提示
1、二维屏幕表示三维立体图的关键:屏幕是一个二维的平面空间,要在它上做出三维
的图形,就必须把三维的空间图形通过一个投影变换变为二维的图形,即投影变换把三维坐
标点〔x,y,z〕变为(x’,0,z’)。
2、投影变换的类型
3、按下述步骤编写绘制三维图形的函数
①在草稿纸上给出草图,并确定各顶点的序号和相应的顶点坐标值,建立顶点表
和连边表。
②在程序中定义三个数组,用于存放顶点的(x,y,z)的坐标值。
③实施对立方体进行相应的投影变换,即对顶点矩阵与变换矩阵相乘,得到一个
新的顶点矩阵。
④用新顶点表的坐标值,注意些时只有x坐标和z坐标,y坐标已在投影中消掉,
投影
平行投影
正平行投影
斜平行投影
透视投影
一点透视
三点透视
正投影
正轴侧投影
主视图
俯视图
侧视图
二点透视
一点透视
三点透视
正等侧
正二侧
学习文档仅供参考
按边表的连线规则,用line函数在顶点之间两两连线。
3、将每一个几何变换编写成一个函数,在主程序中进行坐标变换时,直接调用相
应的函数即可;变换后调用绘图函数用不同颜色在屏幕上绘出变换后的图形。
四、上机作业题
1、将右边的立体作出它的主视图、俯视图、侧视图。
五、实例源程序
#include
#include
#include
#include
doublexmax=639.0,ymax=399.0;
doublef[4][4],xx,yy,zz,dd;
intscx(doublexj)
{intx;
x=(int)(-xj+xmax/2);
return(x);
}
intscy(doubleyj)
{inty;
y=ymax-(int)(yj+ymax/2);
return(y);
}
voidtv()
{
f[0][0]=1.0;f[0][1]=0.0;f[0][2]=0.0;f[0][3]=0.0;
f[1][0]=0.0;f[1][1]=0.0;f[1][2]=0.0;f[1][3]=0.0;
f[2][0]=0.0;f[2][1]=0.0;f[2][2]=1.0;f[2][3]=0.0;
f[3][0]=0.0;f[3][1]=0.0;f[3][2]=1.0;f[3][3]=1.0;
学习文档仅供参考
}
voidth(intn)
{
f[0][0]=1.0;f[0][1]=0.0;f[0][2]=0.0;f[0][3]=0.0;
f[1][0]=0.0;f[1][1]=0.0;f[1][2]=-1.0;f[1][3]=0.0;
f[2][0]=0.0;f[2][1]=0.0;f[2][2]=0.0;f[2][3]=0.0;
f[3][0]=0.0;f[3][1]=0.0;f[3][2]=-n;f[3][3]=1.0;
}
voidtw(intd)
{
f[0][0]=0.0;f[0][1]=0.0;f[0][2]=0.0;f[0][3]=0.0;
f[1][0]=-1.0;f[1][1]=0.0;f[1][2]=0.0;f[1][3]=0.0;
f[2][0]=0.0;f[2][1]=0.0;f[2][2]=1.0;f[2][3]=0.0;
f[3][0]=-d;f[3][1]=0.0;f[3][2]=0.0;f[3][3]=1.0;
}
voidteq()
{
f[0][0]=0.707;f[0][1]=0.0;f[0][2]=-0.408;f[0][3]=0.0;
f[1][0]=-0.707;f[1][1]=0.0;f[1][2]=-0.408;f[1][3]=0.0;
f[2][0]=0.0;f[2][1]=0.0;f[2][2]=0.816;f[2][3]=0.0;
f[3][0]=0.0;f[3][1]=0.0;f[3][2]=0.0;f[3][3]=1.0;
}
voidtt1yq(doublel,doublen,doublem,doubleq)
{
f[0][0]=1.0;f[0][1]=0.0;f[0][2]=0.0;f[0][3]=0.0;
f[1][0]=0.0;f[1][1]=0.0;f[1][2]=0.0;f[1][3]=q;
f[2][0]=0.0;f[2][1]=0.0;f[2][2]=1.0;f[2][3]=0.0;
f[3][0]=l;f[3][1]=0.0;f[3][2]=n;f[3][3]=m*q+1;
}
voidaxis()
{
line(scx(0.0),scy(ymax/2),scx(0),scy(0.0));
line(scx(0),scy(0),scx(xmax/2),scy(-ymax/2)-19);
line(scx(0),scy(0),scx(-xmax/2),scy(-ymax/2)-19);
学习文档仅供参考
outtextxy(scx(0),ymax/2+10,"O");
outtextxy(scx(-xmax/2+10),scy(-ymax/2)-10,"Y");
outtextxy(scx(xmax/2),scy(-ymax/2)-10,"X");
outtextxy(scx(0)+3,scy(ymax/2)+6,"Z");
}
doubleaffine3x(doublex,doubley,doublez,doubled)
{
xx=x*f[0][0]+y*f[1][0]+z*f[2][0]+d*f[3][0];
return(xx);
}
doubleaffine3y(doublex,doubley,doublez,doubled)
{
yy=x*f[0][1]+y*f[1][1]+z*f[2][1]+d*f[3][1];
return(yy);
}
doubleaffine3z(doublex,doubley,doublez,doubled)
{
zz=x*f[0][2]+y*f[1][2]+z*f[2][2]+d*f[3][2];
return(zz);
}
doubleaffine3d(doublex,doubley,doublez,doubled)
{
dd=x*f[0][3]+y*f[1][3]+z*f[2][3]+d*f[3][3];
return(dd);
}
voiddraw(x1,z1)
doublex1[8],z1[8];
{
line(scx(x1[0]),scy(z1[0]),scx(x1[1]),scy(z1[1]));
line(scx(x1[0]),scy(z1[0]),scx(x1[3]),scy(z1[3]));
line(scx(x1[1]),scy(z1[1]),scx(x1[2]),scy(z1[2]));
line(scx(x1[2]),scy(z1[2]),scx(x1[3]),scy(z1[3]));
line(scx(x1[2]),scy(z1[2]),scx(x1[1]),scy(z1[1]));
line(scx(x1[3]),scy(z1[3]),scx(x1[4]),scy(z1[4]));
学习文档仅供参考
line(scx(x1[2]),scy(z1[2]),scx(x1[7]),scy(z1[7]));
line(scx(x1[1]),scy(z1[1]),scx(x1[6]),scy(z1[6]));
line(scx(x1[4]),scy(z1[4]),scx(x1[7]),scy(z1[7]));
line(scx(x1[4]),scy(z1[4]),scx(x1[5]),scy(z1[5]));
line(scx(x1[6]),scy(z1[6]),scx(x1[7]),scy(z1[7]));
line(scx(x1[6]),scy(z1[6]),scx(x1[5]),scy(z1[5]));
line(scx(x1[5]),scy(z1[5]),scx(x1[0]),scy(z1[0]));
}
voidmain()
{intdrive=DETECT,mode;
staticdoublex0[]={60.0,0.0,0.0,175.0,175.0,60.0,0.0,0.0};
staticdoubley0[]={75.0,75.0,75.0,75.0,0.0,0.0,0.0,0.0};
staticdoublez0[]={125.0,125.0,0.0,0.0,0.0,125.0,125.0,0.0};
staticdoublex1[8],y1[8],z1[8],dd[8];
staticdoublex2[8],y2[8],z2[8];
staticdoublex3[8],y3[8],z3[8];
inti;
doublex,xx,yy,zz,zt;
initgraph(&drive,&mode,"c:tc3bgi");
axis();
teq();
for(i=0;i<=7;i++)
{
x1[i]=affine3x(x0[i],y0[i],z0[i],1.0);
y1[i]=affine3y(x0[i],y0[i],z0[i],1.0);
z1[i]=affine3z(x0[i],y0[i],z0[i],1.0);
}
tcolor(RED);
draw(x1,z1);
zt=scy(z1[0])+10;
outtextxy(scx(x1[0]),zt,"tequ");
getch();
tw(20);
for(i=0;i<=7;i++)
学习文档仅供参考
{
x1[i]=affine3x(x0[i],y0[i],z0[i],1.0);
y1[i]=affine3y(x0[i],y0[i],z0[i],1.0);
z1[i]=affine3z(x0[i],y0[i],z0[i],1.0);
}
tcolor(BLUE);
draw(x1,z1);
zt=scy(z1[0])+10;
outtextxy(scx(x1[0]),zt,"tw");
getch();
th(20);
for(i=0;i<=7;i++)
{
x1[i]=affine3x(x0[i],y0[i],z0[i],1.0);
y1[i]=affine3y(x0[i],y0[i],z0[i],1.0);
z1[i]=affine3z(x0[i],y0[i],z0[i],1.0);
}
tcolor(BLUE);
draw(x1,z1);
zt=scy(z1[0])+10;
outtextxy(scx(x1[0]),zt,"th");
getch();
tv();
for(i=0;i<=7;i++)
{
x1[i]=affine3x(x0[i],y0[i],z0[i],1.0);
y1[i]=affine3y(x0[i],y0[i],z0[i],1.0);
z1[i]=affine3z(x0[i],y0[i],z0[i],1.0);
}
tcolor(BLUE);
draw(x1,z1);
zt=scy(z1[0])+10;
outtextxy(scx(x1[0]),zt,"tv");
getch();
学习文档仅供参考
tt1yq(10.0,-20.0,-30.0,-0.005);
for(i=0;i<=7;i++)
{
x1[i]=affine3x(x0[i],y0[i],z0[i],1.0);
y1[i]=affine3y(x0[i],y0[i],z0[i],1.0);
z1[i]=affine3z(x0[i],y0[i],z0[i],1.0);
dd[i]=affine3d(x0[i],y0[i],z0[i],1.0);
x1[i]=x1[i]/dd[i]-250;
y1[i]=y1[i]/dd[i];
z1[i]=z1[i]/dd[i];
}
tcolor(GREEN);
draw(x1,z1);
getch();
clograph();
}
学习文档仅供参考
电脑图形学实验报告四
实验名称绘制简单的三维图形评分
实验日期年月日指导教师
专业班级学号
一、实验目的
二、实验要求
三、关键算法及实现原理
四、程序调试中的问题
五、程序运行结果或数据
六、实验收获及体会
七、参考源程序(可附页)
学习文档仅供参考
实验五Bezier曲线和样条曲线的生成算法
一、实验目的
1、复习Bezier曲线和B样条曲线的参数表示法。
2、编程实现用二次Bezier曲线绘制。
3、编程实现用三次Bezier曲线绘制和分段光滑Bezier曲线图形的绘制。
4、用三次B样条函数绘制曲线。
二、基本要求
1、编程实现在屏幕上绘制出两次Bezie曲线的几何图形和特征多边形图形,对于
直线和曲线设置不同的线形和颜色。
2、现在屏幕上绘制出三次Bezie曲线的几何图形和特征多边形图形,对于直线和
曲线设置不同的线形和颜色。
3、编程实现用分段三次Bezier曲线绘制光滑Bezier曲线图形。
4、编程实现在屏幕上绘制出三次B样条函数绘制曲线。
5、编程实现在屏幕上绘制出光滑连接的三次B样条曲线。
三、算法提示
1、二次Bezier曲线的计算公式为:
P(t)=(P
0
-2P
1
+P
2
)t2+(-2P
0
+2P
1
)t+P
0
X(t)=(X
0
-2X
1
+X
2
)t2+(-2X
0
+2X
1
)t+X
0
Y(t)=(Y
0
-2Y
1
+Y
2
)t2+(-2Y
0
+2Y
1
)t+Y
0
其中P
0
、P
1
、P
2
为三个已知的点,坐标分别为(X
0
、Y
0
)、(X
1
、Y
1
)、(X
1
、Y
2
)。
2、次Bezier曲线的计算公式为:
P(t)=(-P
0
+3P
1
-3P
2
+P
3
)t3+(3P
0
-6P
1
+3P
2
)t2+(-3P
0
+3P
1
)t+P
0
X(t)=(-X
0
+3X
1
-3X
2
+X
3
)t3+(3X
0
-6X
1
+3X
2
)t2+(-3X
0
+3X
1
)t+X
0
Y(t)=(-Y
0
+3Y
1
-3Y
2
+Y
3
)t3+(3Y
0
-6Y
1
+3Y
2
)t2+(-3Y
0
+3Y
1
)t+Y
0
其中P
0
、P
1
、P
2
、P
3
为四个已知的点,坐标分别为(X
0
、Y
0
)、(X
1
、Y
1
)、(X
1
、
Y
2
)、(X
3
、Y
3
)。
3、三次B样条函数绘制曲线的计算公式为:
P(t)=[(-P
0
+3P
1
-3P
2
+3P
3
)t3+(3P
0
-6P
1
+3P
2
)t2+(-3P
0
+3P
2
)t+(P
0
+4P
1
+P
2
)]/6
学习文档仅供参考
X(t)=[(-X
0
+3X
1
-3X
2
+3X
3
)t3+(3X
0
-6X
1
+3X
2
)t2+(-3X
0
+3X
2
)t+(X
0
+4X
1
+X
2
)]/6
Y(t)=[(-Y
0
+3Y
1
-3Y
2
+3Y
3
)t3+(3Y
0
-6Y
1
+3Y
2
)t2+(-3Y
0
+3Y
2
)t+(Y
0
+4Y
1
+Y
2
)]/6
其中P
0
、P
1
、P
2
、P
3
为四个已知的点,坐标分别为(X
0
、Y
0
)、(X
1
、Y
1
)、(X
1
、
Y
2
)、(X
3
、Y
3
)。
4、三次B样条函数绘制曲线的光滑连接条件为:对于N个顶点,取P
1
、P
2
、P
3
、
P
4
4个顶点绘制在第一段三次样条曲线,再取P
2
、P
3
、P
4
、P
5
4个顶点绘制
在第二段三次样条曲线,总计可绘制n-3段光滑连接的三次样条曲线。
5、程序设计方法
根据Bezier曲线的定义,输入Bezier曲线的特征多边形〔例如三次Bezier曲
线输入四个型值点〕,然后把t从0~1分成n等分,按相应的Bezier曲线公式计算
出Bezier曲线上的点,用绘直线段的方法依次这些点连接起来,就得到Bezier曲
线。如果要画多段Bezier曲线,可设置一些变量存放Bezier曲线的条数,按条数
依次绘制出来即可。
四、上机作业题
1、编程绘制三次Bezier曲线。
2、编程实现光滑连接的二次B-样条曲线(至少给出8个已知点)。
3、改变已知点的坐标值,曲线形状有什么变化?
五、参考实例源程序
1、绘制二次Bezier曲线的源程序
/*二次Bezier曲线一般算法*/
#include"display.h"
voidBezier_2(intcolor,doublep[3][2])
{doublet,xt,yt;
intrate=200,x,y;
tcolor(color);
moveto(p[0][0],p[0][1]);
for(t=0;t<=1;t+=1.0/rate)
{yt=1-t;
学习文档仅供参考
xt=p[0][0]*yt*yt+p[1][0]*2*yt*t+p[2][0]*t*t;
yt=p[0][1]*yt*yt+p[1][1]*2*yt*t+p[2][1]*t*t;
x=(int)(xt);
y=(int)(yt);
lineto(x,y);
}
}
voidmain(void)
{staticdoublep[3][2]={50,400,340,20,635,420};
constN0=3;/*特征顶点个数*/
inti;
Initialize();/*SetsystemintoGraphicsmode*/
tcolor(WHITE);
moveto(p[0][0],p[0][1]);
for(i=1;i
Bezier_2(LIGHTRED,p);
while(getch()!=ESC);/*按ESC键退出*/
clograph();/*Returnthesystemtotextmode*/
}
2、实现光滑连接的三次B-样条曲线源程序
#include"graphics.h"
#include"conio.h"
#include
voidB_yt_3(int[][2],intcolor,inttzb);
voidtulie(int,int,int);
voidxuehaopri(intcolor);
voidmain()
{intgdriver=DETECT,gmode;
intp[8][2]={{30,350},{90,110},{250,260},{390,90},{490,110},
{530,370},{600,230},{550,110}};
学习文档仅供参考
initgraph(&gdriver,&gmode,"D:tcbgi");
xuehaopri(14);
tulie(2,4,15);
B_yt_3(p,4,0);
getch();
clograph();
}
voidB_yt_3(intp[][2],intcolor,inttzb)
{
floatt=0;
intxt,yt,i,m;
tlinestyle(0,0,1);
tcolor(15);
delay(1000);
if(tzb==1)
for(i=0;i<7;i++)
line(p[i][0],p[i][1],p[i+1][0],p[i+1][1]);
tcolor(color);
for(m=0;m<5;m++)
for(t=0;t<=1.0;t+=0.01)
{
xt=1.0/6*((-p[m][0]+3*p[m+1][0]-3*p[m+2][0]+p[m+3][0])*t*t*t+
(3*p[m][0]-6*p[m+1][0]+3*p[m+2][0])*t*t+
(-3*p[m][0]+3*p[m+2][0])*t+(p[m][0]+4*p[m+1][0]+p[m+2][0]));
yt=1.0/6*((-p[m][1]+3*p[m+1][1]-3*p[m+2][1]+p[m+3][1])*t*t*t+
(3*p[m][1]-6*p[m+1][1]+3*p[m+2][1])*t*t+
(-3*p[m][1]+3*p[m+2][1])*t+(p[m][1]+4*p[m+1][1]+p[m+2][1]));
if(t==0)moveto(xt,yt);
lineto(xt,yt);
delay(15);
学习文档仅供参考
}
}
voidxuehaopri(intcolor)
{
tcolor(color);
ttextstyle(1,0,3);
ttextjustify(1,1);
outtextxy(getmaxx()/2,15,"MadeByNo.010XXX");
}
voidtulie(intcolor1,intcolor2,inttextcolor)
{
intx=getmaxx()/2,y=getmaxy()-20;
moveto(x-180,y);
tcolor(color1);
tlinestyle(0,0,3);
lineto(x-155,y);
tcolor(color2);
moveto(x,y);
lineto(x+25,y);
tcolor(textcolor);
ttextstyle(0,0,1);
outtextxy(x-80,y,"2ciB_yangtiao");
}
学习文档仅供参考
电脑图形学实验报告五
实验名称Bezier曲线和样条曲线的生成算法评分
实验日期年月日指导教师
专业班级学号
一、实验目的
二、实验要求
三、关键算法及实现原理
四、程序调试中的问题
五、程序运行结果或数据
六、实验收获及体会
七、参考源程序(可附页)
本文发布于:2022-12-30 00:18:09,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/56316.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |