计算机图形学教程课后习题答案_第1页
计算机图形学教程课后习题答案_第2页
计算机图形学教程课后习题答案_第3页
计算机图形学教程课后习题答案_第4页
计算机图形学教程课后习题答案_第5页
已阅读5页,还剩72页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第一章

1、试述计算机图形学研究的基本内容?

答:见课本P5-6页的1.1.4节。

2、计算机图形学、图形处理与模式识别本质区别是什么?请各举一例说明。

答:计算机图形学是研究根据给定的描述,用计算机生成相应的图形、图像,且所生成的图形、

图像可以显示屏幕上、硬拷贝输出或作为数据集存在计算机中的学科。计算机图形学研究的是从数

据描述到图形生成的过程。例如计算机动画制作。

图形处理是利用计算机对原来存在物体的映像进行分析处理,然后再现图像。例如工业中的射

线探伤。

模式识别是指计算机对图形信息进行识别和分析描述,是从图形(图像)到描述的表达过程。

例如邮件分捡设备扫描信件上手写的邮政编码,并将编码用图像复原成数字。

3、计算机图形学与CAD、CAM技术关系如何?

答:见课本P4-5页的1.1.3节。

4、举3个例子说明计算机图形学的应用。

答:①事务管理中的交互绘图

应用图形学最多的领域之一是绘制事务管理中的各种图形。通过从简明的形式呈现出数据的模

型和趋势以增加对复杂现象的理解,并促使决策的制定。

②地理信息系统

地理信息系统是建立在地理图形基础上的信息管理系统。利用计算机图形生成技术可以绘制地

理的、地质的以及其它自然现象的高精度勘探、测量图形。

③计算机动画

1

用图形学的方法产生动画片,其形象逼真、生动,轻而易举地解决了人工绘图时难以解决的问

题,大大提高了工作效率。

5、计算机绘图有哪些特点?

答:见课本P8页的1.3.1节。

6、计算机生成图形的方法有哪些?

答:计算机生成图形的方法有两种:矢量法和描点法。

①矢量法:在显示屏上先给定一系列坐标点,然后控制电子束在屏幕上按一定的顺序扫描,逐

个"点亮"临近两点间的短矢量,从而得到一条近似的曲线。尽管显示器产生的只是一些短直线的线

段,但当直线段很短时,连成的曲线看起来还是光滑的。

②描点法:把显示屏幕分成有限个可发亮的离散点,每个离散点叫做一个像素,屏幕上由像素

点组成的阵列称为光栅,曲线的绘制过程就是将该曲线在光栅上经过的那些像素点串接起来,使它

们发亮,所显示的每一曲线都是由一定大小的像素点组成的。当像素点具有多种颜色或多种灰度等

级时,就可以显示彩色图形或具有不同灰度的图形。

7、当前计算机图形学研究的课题有哪些?

答:见课本P10-11页的1.4节。

8、简述三维图形生成和输出的流水线?

答:见课本P13页1.5.6节。

9、向量图形和点阵图形之间的区别有哪些?

答:通过矢量法产生的图形称为矢量图形或者向量图形,用描点法产生的图形称为点阵图形。向量

图形区别点阵图形的特点在于描述图形几何形状的数学模型及依据此模型生成几何图形的计算机

命令。向量图形由各个基本图形构成,这就要求各个基本图形有各自独立的信息。如果用点阵图形

来表示一个向量图形,构成向量图形的某个基本图形(如直线段、圆弧等)的所有点应有一个信息。

因此,在描述一个基本图形时,同时要描述其相应的信息。向量图形最基本的优点是它本身是由精

2

确的数据给出,所以可以充分利用各种输出图形设备的分辨率尽可能精确地输出图形。也正因为如

此,向量图形的尺寸可以任意变化而不损失图形显示的质量。但是向量图形仅适合于描绘简单图形,

而点阵图形可以描绘绚烂多彩的复杂图形。

10、什么是虚拟现实技术和可视化技术?

答:虚拟现实技术:利用计算机生成一种模拟环境,通过多种传感器和设备使用户"投入"到该

环境中,实现用户和该环境直接进行交互的技术。例如模拟飞机驾驶舱。

可视化技术通过对空间数据场构造中间几何因素或用图形绘制技术在屏幕上产生二维图像。

例如分子模型构造。

第二章

1、计算机图形系统有什么特点?有哪些主要功能?

答:课本2.1.1

2、计算机图形系统有哪几种?各有什么特点?

答:一种分类方法:交互式图形系统允许操作者以某种方式(对话方式或命令方式)来控制和操

