计算机图形学课后题答案(第二版)--许长青、许志闻.pdf

上传人:b****2 文档编号:3217518 上传时间:2022-11-20 格式:PDF 页数:21 大小:260.68KB
下载 相关 举报
计算机图形学课后题答案(第二版)--许长青、许志闻.pdf_第1页
第1页 / 共21页
计算机图形学课后题答案(第二版)--许长青、许志闻.pdf_第2页
第2页 / 共21页
计算机图形学课后题答案(第二版)--许长青、许志闻.pdf_第3页
第3页 / 共21页
计算机图形学课后题答案(第二版)--许长青、许志闻.pdf_第4页
第4页 / 共21页
计算机图形学课后题答案(第二版)--许长青、许志闻.pdf_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

计算机图形学课后题答案(第二版)--许长青、许志闻.pdf

《计算机图形学课后题答案(第二版)--许长青、许志闻.pdf》由会员分享,可在线阅读,更多相关《计算机图形学课后题答案(第二版)--许长青、许志闻.pdf(21页珍藏版)》请在冰豆网上搜索。

计算机图形学课后题答案(第二版)--许长青、许志闻.pdf

习题习题4444.在本章第一节说明Bresenham算法如何选择下一个像素点位置的图2-3中,其实是假定了在当前选择的点是(x,y)时,真正直线与横坐标为x+1的直线的交点是在y和y+1之间。

如果不是这样,而是下面两种情况:

(1)在y到y-1之间。

例如从(0,0)到(7,2)的直线,在点(2,1)处向后。

(2)在y+1到y+2之间。

例如从(0,0)到(7,5)的直线,在点(2,1)处向后。

试说明为什么对所列两种情况算法仍能正确地工作。

解答:

解答:

在给出两种情况下,Bresenham算法仍然能够正确工作的原因是判别式d保证了在这两种总情况下,仍然能正确的取到最接近真正直线的像素点。

在Bresenham算法中,按照判别式d的正负来决定选择哪一点作为下一个像素点,判别式d如下计算:

d=d1d2。

其中d1=ypy,d2=y+1yp,y是当前选中点(x,y)的纵坐标,yp是真正直线与横坐标为x+1的直线的交点的纵坐标。

当d0时,取上点,即(x+1,y+1)作为下一个像素点,当d0时,取下点,即(x+1,y)作为下一个像素点。

这里还要说明一下,因为此处是按照书上给出的Bresenham算法来进行像素选择的,所以实际上有一个先决条件,即直线的斜率处于0和1之间。

只要保证斜率满足条件,在当前选择的点是(x,y)时,真正直线与横坐标为x+1的直线的交点即使不在y和y+1之间,书上所给的Bresenham都可以正确工作。

题目所给两种情况中的直线斜率都满足算法的先决条件。

在第

(1)种情况下,如下图所示:

当前选择点为(x,y),下一点实际为P点,该点处于(x+1,y-1)和(x+1,y)两点之间,实际应取(x+1,y)点作为下一个像素点。

现在来看一下为什么一定会取(x+1,y)点作为下一个像素点,而不是取(x+1,y-1)点作为下一个像素点。

设Q点为选择(x,y)点作为显示像素点时实际的直线上的点,根据Bresenham算法的特点Q点的纵坐标yq一定满足y-0,5yqy+0.5,否则不会选择(x,y)点作为显示像素点,因为P点的纵坐标处于y和y-1之间,所以y-0.5yqy,否则该直线斜率将不满足条件(直线斜率将小于0)。

当y-0,5yqy时,则一定有y-0,5ypy,因为如果ypy-0.5,则P点的纵坐标会比Q点纵坐标更小,这时直线的斜率就不满足先决条件了(直线斜率将小于0)。

所以因为直线斜率先决条件的限制,当真正直线与横坐标为x+1的直线的交点是在y和y-1之间时,该实际交点一定更靠近(x+1,y)点,所以一定会取(x+1,y)点作为下一个像素点。

再来看一下按照Bresenham算法计算会取哪一点。

从图可知,因为P点纵坐标yp在y-1和y之间,所以有ypy,ypy+1,所以有d1=yp-y0,由此可得d=d1-d2y+1,而如果yq1,所以直线斜率大于1)。

当yyqy+0.5时,则一定有y+1ypy+1+0.5,因为如果ypy+1+0.5,同时又有yqy+0.5,则yp-yq1,这时直线的斜率大于1,不满足先决条件。

所以因为直线斜率先决条件的限制,当真正直线与横坐标为x+1的直线的交点是在y+1和y+2之间时,该实际交点一定更靠近(x+1,y+1)点,所以一定会取(x+1,y+1)点作为下一个像素点。

再来看一下按照Bresenham算法计算会取哪一点。

从图可知,因为P点纵坐标yp在y+1和y+2之间,所以有ypy,ypy+1,所以有d1=yp-y0,d2=y+1-yp0,所以要取上点(x+1,y+1)作为下一个像素点,跟实际应取的点是一致的,所以在这种情况下Bresenham算法仍然可以正确工作。

综上所述,虽然书中所说算法在当前选择的点是(x,y)时,假定了真正直线与横坐标为x+1的直线的交点是在y和y+1之间,但只要要绘制的直线斜率满足处于0与1之间的先决条件,那么即使真正直线与横坐标为x+1的直线的交点不是在y和y+1之间,书上所介绍的Bresenham算法仍然可以正确工作。

习题习题6666.推广本章第二节给出的Bresenham画圆算法使能够画出一个内部填充的实心圆。

解答:

解答:

因为Bresenham画圆算法在画圆的时候通过绘制对称点来完成整个圆周的绘制,所以只需绘制对称点之间连线上的象素点即可完成对圆形内部的填充。

