logo资料库

计算机图形学课后题答案-徐长青、许志闻(完整版).doc

第1页 / 共101页
第2页 / 共101页
第3页 / 共101页
第4页 / 共101页
第5页 / 共101页
第6页 / 共101页
第7页 / 共101页
第8页 / 共101页
资料共101页,剩余部分请下载后查看
第2章
第3章
第4章
第5章
第6章
习题解答 第 2 章 2.如果线段端点坐标值不是整数,采用 DDA 算法产生的直线和将端点坐标值先取整 再用 Bresenham 算法产生的直线是否完全相同?为什么?能否扩充整数 Bresenham 算法使之能 处理当线段端点坐标值不是整数的情况(比端点坐标先取整数产生的直线更精确)。 如果线段端点坐标值不是整数,DDA 算法和 Bresenham 算法产生的直线不完全相同。 DDA 算法是在直线附近寻找最靠近直线的象素点。而端点坐标值先取整再用 Bresenham 算 法,因为端点坐标值先取整,与原直线相比,可能会改变直线的斜率。因此两种算法相比, 前者比后者更精确。 可以将整数 Bresenham 算法扩充为实数 Bresenham 算法。算法中的变量都应采用实数类 型,在绘制时再对实数坐标值取整数,这样做比端点坐标先取整数产生的直线更精确,具体 算法如下: void BresenhamLine(double x1, double y1, double x2, double y2) { int x,y ; double dx,dy,p; x=(int)(x1+0.5); y=(int)(y1+0.5); dx=x2-x1; dy=y2-y1; p=2*dy*(x-x1+1)-dx*(2*y-2*y1+1); for(;x<=x2;x++) { SetPixel(x,y); if(p>=0) { y++; p+=2*(dy-dx); } else { } p+=2*dy; } } 3.推广本章第一节给出的产生线段的整数 Bresenham 算法,去掉 0≤m≤1 和 xl
dy dx y d 1  ( x     b y x ) y d      2 ( dx d p  1 i ( 2 dy x p  1 i  2 dy x p     ( x dy dx 2 ) ( d dy x  2 2 ) 2( x    2( y  i 1  )    x b   ydx b y dx    ) i ydx ) 2( x    ) b y dx  i ) y dx i 1  若 ip  , 则 1iy 0     , y y p   2 dy x   2 dx y  ; 若 ip  , 则 1 iy 0    , 0 y p   2 dy x  。 m 0≤m≤1 Δx Δy Δp(p≥0) >0 >0 2 dy p    2 dx Δp(p<0) 2 p   dy <0 <0 p    2 dy  2 dx p    2 dy -1≤m≤0 >0 <0 p   2 dy  2 dx p    2 dy <0 >0 p    2 dy  2 dx p   2 dy m>1 >0 >0 p   2 dx  2 dy p   2 dx <0 <0 p    2 dx  2 dy p    2 dx m<-1 >0 <0 p   2 dx  2 dy p    2 dx <0 >0 p    2 dx  2 dy p   2 dx void BresenhamLine(int x1,int y1,int x2,int y2) { int x,y,dx,dy,p,xmin,ymin,xmax,ymax,lx,ly,deltax,deltay; dx=x2-x1; dy=y2-y1; xmin=min(x1,x2); xmax=max(x1,x2); ymin=min(y1,y2); ymax=max(y1,y2); lx=xmax-xmin; ly=ymax-ymin; deltax= (dx==0)?0:(dx>0?1:-1); deltay= (dy==0)?0:(dy>0?1:-1);
x=x1; y=y1; if(lx>ly) { p=2*dy-dx; for(;x!=x2;x+=deltax) { SetPixel(x,y,RGB(0,0,0)); if(p>=0) { y+=deltay; p+=2*(ly-lx); } else { } p+=2*ly; } } else { p=2*dx-dy; for(;y!=y2;y+=deltay) { SetPixel(x,y,RGB(0,0,0)); if(p>=0) { x+=deltax; p+=2*(lx-ly); } else { } p+=2*lx; } } } 4.在本章第一节说明 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)处向后。 试说明为什么对所列两种情况算法仍能正确地工作。
假定 0≤m≤1,如图所示 d1 d1 d2 d2 (x,y)
若当前象素点是(x,y),则该直线与横坐标为 x 的直线的交点必落在(x,y-0.5),(x,y+0.5) 之间。又由于 0≤m≤1,则该直线与横坐标为 x+1 的直线的交点必落在(x+1,y-0.5),(x+1,y+1.5) 之间。 情况(1),交点在 y-0.5 到 y 之间,d1<0,d2>0,则Δ=Δx (d1-d2)<0,应取(x+1,y); 情况(2),交点在 y+1 到 y+1.5 之间,d1>0,d2<0,则Δ=Δx (d1-d2)>0,应取(x+1,y+1。 以上结果是根据算法而得到的,同时该结果也符合实际的绘制。 综上,当交点在在 y-0.5 到 y 之间,四舍五入取象素点(x+1,y);当交点在在 y+1 到 y+1.5 之间,四舍五入取象素点(x+1,y+1)。 5.本章介绍的 Bresenham 直线算法是否可以利用对称性,通过判别量 p 同时从直线两 端向中心画线?当 0<Δy<Δx,Δx 和Δy 有最大公因数 c,而且Δx/c 为偶数和Δy/c 为奇 数时,两种方法画出的线是否一致?当Δx 是 2Δy 的整数倍时两种方法画出的线是否一致。 x y ,已知一点坐 求对称点的推导:设中点坐标为 ( ) ) ) y ,端点坐标为 1 m , x y 和 2 ( ( , x m , 1 2 x 标为 1 i ( , y ,其对称点坐标为 2 x 1 i ) ( , y i 2 i )
    x m x 2 i ( x x  1 x x  1 2 ) / 2 ( x  2 1 i y x  1 i 2 i   i x 2 y 1 ) / 2 y  2 y m y 1 i   ( y 1  y 2 ) / 2 (  y 1 i  y 2 i ) / 2 void SymmetryBresenhamLine(int x1,int y1,int x2,int y2) { int x,y,dx,dy,p,xmin,ymin,xmax,ymax; xmin=min(x1,x2); xmax=max(x1,x2); ymin=min(y1,y2); ymax=max(y1,y2); x=xmin; y=ymin; dx=xmax-xmin; dy=ymax-ymin; if(dx>dy) { p=2*dy-dx; for(;(x+x)<=(xmin+xmax);x++) { SetPixel(x,y,RGB(0,0,0)); SetPixel((xmin+xmax)-x,(ymin+ymax)-y,RGB(0,0,0)); if(p>=0) { y++; p+=2*(dy-dx); } else { } p+=2*dy; } } else { p=2*dx-dy; for(;(y+y)<=(ymin+ymax);y++) { SetPixel(x,y,RGB(0,0,0)); SetPixel((xmin+xmax)-x,(ymin+ymax)-y,RGB(0,0,0)); if(p>=0) { x++; p+=2*(dx-dy);
} else { } p+=2*dx; } } } 当Δx 和Δy 有最大公因数 c,而且Δx/c 为偶数和Δy/c 为奇数时,和当Δx 是 2Δy 的整数倍时,对称性算法画出的线与 Bresenham 直线算法画出的线不一致。 例如:端点为(0,0)和(4,3)的线段(Δx/c 为偶数和Δy/c 为奇数) 用 Bresenham 直线算法画线 (0,0)(1,1)(2,2)(3,2)(4,3) 用对称性算法画线 (0,0)(4,3)(1,1)(3,2)(2,2)(2,1) 端点为(0,0)和(6,3)的线段(Δx 是 2Δy 的整数倍) 用 Bresenham 直线算法画线 (0,0)(1,1)(2,1)(3,2)(4,2)(5,3)(6,3) 用对称性算法画线 (0,0)(6,3)(1,1)(5,2)(2,1)(4,2)(3,2)(3,1) 6.推广本章第二节给出的 Bresenham 画圆算法使能够画出一个内部填充的实心圆。 填充实心圆算法
y y=-x y=x x void SolidBresenhamCircle(int x0,int y0,int R,COLORREF color) { int x,y,p,i; x=0; y=R; p=3-2*R; for(;x<=y;x++) { for(i=-x;i<=x;i++) { SetPixel(x0+i,y0+y,color); SetPixel(x0+i,y0-y,color); } for(i=-y;i<=y;i++) { SetPixel(x0+i,y0+x,color); SetPixel(x0+i,y0-x,color); } if(p>=0) { p+=4*(x-y)+10; y--; } else { } p+=4*x+6;
分享到:
收藏