作图形生成过程,使得图形可以边生成、边显示、边修改,直至符合要求为止。而被动式绘图系统,

图形在生成过程中,操作者无法对图形进行实时操作和控制,不具备交互功能,只提供各种图形命

令或图形程序库,通过编程获得所需图形。

另一种分类方法:见课本2.1.3节,分为脱机绘图系统、联机绘图系统和交互式绘图系统。

3、阴极射线管由哪些部分组成?它们的功能分别是什么?

答:CRT由四部分组成:电子枪、聚焦系统、偏转系统和荧光屏,这四部分都在真空管内。电

子枪由灯丝、阴极和控制栅极组成。灯丝加热阴极,阴极表面向外发射自由电子,控制栅控制自由

电子是否向荧光屏发出,若允许电子通过,形成的电子流在到达屏幕的途中,被聚焦系统(电子透

3

镜)聚焦成很窄的电子束,由偏转系统产生电子束的偏转电场(或磁场),使电子束左右、上下偏

转,从而控制荧光屏上光点上下、左右运动,使得在指定时刻在屏幕指定位置上产生亮点。

4、光栅扫描显示器由哪些部分组成?它们的功能分别是什么?

答:见课本P21页图2.9所展示的组成框图,其后有各部分的介绍及功能。

5、对于分辨率为1024*1024的光栅系统,若每一像素用8位和12位二进制来表示存储信息,各

需多大光栅存储容量以及显存?每一屏幕最多能显示多少颜色?若R,G,B灰度都占8位,其显

示颜色的总数是多少?

解:

1)每一像素用8位二进制来表示存储信息,所需容量为1024*1024*1=22。(Byte)=1MB

彩色素:28=256(项)

2)若每一像素用12位二进制表示存储信息,所需容量为:1024*1024*1.5=1.5*22°

(Byte)=1.5MB(由于显示卡的显存是按2的指数次倍增长的,因此所需显存为2M)

彩色素:2'2=4096(项)

3)颜色总数:28*2‘*28=2"(种)

6、对于19英寸显示器,若X和Y两方向的分辨率相等,即1024*1024,那么每个像素点的直径

是多少?

19*2S410

解:--=0.33(mm)或..尸=0.013(英寸)

1024V21024V2

7、对于分辨率为1024x768的光栅系统,若调色板设置为真彩色32位,此时需要显示一个三维

图形,各需要多大光栅存储容量以及显存?

答:调色板为真彩色32位,即意味着像素值的位长为32

所需容量为1024*768*32/8*3=9MB因此所需要的显存为16M

8、GKS有哪三种坐标系?它们有什么不同?试写出它们之间对应关系?

4

答:GKS有3种不同的坐标系。第一种是供应用程序使用的实际世界坐标系统

(WorldCoordinateSystem,简称WC);第二种是GKS内部使用的规范设备坐标系

(NormalizedDeviceCoordinate,简称NDC),它的取值范围为[0,1],这是一种既与设备

无关也与应用无关的坐标系;第三种是各工作站物理设备使用的设备坐标系

(DeviceCoordinateSystem,简称DC).GKS只支持二维对象的图形处理,因此上述3个坐

标系都是二维坐标系。详见课本图3.28的描述。

9、GKS中输入设备有哪6种逻辑功能?请各举出对应的物理设备。

答:见课本2.4.5.节。

10、当前主流的图形软件有哪些?

答:见课本2.6.3节。

第三章

1、编写画一正方形程序,并在其中用不同的颜色画15个正方形,每一个都比前一个小。

#include“graphics.h"

#include“conio.h"

voidmain()

(

inti,color=0,ls=0;

intj=700;

intgdriver=VGA;

intgmode=VGAHI;

,/H3-1批改说明;

initgraph(&gdriver,&gmode/);

setbkcolor(15);•必须至少包含"graphics.h"

•initgraph(&gdriver,&gmode,n");

•必须包含15个正方形,一般用for循

环,也可能用到while等。

for(i=0;i<225;i=i+15,j=j-30)

setcolor(color);

bar(i,i,j,j);

color++;

ls++;

)

getch();

closegraph();

)

2、用不同的线形绘制题1中的图形

#include,,graphics.h,,

#include"conio.h"

voidmain()

