七、思考题(尽量做,计入成绩):
1、如果要用鼠标绘制裁剪窗口和线段,应该如何编程?
Cohen_Sutherland算法将窗口平面划分成九个区域,每个区域给予不同的编码。格局线段端点落入不同的区域,给予线段端点不同编码。基于线段端点编码,算法给出了一整套剪裁方法。在剪裁过程中,窗口的参数要多次使用,线段端点需要多次编码,编码的计算需要多次与某些常数相“与”。
2、程序其它方面还有什么需要改进的?(提示:如何调用裁剪函数?) 在Ondraw加入调用函数: OnClipLineCohenSutherland();
3、如果要用Liang-Barskey算法实现裁剪,如何修改程序?
int ClipT(float p,float q,float *u1,float *u2) {
int flag=1; float r; if(p<0.0) {
r=q/p;
if(r>*u2) flag=0; else if(r>*u1) *u1=r; }
else if(p>0.0) {
r=q/p;
if(r<*u1) flag=0; else if(r<*u2) *u2=r; }
else if(q<0.0) flag=0; return flag; }
void Liang_Barsky(int xL,int yT,int xR,int yB,int x1,int y1,int x2,int y2) {
float dx,dy,u1,u2; u1=0.0;u2=1.0; dx=x2-x1;
if(ClipT(-dx,x1-xL,&u1,&u2))
if(ClipT(dx,xR-x1,&u1,&u2)) {
dy=y2-y1;
if(ClipT(-dy,y1-yT,&u1,&u2)) if(ClipT(dy,yB-y1,&u1,&u2)) {
if(u2<1.0) {
x2=x1+u2*dx; y2=y1+u2*dy; }
if(u1>0.0) {
x1=x1+u1*dx; y1=y1+u1*dy; }
line(x1,y1,x2,y2); } } }
void main(void) {
int gdriver=DETECT,gmode; int XL,XR,YB,YT; int x0,y0,x1,y1; do {
registerbgidriver(EGAVGA_driver); initgraph(&gdriver,&gmode,\ cleardevice();
printf(\ printf(\
printf(\ scanf(\ printf(\ cleardevice();
setcolor(LINE_COLOR); line(x0,y0,x1,y1); getch();
printf(\ printf(\
printf(\ scanf(\
printf(\ cleardevice(); line(x0,y0,x1,y1);
setcolor(WINDOW_COLOR); rectangle(XL,YT,XR,YB); getch();
cleardevice();
rectangle(XL,YT,XR,YB); setcolor(LINE_COLOR);
Liang_Barsky(XL,YT,XR,YB,x0,y0,x1,y1); getch();
printf(\ Continue?(y|n?)\ getchar();
}while(getchar()=='y'||getchar()=='Y'); printf(\
printf(\ getch();
closegraph(); }
八、实验体会
这次试验我的收获只要有两个方面:一个是编程水平的提高,还有一个是对计算机图形学理论知识的巩固。
首先,自此实验帮助我巩固了计算机图形学上课学习的内容,让我对算法的原理有了更为清晰的理解,并且能够根据算法,进行修改和添加,完成算法编出程序
而且,在和同学交流过程中,我学会了一些简单的技巧并且能够简单的调试程序,争取自己独立解决在编程过程中遇到的问题。
通过学习和实践,完成二维裁剪算法Cohen_Sutherland的实现3条典型线段,分别对应于完全在裁剪窗口内、完全在裁剪窗口外、穿过裁剪窗口三种情况,通过改变线段的坐标加以实现。还不能忘记在Ondraw加入调用函数:OnClipLineCohenSutherland();
总之,这次试验是我的编程水平有一定的提高,相信会对我以后的学习起到很大作用。
九、注意及特别说明:
如对Visual C++的编译环境不熟悉,请课下提前参考Visual C++的相关书籍和MSDN。