计算机图形学实验四 裁剪.docx

上传人:b****8 文档编号:10110821 上传时间:2023-02-08 格式:DOCX 页数:13 大小:76.35KB
下载 相关 举报
计算机图形学实验四 裁剪.docx_第1页
第1页 / 共13页
计算机图形学实验四 裁剪.docx_第2页
第2页 / 共13页
计算机图形学实验四 裁剪.docx_第3页
第3页 / 共13页
计算机图形学实验四 裁剪.docx_第4页
第4页 / 共13页
计算机图形学实验四 裁剪.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

计算机图形学实验四 裁剪.docx

《计算机图形学实验四 裁剪.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验四 裁剪.docx(13页珍藏版)》请在冰豆网上搜索。

计算机图形学实验四 裁剪.docx

计算机图形学实验四裁剪

贵州大学实验报告

学院:

计算机科学与技术专业:

计算机科学与技术班级:

计科131

姓名

学号

实验组

实验时间

指导教师

黄初华

成绩

实验项目名称

直线裁剪

实验目的

一、实验目的

掌握常用的裁减及消隐算法:

直线的裁剪

实验要求

实现一个直线裁减算法

对于设计性实验,应根据“由学生自行设计实验方案并加以实现的实验”内涵要求,注意省略由学生自主设计的“实验方案”.

根据本实验的特点、要求和具体条件,采用“以学生自主训练为主的开放模式组织教学,还是采用集中授课形式”,须加以明确。

实验原理

直线裁减

Cohen-SutherLand算法(编码算法)

算法原理(递归的裁剪过程):

对于每条线段P1P2分为三种情况处理:

(1)若P1P2完全在窗口内,则显示该线段P1P2。

(2)若P1P2明显在窗口外,则丢弃该线段。

(3)若线段不满足

(1)或

(2)的条件,则在交点处把线段分为两段。

其中一段完全在窗口外,可弃之。

然后对另一段重复上述处理。

为快速判断,采用如下编码方法:

由窗口四条边所在直线把二维平面分成9个区域(右图),每个区域赋予一个四位编码:

CtCbCrCl(上下右左);直线的端点都按其所处区域赋予相应的区域码,用来标识出端点相对于裁剪矩形边界的位置。

各位编码含义:

上:

ify>ymax,Ct=1,else,0;

下:

ify

右:

ifx>xmax,Cr=1,else,0;

左:

ifx

对某线段的两个端点的区号进行位与运算,可知这两个端点是否同在视区的上、下、左、右;

‐如果两端点的编码均为0000,表示直线在窗口内。

‐如果两端点的编码相与不为0000,表示直线在窗口外。

‐如果两端点的编码不全为0000,但相与为0000,则该直线部分可见,需计算直线与窗口的交点,确定哪一部分可见。

算法描述:

BOOLdone,draw;(done表示是否完成,draw表示是否可见)

Unsignedcharcode1,code2;端点1,端点2的编码

While(!

done)

begin

if(判断code1,code2,若为第1种情况)

begin

done=TRUE;

draw=TRUE;

end

elseif(为第2种情况)

begin

done=TRUE;

draw=FALSE;

end

elseif(检查code1,若在窗口内)/*第3种情况*/

begin

交换端点及端点的编码;以左,上,右,下的次序对端点1进行判断及求交;将交点的值赋给端点1;

end

end

算法分析:

本算法的优点在于简单,易于实现。

用编码方法可快速判断线段的完全可见和显然不可见,他可以简单的描述为将直线在窗口左边的部分删去,按左,右,下,上的顺序依次进行,处理之后,剩余部分就是可见的了。

在这个算法中求交点是很重要的,他决定了算法的速度。

本算法对于其他形状的窗口是否同样有效就值得讨论了,这也证明了在图形算法中,没有几个是对大多数情况有效的。

特别适用二种情形:

大窗口场合;窗口特别小场合(光标拾取图形,光标看作小的裁剪窗口)。

Cohen-Sutherland与中点法在区域码测试阶段能以位运算方式高效率地进行,因而当大多数线段能够简单的取舍时,效率较好。

实验环境

五、实验条件:

硬件平台:

PC

软件(推荐):

Windows平台,Visualstdio2013,opengl

实验步骤

六、实验步骤

1.掌握算法原理;

2.依据算法,编写源程序并进行调试;

3.对运行结果进行保存与分析;

4.把源程序以文件的形式提交;

5.按格式书写实验报告。

实验内容

#include"stdafx.h"

#include

#include

#include

#pragmacomment(lib,"opengl32.lib")

#pragmacomment(lib,"glu32.lib")

#pragmacomment(lib,"glut32.lib")

#defineLEFT_EDGE1

#defineRIGHT_EDGE2

#defineBOTTOM_EDGE4

#defineTOP_EDGE8

staticinttimes=1;

//画从(x0,y0)到(x1,y1)的直线