(

inti,color=1,ls=0;

intj=700;

3-2批改说明;

intgdriver=VGA;

•注意查看3」部分内容

gmode=VGAHI;

initgraph(&gdriver,&gmode,'"');

setbkcolor(15);

for(i=0;i<=225;i=i+15,j=j-30)

6

setcolor(color);

〃setlinestyle(ls%4,0,1);或者

setlinestyle(4,ls,3);

rectangle(i,i,j,j);

setfillstyle(SOLID_FILL,color);

〃floodfill(getmaxx()/2,getmaxy()/2,color);此句会出现最后只用一种颜色填充

的情况

color++;

ls++;

)

getch();

closegraph();

)

3、画一五颜六色的图(此例为画一个五颜六色的圆)

#include"graphics.h"

#includeHconio.hM

voidmain()

(

intdriver=DETECT,mode=0;

inti,start,end;

,w

initgraph(&driver,&mode/);3-3批改说明;

start=0;•必须至少包含"graphies,h"

•initgraph(&gdriver,&gmode,

");

end=20;

for(i=0;i<18;i++)

(

setfillstyle(SOLID_FILL,i);

pieslice(300,200,start,end,100);

start+=20;

end+=20;

)

getch();

restorecrtmode();

)

4、编写一辆自行车在一公路上由右至左快速行驶的程序。

#include"stdlib.h"

#includengraphics.hn

#include"conio.hn

#include"stdio.h"

voidmain()

(

void*w;

intdriver=DETECT,mode=0/i,start/endj;

n

initgraph(&driver/&mode/");

cleardevice();

setbkcolor(15);

8

setcolor(CGA-LIGHTGREEN);

start=0;

end=180;

circle(387/290,37);

circle(525/290,37);

line(404,217,398,230);

line(436,217,429,230);

line(398,230,429,230);

line⑷3,230,387,290);

line(387,290,525,290);

line(408,243,484,243);

line(387,290,484,243);

line(484,243,525,290);

line(444,290,484,243);

line(444,290,446,279);

line(444,290,443,300);

line(438,277,444,278);

line(435,300,451,301);

line(484,243,487,233);

line(472,233,502,233);〃自行车基本轮廓的绘制

w=malloc(imagesize(350/200,562,327));

getimage(350,200,562,327,w);

9

for(i=350j=0;i>0;i—j—)

setfillstyle(EMPTY_FILL,O);

pieslice(387+j,290,start,end,37);

pieslice(525+j,290,start,end,37);

start+=40;

end+=40;

delay⑸;〃处于运动状态的自行车车轮的轴线的绘制

putimage(i-1,200/w/COPY_PUT);

line(2,327,562,327);

delay(10);〃自行车行驶动画的实现

)

for(i=0;i<10;i++)

(

pieslice(37,290,start,end,37);

pieslice(175,290,start,end,37);

start+=40;

end+=40;

}〃处于静止状态的自行车车轮的轴线的绘制

getch();

restorecrtmodeO;

closegraphQ;

)

10

5、试自行设计一个美术图案,并且用程序实现。

(略)

第四章

1.为什么说直线生成算法是二维图形生成技术的基础?

答无论什么复杂图形,它们都是由直线段和曲线段组成三维图形经投影后最终变成了二维图形),

而图形设备显示曲线段时,最终还是将曲线段转化成一系列直线段逼近表示的。因此,所有图形都

可以看成是由直线段组成的。可参考课本图4.10

2根据DDA画直线算法,遍一程序求(0,0)到(4,12)和(0,0,)到(12,4)的直线

#include"graphics.h"

#include,,math.h),

voidDDA_Line(intx1,inty1,intx2,inty2)

(

floatincrex,increy,x,y,length;

inti;

if(abs(x2-x1)>abs(y2-y1))

Iength=abs(x2-x1);

else

Iength=abs(y2-y1);

increx=(x2-x1)/length;

increy=(y2-y1)/length;

x=x1;

y=y1;

11

for(i=1;i<=length;i++)

putpixel(x,y,1);

x=x+increx;

y=y+increy;

)

)

voidmainO

(

intdriver=DETECT,mode=0;

initgraph(&driver,&mode,"");

intxl=O,y1=0,x2=4,y2=12;

intx3=12,y3=4;

DDA_Line(x1,y1,x2,y2);

DDA_Line(x1,y1,x3,y3);

getch();

)

3根据逐点比较法编一程序画一段圆弧,其圆心为(0,0),圆弧两点为A(5,0)、B(0,5)

方法1:顺4象限

#include"graphics.h"

#ir)clude"stdio.h"

#include"conio.h"

voidZDBJ_ARC(floatxO,floatyO,floatx1,floaty1,floatx2,floaty2);

12

voidmainO

intgdriver=CGA,mode=CGACO;

initgraph(&gdriver,&mode,"");

