《计算机图形学》答案第四章.docx
- 文档编号:11725761
- 上传时间:2023-03-31
- 格式:DOCX
- 页数:28
- 大小:41.62KB
《计算机图形学》答案第四章.docx
《《计算机图形学》答案第四章.docx》由会员分享,可在线阅读,更多相关《《计算机图形学》答案第四章.docx(28页珍藏版)》请在冰豆网上搜索。
《计算机图形学》答案第四章
第四章:
P215
1、将中点画线算法推广以便能画出任意斜率的直线
算法设计:
(1)输入直线的起点坐标P0(x0,y0)和终点坐标P1(x1,y1).
(2)定义直线当前点坐标x和y,定义中点偏差判别式d、直线斜率k、像素点颜色rgb
(3)x=x0,y=y0计算d=0.5-k,k=(y1-y0)/(x1-x0),rgb=RGB=(0,0,255).
(4)绘制点(x,y),判断d的符号,若d<0,则(x,y)更新为(x+1,y+1),d更新为d+1-k,否则(x,y)更新为(x+1,y),d更新为d-k.
(5)如果当前点x小于(x1,重复步骤(4),否则结束。
程序主要代码:
MidPointLine(x0,y0,x1,y1,color)
{
inta,b,delta1,delta2,d,x,y;
a=y0–y1;
b=x1–x0;
d=2*a–b;
delta1=2*a;
delta2=2*(a+b);
x=x0;
y=y0;
if(a
drawpixel(x,y,color);
else
drawpixel(y,x,color);
while(x>x1)
{
If(d<0)
{
x++;
y++;
d+=delta2;
}
Else
{
X++;
D+=delta1;
}
Putpixel(x,y,color);
}
Else
While(x { If(d<0) { x--; y++; d-=delta3; } Else { x--; d-=delta1; } Putpixel(x,y,color); } } 2、采用整数Bresenham算法,为一台计算机编制直线扫描转换程序。 从键盘敲入两端点坐标,就能在显示器屏幕上画出对应的直线。 VoidDrawLine(intcolor) { intx0,y0,x1,y1,color,I; scanf(“%d,%d,%d,%d”,&x0,&y0,&x1,&y1); dx=x1–x0; dy=y1–y0; e=-dx; x=x0; y=y0; for(i=0;i<=dx;i++) { putpixel(x,y,color); x=x+1; e=e+2*dy; if(e>=0) { y=y+1; e=e–2*dy; } } } 4、试编写按逆时针方向生成第二个8分圆的中点算法 算法设计: (1)输入圆的半径 (2)定义圆当前点坐标x和y、中点偏差判别式d、像素点颜色rgb (3)计算d=1.25-R,x=0,y=R,rgb=RGB=(0,0,255). (4)绘制点(x,y),及其在八分圆中的另外7个对称点‘ (5)判断d的符号,若d<0,则(x,y)更新为(x+1,y),d更新为d+2x+3,否则(x,y)更新为(x+1,y-1),d更新为d+2(x-y)+5. (6)当x小于等于y,重复步骤(4)和(5),否则结束。 MidpointCircle(r,color) intr,color; { floatx,y; floatd; x=0; y=r; d=1.25–r/1.414; drawpixel(x,y,color); while(x { if(d<0) { d+=2*x+3; x++; } else { d+=5+2*(x-y); x++; y--; } drawpixel(x,y,color); } } 5、假设圆的圆心不在原点,试编写算法对整个圆进行扫描转换 算法设计: (1)输入圆的半径r,圆心坐标为(xc,yc) (2)定义圆当前点坐标x和y、中点偏差判别式d、像素点颜色rgb (3)计算d=1.25-R,x=0,y=R,rgb=RGB=(0,0,255). (4)绘制点(x+xc,y+yc),及其在八分圆中的另外7个对称点‘ (5)判断d的符号,若d<0,则(x,y)更新为(x+1,y),d更新为d+2x+3,否则(x,y)更新为(x+1,y-1),d更新为d+2(x-y)+5. (6)当x小于等于y,重复步骤(4)和(5),否则结束。 (1)用bresenham画圆法,设圆心坐标为(xc,yc) bresenham_circle(r,color) intr,color; { intx,y,delta,delta1,delta2,direction; x=xc; y=yc+r; delta=2*(1-r); while(y>=0) { drawpixel(x,y,color); if(delta<0) { delta1=2*(delta+y-b)-1; if(delta1<=0) direction=1; else direction=2; } elseif(delta>0) { delta2=2*(delta-x+xc)-1; if(delta2<=0) direction=2; else direction=3; } else direction=2; switch(direction) { case1: x++; delta+=2*(x-xc)+1; break; case2: x++; y++; delta+=2*(x-a-y+yc+1); break; case3: y--; delta+=-2*(y-yc)+1; break; } } } (2)采用中点画圆算法 #include #include #include MidpointCircle(r,color) intr,color; { floatx,y; floatd; x=0; y=r; d=1.25–r/1.414; putpixel(xc+x,yc+y,color); while(x { if(d<0) { d+=2*x+3; x++; } else { d+=5+2*(x-y); x++; y--; } putpixel(xc+x,yc+y,color); } } putpixel(x,y,color); putpixel(xc+yc-y,yc+xc-x,color); putpixel(xc+yc-y,yc+xc-x,color); putpixel(x,yc+yc-y,color); putpixel(xc+xc-x,yc+yc-y,color); putpixel(xc-yc+y,yc-xc+x,color); putpixel(xc-yc+y,yc+xc-x,color); putpixel(xc+xc-x,y,color); } voidmain() { intgdriver=DETECT,gmode,xc,yc,r; initgraph(&gdriver,&gmode,“”); printf(“Pleaseenterthexc: ”); scanf(“%d”,&xc); printf(“Pleaseentertheyc: ”); scanf(“%d”,&yc); printf(“PleaseentertheR: ”); scanf(“%d”,&r); cleardevice(); MidpointCircle(xc,yc,r,RED); getch(); closegraph(); } 6、试编写可以对一段任意圆弧进行扫描转换的算法 将360度的区域分成8个部分 32 41 58 67 编写可以对一段任意圆弧进行扫描转换的算法的关键在于,对这段圆弧的起点和终点分别判定是否在同一区域 如果起点和终点在同一区域,调用中点画圆算法,但要根据实际情况对参数进行修正; 如果起点和终点不在同一区域,则要根据实际情况对圆弧段进行分割,分割的原则是将每一段的起点和终点放在同一区域,然后分别调用中点画圆算法画圆弧,同样在画的过程中,要根据实际情况对参数进行修正及算法进行修正; 设圆弧的起点为(x1,y1),终点为(x2,y2),半径为r 如图 A(x1,y1) D(x0-r,y0)C(x0,y0) B(x2,y2) 将整个圆弧分为两段,弧AC和弧CB,分别进行扫描转换,转换过程中利用中点画圆方法进行,代码如下: midpoint(x1,y1,x2,y2,r,color,k) { intx,y; floatd; x=x1; y=y1; d=(x1+1)^2+(y1-0.5)^2-r^2; putpixel(x,y,color); while(x<=x2) { if(d<0) { d+=2*x+3; x++; } else { d+=2*(x-y)+5; x++; y=y+k; } } putpixel(x,y,color); main() { scanf(“%d”,&n);//分割的圆弧数 for(i=1;i<=n;i++) { scanf(“%d,%d,%d,%d,%d”,&x1,&y1,&x2,&y2,,&k);//要求x1 midpoint(x1,y1,x2,y2,r,color,k); 7、设计一个多边形区域填充算法,使其边界像素具有一个值,而内部的像素具有另一个值。 算法设计: (1)使用画线语句绘制多边形 (2)计算窗口客户区的水平边界最大值MaxX和垂直边界最大值MaxY (3)调用系统调色板,设置颜色值FillColor为调色板上取得的颜色,CBackColor为白色。 (4)对于每一条边,y从ymin开始,执行下面的循环。 (5)x从扫描线和边的交点处开始到窗口客户区右边界,先获得(x,y)位置的像素颜色,如果是填充色,则置成背景色,否则所有填充色填充。 执行x=x+1/k,计算下一个x起点值。 (6)如果y=ymin,则扫描结束,否则y++,转(5)。 主要代码: intMaxX,MaxY; VoidGetMaxX()//求屏幕最大x值 { CRectrect; GetClientRect(rect); MaxX=rect.riht; } VoidGetMaxY()//求屏幕最大y值 { CRectrect; GetClientRect(rect); MaxX=rect.bottom; } VoidDraw()//填充多边形函数 { COLORREFCBackColor=RGB(255,255,255);//白色 CClientDCdc(this); intm,n,ymin,ymax; doublex,y,k; for(inti=0;i<=6;i++) { m=i,n=i+1; if(7==n)n=0; k=(double(Point[m].x-Point[n].x)/(Point[m].y-Point[n].y);//计算1/k; if((Point[m].y { ymin=Point[m].y; ymax=Point[n].y; x=Point[m].x;//得到x|ymin } else { ymin=Point[n].y; ymax=Point[m].y; x=Point[n].x; } For(y=ymin;y { For(intj=ROUND(x);j { If(dc.GetPixel(j,ROUND(y)==FillColor)//如果像素的颜色是填充色 { dc.SetPixel(j,ROUND(y),CBackColor);//改为背景色 } else { dc.SetPixel(j,ROUND(y),FillColor);//改为填充色 } } x+=k;//计算下一个x起点值 } } } DrawPolygon()//绘制多边形函数 { CClientDCdc(this); intm,n; for(intj=0;j<=6;j++) { M=j;n=j+1; If(7==n)n=0; dc.MoveTo(Point[m]); dc.LineTo(Point[n]); } } 10、试设计一个生成具有宽度的直线条的算法,使得在直线条连接处不出现图示的缺口 对于第一种方案: c d e abf 可以把整个线条分成两个部分, 对于左半部分: 先计算出线条的四个顶点,a,b,c,d 再用直线段把相邻角点连接起来, 最后调用多边形填充算法把所得的四边形进行填色 同样,对于右半部分,依法处理 对于第二种方案: c e df g abh 可以把整个线条分成三个部分, 对于左半部分: 先计算出线条的四个顶点,a,b,c,d 再用直线段把相邻角点连接起来, 最后调用多边形填充算法把所得的四边形进行填色 对于中间部分: 先计算出线条的四个顶点,c,d,e,f 再用半径为某个值如R圆弧分别把c,e和d,f连接起来, 最后调用区域填充算法把所得的圆环段c,e,d,f进行填色 同样,对于右半部分,依法处理 先计算出线条的四个顶点,e,f,g,h 再用直线段把相邻角点连接起来, 最后调用多边形填充算法把所得的四边形进行填色 12、为26个英文大写字母设计5X7的字符掩膜矩阵。 13、编写一程序实现线段裁剪的中点分割算法 算法设计: (1)输入直线段的两端点坐标: P0(x0,y0),P1(x1,y1)绘制坐标为(wxl,wyt),(wxr,wyb)的窗口 (2)P0点的编码为RC0,P1点的编码为RC1。 (3)若RC0|RC1=0,对直线段应“取”,转步骤(6);否则若RC0|RC1≠0,对直线段应“弃”,转步骤(6)。 (4)如果直线段有一个端点在窗口内,则计算该直线的中点坐标P[x=(x0+x1)/2,y=(y0+y1)/2],并计算其编码RC。 如果中点P和P0在规定的误差范围内(例如10-6)不重合,则判断中点是否也在窗口内,如果在,PP0“取”之,否则,PP0“弃”之。 将中点P赋给点P1,转步骤(6)。 (5)如果直线段的两个端点都不在窗口内,则必定与窗口相交,求该直线中点坐标P[x=(x0+x1)/2,y=(y0+y1)/2]和其编码RC。 当中点P在窗口外时,如果RC0&RC1=0,则PP1在窗口外,“弃”之;否则PP0在窗口外,“弃”之,直到中点P在窗口内。 对于中点在窗口内的直线段PP1和PP0,重复步骤(4)。 (6)输出裁减后的线段。 主要代码: VoidMidClip(doubleP0x,doubleP0y,doubleP1x,doubleP1y,BOOLflag) { Doublex,y; UnsignedintRCT0,RCT1; RCT0=EnCode(P0x,P0y); RCT1=EnCode(P1x,P1y); x=(P0x+P1x)/2; y=(P0y+P1y)/2;RCT=EnCode(x,y); while(abs(x-P0x)>1e-6||abs(y-P0y)>1e-6) { if(RCT==0)//中点也在窗口内,则P=P0 { P0x=x; P0y=y; RCT0=RCT; } else//否则舍弃P1点 { P1x=x; P1y=y; RCT1=RCT; } x=(P0x+P1x)/2; y=(P0y+P1y)/2;RCT=EnCode(x,y); } if(flag==true) { Pointx[1]=x; Pointy[1]=y; } else { Pointx[0]=x; Pointy[0]=y; } } 14编写一程序实现逐次多边形裁剪算法 算法设计: (1)输入第一个顶点坐标: F(x0,y0) 第二个顶点坐标: S(x1,y1) (2)当顶点输入完毕,转(7) (3)输入顶点P坐标: P(x2,y2) (4)SP与裁剪线相交吗? 是,求SP与裁剪线的交点I(x,y),并输出I坐标: I(x,y) (5)P位于可见一侧吗? 是,输出顶点P坐标: P(x2,y2) (6)将顶点P坐标: P(x2,y2)=》顶点S坐标: S(x1,y1),转 (2) (7)将顶点F坐标: F(x0,y0)=》顶点P坐标: S(x2,y2),形成闭合, (8)SP与裁剪线相交吗? 是,求SP与裁剪线的交点I(x,y),并输出I坐标: I(x,y) (9)P位于可见一侧吗? 是,输出顶点P坐标: P(x2,y2) (10)结束 程序代码: /*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; setcolor(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; elser->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; elser->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; elser->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; elser->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; elser->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; elser->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;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机图形学 计算机 图形学 答案 第四