推广算法的实现代码如下:

/参数:

(x0,y0)为圆心,R为半径,edgeColor为圆形边界颜色,inColor为圆形内部填充颜色voidCDraw:

BresenhamFillCircle(CDC*pDC,intx0,inty0,intR,COLORREFedgeColor,COLORREFinColor)intx,y,p;inti;x=0;y=R;p=3-(R1);for(;x=y;x+)for(i=-y+y0;iSetPixel(-x+x0,i,inColor);pDC-SetPixel(x+x0,i,inColor);for(i=-y+x0;iSetPixel(i,x+y0,inColor);pDC-SetPixel(i,-x+y0,inColor);/绘制圆弧上对称的八个像素点pDC-SetPixel(x+x0,y+y0,edgeColor);pDC-SetPixel(-x+x0,y+y0,edgeColor);pDC-SetPixel(x+x0,-y+y0,edgeColor);pDC-SetPixel(-x+x0,-y+y0,edgeColor);pDC-SetPixel(y+x0,x+y0,edgeColor);pDC-SetPixel(-y+x0,x+y0,edgeColor);pDC-SetPixel(y+x0,-x+y0,edgeColor);pDC-SetPixel(-y+x0,-x+y0,edgeColor);if(p0)p+=(x2)+6);elsep+=(x-y)2)+10);y-;习题习题8888.本章第三节叙述了使用活跃边表的多边形扫描转换算法中ET表的填写方法。

试写一个算法,输入多边形顶点坐标的逆时针序列,输出正确填写的ET表。

解答:

解答:

下面直接给出获得ET表的实现代码,为了构造书中所给样式的ET表,需要定义如下两个结构:

structEdgeNode/边节点intymax;/最大y值,吊桶数据doublexmin;/小y值端点的x值,吊桶数据doublefm;/斜率倒数,吊桶数据EdgeNode*next;/连接下一个边;structHeadNode/头节点intymin;/最小y值,ET表中登记项的y值EdgeNode*link;/连接边节点HeadNode*next;/连接下一个头节点;下面的实现代码用户获得构造完成的ET的头节点的头指针。

其中参数points存放多边形的顶点的逆时针序列。

HeadNode*CTestAView:

GetET(CArray*points)HeadNode*pHead=NULL;intymin;/记录正在处理的当前边的最小y值intnymin,nymax;/记录与正在处理的当前边连接的下一边的最小y值和最大y值/循环点列表构造最初的边链表for(inti=0;iGetSize();i+)/获得当前点和下一点,构成一条边CPointpoint1=(CPoint)points-GetAt(i);CPointpoint2;/如果当前点已经是最后一个点,则和第一点构成一条边if(i=points-GetSize()-1)point2=(CPoint)points-GetAt(0);elsepoint2=(CPoint)points-GetAt(i+1);/边平行于x轴,舍弃if(point1.y=point2.y)continue;/构造边结构EdgeNode*edge=newEdgeNode();edge-next=NULL;/计算斜率倒数edge-fm=(double)(point2.x-point1.x)/(point2.y-point1.y);/设置ymin,ymax和xminif(point1.ypoint2.y)edge-ymax=point1.y;ymin=point2.y;edge-xmin=point2.x;elseedge-ymax=point2.y;ymin=point1.y;edge-xmin=point1.x;CPointpoint3;/获得比较局部极大极小的第三点,该点和第二点够成一条边/如果前两点已经取到顶点序列尾部,则顺序从头取点作为第三点intj=i+2;doif(jGetSize()point3=(CPoint)points-GetAt(j);elsepoint3=(CPoint)points-GetAt(j-points-GetSize();j+;while(point2.y=point3.y);if(point2.ypoint3.y)/计算point2和point3点对应的ymin和ymaxnymax=point2.y;nymin=point3.y;elsenymax=point3.y;nymin=point2.y;/下面判断局部极大极小并缩短相应的边/如果连续的两条边的ymin值和ymax值都不同/表示连接两边的节点不为局部极大或极小if(ymin!

=nymin&edge-ymax!

=nymax)/缩短当前边/如果当前边的ymax值较大,则缩短当前边的ymin值if(edge-ymaxnymax)ymin+;edge-xmin+=edge-fm;else/否则,缩短当前边的ymax值edge-ymax-;/以下处理将当前边加入ET表if(pHead=NULL)/当前没有头节点pHead=newHeadNode();pHead-ymin=ymin;pHead-link=edge;pHead-next=NULL;elseAddEdge(pHead,ymin,edge);/返回获得的ET表头指针returnpHead;在上面的实现代码中用到了一个添加边函数,该函数作用是将处理完成的一条边加入到当前已有的ET表中,该函数的实现代码如下:

voidCTestAView:

AddEdge(HeadNode*head,intymin,EdgeNode*edge)HeadNode*temphead;while(head!

=NULL)/循环头节点if(head-ymin=ymin)/找到了对应的头节点EdgeNode*p=head-link;/获得头节点对应的第一条边节点if(p-xminedge-xmin)/新加入边的xmin值较小head-link=edge;edge-next=p;return;while(p-next!

=NULL)/循环当前头节点下所有边节点if(p-next-xminedge-xmin)edge-next=p-next;p-next=edge;return;p=p-next;/到这里说明新加入的边的xmin值比原有的都大p-next=edge;return;elseif(head-yminymin)/当前头节点的ymin值大于新加入的边的ymin/下面处理新加入头节点HeadNode*newhead=newHeadNode();newhead-ymin=head-ymin;newhead-link=head-link;newhead-next=head-next;head-ymin=ymin;head-link=edge;h

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1