ZDBJ_ARC(O,0,25,0,0,25);

getch();

closegraph();

)

voidZDBJ_ARC(floatxO,floatyO,floatx1,floaty1,floatx2,floaty2)

(

floatf=0.0,F;

floatdx=1,dy=1;

while(abs(x1-x2)>1)

(

if(f>=0)

(

x1=x1-dx;

yi=yi;

putpixel(x1,y1,1);

f=f-2*dx*(x1-xO)+dx*dx;

)

else

13

x1=x1;

y1=y1+dy;

putpixel(x1,y1,1);

f=f+2*dy*(y1-yO)+dy*dy;

)

)

)

方法2:逆4象限

#include"graphics.h"

#include"stdlib.h"

#include"conio.h"

voidZDBJ_ARC(floatxO,floatyO,floatx1,floaty1,floatx2,floaty2);

voidmainO

(

intgdriver=CGA,mode=CGACO;

initgraph(&gdriver,&mode,"");

ZDBJ_ARC(0,0,0,25,25,0);

getch();

closegraph();

)

voidZDBJ_ARC(floatxO,floatyO,floatx1,floaty1,floatx2,floaty2)

14

floatf=0.0,F;

floatdx=1,dy=1;

while(abs(y1-y2)>1)

(

if(f>0)

(

x1=x1;

y1=y1-dy;

putpixel(x1,y1,1);

f=f-2*dy*abs(y1-yO)+dy*dy;

)

else

(

x1=x1+dx;

yi=yi;

putpixel(x1,y1,1);

f=f+2*dx*abs(x1-xO)+dx*dx;

)

)

)

方法3:顺1象限

#include"graphics.h7/省略了图形初始化的步骤

15

#include,,conio.h,,

#include"math.h"

voidmain()

(

intxl=5,y1=0,x2=0,y2=5;

intxO=O,yO=O;

intR=sqrt((x2-xO)*(x2-xO)+(y2-yO)*(y2-yO));

intdx=abs(x2-x1);

intdy=abs(y2-y1);

intn=dx+dy;

putpixel(x2,y2,1);

intf;

intx=x2,y=y2;

for(inti=0;i<n;i++)

(

f=(x-xO)*(x-xO)+(y-yO)*(y-yO)-R*R;

if(f>=0)

putpixel(x,y-,1);

else

putpixel(x++,y,1);

)

getch();

closegraph();

16

}〃另一种做法是采用课本P97页表4.2的公式

4.编一程序用角度DDA法画一圆〃以圆点为圆心,半径为20的圆

#include"graphics.h"〃省略了图形初始化的步骤

#includeHconio.hM

#include"math.h"

voidmain()

(

intxO=0,y0=0,R=20;

intx1,y1,xi,yi;

intN=R*8;

floata=2*3.14/N;

x1=20,y1=0;

for(inti=1;i<=N;i++)

(

xi=xO+R*cos(i*a)

yi=yO+R*sin(i*a);

Iine(x1,y1,xi,yi);

x1=xi;

yi=yi;

)

getch();

closegraph();

17

)

5.如果线段端点坐标值不是整数,采用DDA算法产生的直线和将端点坐标值先取整后再用

Bressenham算法产生的直线是否完全相同?为什么?能否扩充整数Bressenham算法使之能够处理

当线段端点坐标值不是整数的情况。

答:不相同。因为DDA算法总是选择或者Ay中的较大者作为步进的方向,不失一般性,假

设选择x方向,则x方向每前进一个像素点,y方向前进的像素点个数应该在[0,1]区间,但是由于

采用了(向上或者向下或者四舍五入)取整运算,必然会导致某些像素点偏在了真实直线的一侧。而

Bressenham算法每一步都会根据实际直线与网格的距离来决定下一个像素点的选择,因此所选

像素点更加贴近于真实的直线。

可以扩充整数Bressenham算法使之能够处理当线段端点坐标值不是整数的情况。

6.若采用Bresenham算法实现画圆,写出算法实现的具体流程(包括判别公式推导等等)。

答:给定圆心在原点,半径为R的圆,其方程为x2+y2=R2,构造函数F(x,y)=x2+y2-R2,对于圆

上的点,有F(x,y)=0;对于圆外的点,F(x,y)>0;而对于圆内的点,F(x,y)<0o

此处仅考虑如图所示的第一象限内XGhR/拉」的1/8圆弧,此时中点Bresenham画圆算法

要从(0尺)到(R/VIR/点)顺时针地确定最佳逼近于该圆弧的像素序列。