voidLineGL(intx0,inty0,intx1,inty1)

{

glBegin(GL_LINES);

glColor3f(1.0f,0.0f,0.0f);

glVertex2f(x0,y0);

glColor3f(0.0f,1.0f,0.0f);

glVertex2f(x1,y1);

glEnd();

}

//矩形的结构体

typedefstructRectangle

{

floatxmin;

floatxmax;

floatymin;

floatymax;

}Rectan;

Rectanrect;

intx0,y0,x1,y1;

//求出坐标点的Cohen-Sutherland编码

intCompCode(intx,inty,Rectanrect)

{

intcode=0x00;

if(y

{

code=code|4;

}

if(y>rect.ymax)

{

code=code|8;

}

if(x>rect.xmax)

{

code=code|2;

}

if(x

{

code=code|1;

}

returncode;

}

//裁剪直线

intcohensutherlandlineclip(Rectanrect,int&x0,int&y0,int&x1,int&y1)

{

intaccept=0,done=0;

floatx,y;

intcode0,code1,codeout;

intx00=x0,y00=y0,x11=x1,y11=y1;

code0=CompCode(x0,y0,rect);

code1=CompCode(x1,y1,rect);

//直线全部在矩形框内部,应保留

if(!

(code0|code1))

{

accept=1;

done=1;

}

//直线和矩形不相交,并且划直线的两点在矩形同侧(上、下、右。

左),应去掉。

if(code0&code1)

{

done=1;

}

while(!

done)

{

//直线和矩形有交点,只保留矩形内部的

if(!

(code0|code1))

{

accept=1;

done=1;

}

else

{

if(code0!

=0)

{

codeout=code0;

}

else

{

codeout=code1;

}

if(codeout&LEFT_EDGE)

{

y=y0+(y1-y0)*(rect.xmin-x0)/(x1-x0);

x=(float)rect.xmin;

}

else

{

if(codeout&RIGHT_EDGE)

{

y=y0+(y1-y0)*(rect.xmax-x0)/(x1-x0);

x=(float)rect.xmax;

}

else

{

if(codeout&BOTTOM_EDGE)

{

x=y0+(x1-x0)*(rect.ymin-y0)/(y1-y0);

y=(float)rect.ymin;

}

else

{

if(codeout&TOP_EDGE)

{

x=x0+(x1-x0)*(rect.ymax-y0)/(y1-y0);

y=(float)rect.ymax;

}

}

}

}

if(codeout==code0)

{

x0=x;

y0=y;

code0=CompCode(x0,y0,rect);

}

else

{

x1=x;

y1=y;

code1=CompCode(x1,y1,rect);

}

//直线和矩形不相交,但是划直线的两点在矩形不同侧,这时应去掉。

if((times<=3)&&(code0&code1))

{

x0=x1;

y0=y1;

done=1;

accept=1;

}

}

}

 

if(accept)

{

LineGL(x0,y0,x1,y1);

}

returnaccept;

}

voidmyDisplay()

{

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0f,1.0f,0.0f);

glRectf(rect.xmin,rect.ymin,rect.xmax,rect.ymax);

LineGL(x0,y0,x1,y1);

glFlush();

}

voidInit()

{

glClearColor(0.0,0.0,0.0,0.0);

glShadeModel(GL_FLAT);

rect.xmin=100;

rect.xmax=300;

rect.ymin=100;

rect.ymax=300;

x0=0;

y0=360;

x1=650;

y1=0;

}

voidReshape(intw,inth)

{

glViewport(0,0,(GLsizei)w,(GLsizei)h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);

}

//按键盘上字母c裁剪,字母r恢复原状,字母x退出。

voidkeyboard(unsignedcharkey,intx,inty)

{

switch(key)

{

case'c':

cohensutherlandlineclip(rect,x0,y0,x1,y1);

glutPostRedisplay();

break;

case'r':

Init();

glutPostRedisplay();

break;

case'x':

exit(0);

break;

default:

break;

}

}

intmain(intargc,char*argv[])

{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);

glutInitWindowPosition(100,100);

glutInitWindowSize(640,480);

glutCreateWindow("裁剪");

Init();

glutDisplayFunc(myDisplay);

glutReshapeFunc(Reshape);

glutKeyboardFunc(keyboard);

glutMainLoop();

return0;

}

实验结果

实验总结

通过这次实验我对于直线的裁剪有了一定的认识,我实现的直线裁剪方法是Cohen-SutherLand算法(编码算法)算法原理:

对于每条线段P1P2分为三种情况处理:

若P1P2完全在窗口内,则显示该线段P1P2。

若P1P2明显在窗口外,则丢弃该线段。

若线段不满足

(1)或

(2)的条件,则在交点处把线段分为两段。

其中一段完全在窗口外,可弃之。

然后对另一段重复上述处理。

指导教师意见

 

签名:

年月日

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

当前位置:首页 > 党团工作 > 入党转正申请

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

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