构造判别式d=F(XM,yM)=F(Xi+1,yi-0.5)=(Xi+1)2+(yi-0.5)2-R2

⑴当di<0,取Pu(xi+1,yi),计算下一步的的判别式

di+i=F(Xu,yu)=F(Xi+2,yi-0.5)=(Xi+2)2+(yi-0.5)2-R2=di+2xi+3

所以沿正右方向,d的增量为24+3。

18

(2)当di>0,取Pd(Xi+1,yi+1),计算下一步的的判别式

di+i=F(Xd,yd)=F(Xi+2,yi-1.5)=(Xi+2)2+(yi-1.5)2-R2=di+2(Xi-yi)+5

所以沿右下方向,d的增量为2(价0+5。

显然,所绘制圆弧段的第一个像素为Po(O,R),因此判别式do的初始值为1.25-R,可以令

d'=d-0.25来摆脱小数运算,则判别式di<0对应于di<-0.25,由于d始终是整数,di<-0.25等

价于

di<0o

7.已知4个型值点(1.0,2.0),(2.5,3.5),(4.0,4.5),(5.0,4.0),求各段三次样条

曲线。Si(X)(i=1,2,3),设边界条件为抛物线端

解:ml=x2-x1=1.5,m2=x3-x2=1.5,m3=x4-x37=d;Q

A2=m2/(m2+m1)=0.5;f1n°"

u2=m1/(m1+m2)=0.5;

A3=m3/(m2+m3)=0.4;

u3=m2/(m2+m3)=0.6;

R2=3*[u2*(y3-y2)/m2+A2*(y2-y1)/m1]=2.5;

R3=3*[u3*(y4-y3)/m3+A3*(y3-y2)/m2]=-0.1;

于是有

0.5b1+2b2+0.5b3=2.5...........(1)

0.4b2+2b3+0.6b4=-0.1...........(2)

又边界抛物线端

b1+b2=2.............................(3)

b3+b4=-1............................(4)

由⑴,(2),⑶,⑷得

19

b1=39/38,b2=37/38,b3=3/38,b4=-41/38

从而

c1=-1/57;

d1=0;

c2=-1/57;

d2=-64/513;

c3=-11/19;

d3=0;

故可得

s1(x)=2+39/38(x-1)-1/57(x-1)2xe[1,0,2.5]

s2(x)=3.5+37/38(x-2.5)-1/57(x-2.5)2-64/513(x-2.5)3xe[2.5,4.0]

s3(x)=4.5+3/38(x-4)-11/19(x-4)2xe[4.0,5,0]

8.已知4个型值点坐标值P0(5,5)、P1(10,15),P2(15,10)、P3(10,5),绘—

三次贝塞尔曲线。

解:

用矩阵表示为

p(t)=[t3t2t1]P[p0p1p2p3]T

P=p3-31、

3-633

-3300J

1000

p(0)=[5,5]

p(0.15)=[7.215,8.536]

20

p(0.35)=[9.83,10.64]

p(0.5)=[11.25,10.625]

p(0.65)=[12.015,9.615]

p(0.85)=[11.606,7.198]

p(1)=[10,5]

将上面各点相连可以画出三次贝塞尔曲线。

9.编写一个绘制Bezier曲线的程序。

该程序根据以下数据点[x,y]:

[50,100][80,230][100,270][140,160][180,50][240,65][270,120][330,230][380,230][430,150]

计算出结果,并实现三段首尾相接的三次贝塞尔曲线在屏幕上显示的功能,采用了C++语言实现;

#include"graphics.h"

#include"conio.h"

#include"stdio.h"

typedefstruct

(

doublex,y;

}DPOINT;〃定义结构体

dassBezier〃定义Bezier类

(

private:

DPOINT*bP;

intm_maxlndex;

21

voiddrawFrameQ;

voiddrawCurveO;

voiddrawCurve(intpO,intp1Jntp2Jntp3);

public:

Bezier(DPOINT*p,intlen);〃定义构造函数

voiddraw();

);

Bezier::Bezier(DPOINT*p,intlen)//构造函数的实现

(

this->bP=p;

m_maxlndex=len-1;

)

voidBezier::draw()〃通过公有函数调用私有函数

(

drawFrameQ;

drawCurve();

)

voidBezier::drawFrame()〃其功能是绘制出多边形和各个端点

(

setcolor(12);

for(inti=0;i<m_maxlndex;i++)

(

line(bP[i].x,bP[i].y,bP[i+1].x,bP[i+1].y);〃绘制多边形

22

circle(bP[i].x,bP[i].y,5);〃绘制各个端点

)

circle(bP[m_maxIndex].x,bP[m_maxIndex].y,5);

)

voidBezier::drawCurve()〃实现多段Bezier曲线绘制的功能

(

for(inti=0;i<=m_maxIndex-3;i+=3)

(

drawCurve(i,i+1,i+2,i+3);

)

)

voidBezier::drawCurve(intpO,intp1,intp2,intp3)//实现绘制某一段Bezier曲线的功能

(

doubletmpx=0.0;

doubletmpy=0.0;

doublet=0.0;

for(;t<=1.0;t+=0.001)

(

tmpx=(-bP[p0].x+3*bP[p1].x-3*bP[p2].x+bP[p3].x)*t*t*t+(3*bP[p0].x-6*bP[p1].x+3*bP[p2].x)*t*t+(-3*b

P[p0].x+3*bP[p1].x)*t+bP[p0].x;

tmpy=(-bP[p0].y+3*bP[p1].y-3*bP[p2].y+bP[p3].y)*t*t*t+(3*bP[p0].y-6*bP[p1].y+3*bP[p2].y)*t*t+(-3*b

P[p0].y+3*bP[p1].y)*t+bP[p0].y;

23

putpixel(tmpx,tmpy,3);

)

)

voidmain()〃主函数的实现

(

intgraphdriver=DETECT,graphmode;

initgraph(&graphdriver,&graphmode,"E:\\tc3\\bgi");

setbkcolor(15);

DPOINT*p;

p=newDPOINT[10];

p[0].x=50.0;

p[0].y=100.0;

p[1].x=80.0;

p[1].y=230.0;

p[2].x=100.0;

p[2].y=270.0;

p[3].x=140.0;

p[3].y=160.0;

p[4].x=180.0;

p[4].y=50.0;

p[5].x=240.0;

p[5].y=65.0;

p[6].x=270.0;

24

p[6].y=120.0;

p[7].x=330.0;

p[7].y=230.0;

p[8].x=380.0;

p[8].y=230.0;

p[9].x=430.0;

p[9].y=150.0;

BezierbzrCpJO);

bzr.drawQ;

deletep;

getch();

closegraphQ;

)

10.编写一个绘制B样条曲线的程序。

该程序根据以下数据点[x,y]:P0[50,130]P1[120,40]P2[100,270]和P3[140,160]计算出结果,

并实现两段首尾相接的两次B样条曲线在屏幕上显示的功能,采用了C++语言实现;

将已知点代入式(4-19)可得两段两次B样条曲线方程:

1-2150130

凡(心⑹1]-22012040

2110

100270

=[-45160]?+[70-90]t+[8585]

1-2112040

丹。=_1[代力]-220100270

2110

140160

=[30-170]^+[-20230"+[110155]

25

#includengraphics.hn

#include"conio.hn

#indudenstdio.hn

typedefstruct

(

doublex,y;

}DPOINT;〃定义结构体

dassB_Spline〃定义B样条曲线类

(

private:

DPOINT*bP;

intm_maxlndex;〃有多少个型值点

voiddrawFrame();

voiddrawCurveO;

voiddrawCurve(intpO,intp1,intp2);

public:

B_Spline(DPOINT*p,intlen);〃定义构造函数

voiddraw();

);

B_Spline::B_Spline(DPOINT*p,intlen)〃构造函数的实现

(

this->bP=p;

m_maxlndex=len;

26

)

voidB_Spline::draw()〃通过公有函数调用私有函数

(

drawFrameQ;

drawCurve();

)

voidB_Spline::drawFrame()〃其功能是绘制出多边形和各个端点

(

setcolor(12);

for(inti=0;i<m_maxlndex-1;i++)

(

line(bP[i].x,bP[i].y,bP[i+1].x,bP[i+1].y);〃绘制多边形

circle(bP[i].x,bP[i].y,5);〃绘制多边形各个端点

)

circle(bP[m_maxIndex-1].x,bP[m_maxIndex-1].y,5);

)

voidB_Spline::drawCurve()〃实现多段B样条曲线绘制的功能

(

for(inti=0;i<m_maxlndex-2;i++)

(

drawCurve(i,i+1,i+2);

)

27

)

voidB_Spline::drawCurve(impO,intp1,intp2)〃实现绘制某一E殳Bezier曲线的功能

(

doubletmpx=0.0;

doubletmpy=0.0;

doublet=0.0;

for(;t<=1.0;t+=0.001)

(

tmpx=(O.5*bP[pO].x-bP[p1].x+O.5*bP[p2].x)*t*t-t-(-bP[pO].x+bP[p1].x)*t+O.5*bP[pO].x+O.5*bP[p1].x;

tmpy=(0.5*bP[p0].y-bP[p1].y+0.5*bP[p2].y)*t*t+(-bP[p0].y+bP[p1].y)*t+0.5*bP[p0].y+0.5*bP[p1].y;

putpixel(tmpx,tmpy,3);

)

)

voidmain()〃主函数的实现

(

intgraphdriver=DETECT,graphmode;

initgraph(&graphdriver,&graphmode「);〃图形初始化

setbkcolor(15);

DPOINT*p;

p=newDPOINT[4];

p[0].x=50.0;

p[0].y=130.0;

28

p[1].x=120.0;

p[1].y=40.0;

p[2].x=190.0;

p[2].y=130.0;

p[3].x=260.0;

p[3].y=40.0;

B_Splineb_sp(pz4);

b_sp.draw();

deletep;

getch();

closegraphO;

)

11.简述NURBS曲线产生的背景和特点?

答:NURBS曲线具有局部可调性、凸包性、几何和透视投影变换不变性等等,它采用有理参

数多项式可以精确表示圆锥曲线、二次曲面等,对于几何造型算法提供了思路。

124各下列数据

X2610121416

Y3811131517

按最小二乘法曲线拟合,分别求一次和二次多项式曲线,拟合以上数据并画图表示。

解:如下表所示:

i

1236412816

29

26848362882161296

310111101001100100010000

412131561441872172820736

514152101962940274438416

616172722564352409665536

6067802736105649792136000

一次多项式的情形:

+60a,=67«0=1.46081

oO«0+736a1=802o,=0.97061

所求多项式为y=f(x)=1.4608+0.9706x

二次多项式的情形:

国)+60q+736a2=67%)=1.0793(

SOa0+736a,+9792a2=802at=1.(^21<

736a0+9792a,+136000a2=10564%=-0.0&6796

所求多项式为y=f(x)=1.0793+1.0921x-0.006796x2

13.设五边形的五个顶点坐标为(10,10),(15,5),(12,5),(8,2)和(4,5),利用多边形区域填充算法,

编一程序生成一个实心图。

解:假设以上五个顶点依次对应编号A-B-C-D-E,首先计算得到ET表:

30

6-10

匚,

1公/匚-1-11

4

3

n匚n

CQ//CQA/□

0用于存放AET活动边表

该多边形的AET指针的内容为:

1AET为空

31

4

具体编程实现如下:

第1步:(1)根据输入的五个顶点坐标找到V值最小的点(例如点D,此时y=2),并找到与D有边

关系的两个顶点(此时为E和C),在y=2处建立ET边表记录(ymax、xi和m值均可通过顶点坐标

间的计算得到,例如DE边的建立,特别注意:当D点和E点v坐标值相同时,也即是DE与x

轴平行,该边不能计入ET边表),之后标记D点被访问过;(2)排除访问过的点以及和该点相关联

的边,重复(1)直至将ET表建立完善。

[注]边关系的建立可通过邻接矩阵的数据结构实现,权值可以为该矩阵行编号对应点的y坐标值,

ET边表采用邻接表的数据结构

第2步:根据ET表构建AET表,并逐行完成多边形填充,具体的C++代码如下:

32

(1)建立头文件base_class.h,主要是边表结点结构体和ET边表类的实现

enumResultCode{Success,Failure};

template<classT>

structEnode

(

Enode(){next=NULL;}

Enode(Tpymax,floatpxi,floatpm,Enode*pnext)

(

ymax=pymax;xi=pxi;

m=pm;next=pnext;

)

Tymax,xi;//ymax表示最大的y值,xi表示最底端点的x坐标值

floatm;//m表示斜率的倒数

Enode*next;

};〃定义了ET表和AET表中结点的结构体

template<classT>

classET

(

public:

ET(intmSize);

~ET();

ResultCodeInsert(intu,Tymax,floatxi,floatm);

33

intn;〃覆盖该多边形的扫描线的总数,从0开始计数

Enode<T>**a;

};〃定义了边表类

template<classT>

ET<T>::ET(intmSize)

(

n=mSize;

a=newEnode<T>*[n];

for(inti=0;i<n;i++)a[i]=0;

}〃ET边表的初始化

template<classT>

ET<T>::~ET()

(

Enode<T>*p,*q;

deletea[O];

for(inti=1;i<n;i++)

(

p=a[i];q=p;

while(p)

(

p=p->next;

deleteq;

q=p;

34

)

)

delete[]a;

}〃析构函数负责回收内存空间

template<classT>

ResultCodeET<T>::Insert(intu,Tymax,floatxi,floatm)

(

if(u<0||u>n-1)returnFailure;

Enode<T>*p=newEnode<T>(ymax,xi,m,a[u]);

a[u]=p;

returnSuccess;

}〃依次插入结点构建出边表,其中a[1]到a[10]用于构建ET边表

〃a[0]用于构建活动AET边表

(2)填充函数po_fill的实现和主函数的实现

#include"base_class.h"

#include"graphics.h"

#include<iostream.h>

voidpo_fill(ET<int>&etp,intep,intcolor)//多边形填充函数的实现

(

inti=1;〃i作为控制变量标识扫描线

while(i<ep-1)

35

if(etp.a[i]!=NULL)

Enode<int>*p,*r;

p=etp.a[i];

r=etp.a[O];

while(p)

(

Enode<int>*q=newEnode<int>(p->ymax,p->xi,p->m,NULL);

if(!etp.a[O]){etp.a[O]=q;r=q;}

else

(

if(r->xi==q->xi){q->next=r->next;r->next=q;r=q;}

if(r->xi>q->xi){etp.a[O]=q;q->next=r;}

else{

while(q->xi>r->xi&&r->next)

r=r->next;

if(r->next){q->next=r->next;r->next=q;}

else{r->next=q;q->next=NULL;}

)

)

p=p->next;

)

}〃按照xi值的大小将当前ET表中的记录放置到AET表中

36

Enode<int>*f,*g;

if(etp.a[0])

f=etp.a[0];

while(f->next)

(

g=f;

f=f->next;

for(intj=g->xi;j<=g->next->xi;j++)

putpixel(j,i,color);

}〃把一对相邻结点的xi区间范围进行填充

)

if(etp.a[O]!=NULL)

Enode<int>*w;

ints=1;

while(s)

(

Enode<int>*z=NULL;

w=etp.a[0];

s=0;

while(w&&w->ymax!=i)

37

z=w;w=w->next;

)

if(!w)break;

if(z)z->next=w->next;

elseetp.a[O]=w->next;

deletew;

s=1;

}〃删去AET表中i值已经等于ymax的结点记录

if(etp.a[O])

(

Enode<int>*u,*v;

u=etp.a[O];

while(u)

(

v=u;

u=u->next;

v->xi=v->xi+v->m;

)

}〃用xi+m来替代原有的xi

)

i++;〃进入下一条扫描线

)

38

)

voidmain()〃主函数的实现

(

intgdriver,gmode;

gdriver=DETECT;

gmode=VGAHI;

initgraph(&gdriver,&gmode,"");//图形系统初始化

inte=11;

intcolor=5;//color用于标识填充颜色

ET<int>et(e);

et.Insert(2,5,8,4/3);

et.Insert(2,5,8,-4/3);

et.Insert(5,10,15,-1);

et.Insert(5,10,4,6/5);//根据初始数据建立边表

po_fill(et,e,color);〃调用填充函数

getch();

closegraph();

)

[注]第2步的实现存在两个问题:(1)没有实现世界坐标系统(第1象限)到设备坐标系统的转换,所

以显示出来的图形是以上所画图形的倒置,解决方法就是从世界坐标系统的最高y值开始扫描;(2)

由于m的取值为分数(浮点型),这就导致像素点坐标值出现浮点型,这样经过取整运算,计算出

39

来的像素点坐标值将可能与多边形填充点真实值之间存在偏差,导致所绘制的图形不完全与实际吻

合。

14.已知多边形各顶点坐标为(2,2)(2,4)(8,6)(12,2)(8,1)(6,2)及(2,2),在用多边形区域填充时,请写

出ET及全部AET内容。

解:如图所示:

则该多边形的ET表为:

6

5

ETDD2

C.D

4

3

6D7

An

2

cn6

oOA

该多边形的AET指针的内容为:(每条扫描线均有3行指针链,第1行表示将ET表加入AET中,

第2行表示从AET表中删去yi=ymax,第3行表示Xi=Xi+1/m后,学生只要写出第2行即可)

、DuDI

OQA

40

oCo—

-cmXI——cacXI———34Z

on—con

cav,Qca(Q3v

onc3n

―cm<a___tac,a—3a/

G

uC□n—

cav-------CQCJ3——□V

Uc□—

mbricacq——□V

Pcczr—

,C1cac43————3-A/

pccnucB___1LI

cxu<□1-catq------caq——d_J

P

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论