实验六二维裁剪Word文档下载推荐.docx

上传人:b****5 文档编号:18378518 上传时间:2022-12-15 格式:DOCX 页数:11 大小:33.99KB
下载 相关 举报
实验六二维裁剪Word文档下载推荐.docx_第1页
第1页 / 共11页
实验六二维裁剪Word文档下载推荐.docx_第2页
第2页 / 共11页
实验六二维裁剪Word文档下载推荐.docx_第3页
第3页 / 共11页
实验六二维裁剪Word文档下载推荐.docx_第4页
第4页 / 共11页
实验六二维裁剪Word文档下载推荐.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

实验六二维裁剪Word文档下载推荐.docx

《实验六二维裁剪Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《实验六二维裁剪Word文档下载推荐.docx(11页珍藏版)》请在冰豆网上搜索。

实验六二维裁剪Word文档下载推荐.docx

在这个矩形方位之外定义的图形,不能被显示出来。

注意,当没有为应用程序指定裁剪窗口时,就使用默认的坐标:

xWinMin=-1.0,xWinMax=1.0,yWinMin=-1.0,yWinMax=1.0。

这样,默认的裁剪窗口是以坐标系原点为中心,边长为2的正方形区域。

那么,这个范围内的图形,显示在显示器上生成窗口的哪个位置呢?

这需要通过视区函数(ViewPort,有时也称视口)来指定:

glViewport(xViewportMin,xViewportMax,viewportWidth,viewportHeight);

这里的所有参数用对应于显示窗口的整数屏幕坐标给出,参数xViewportMin和yViewportMin指定视区左下角的位置,视区的宽度和高度用参数viewportWidth和viewportHeight指定。

也就是说,用gluOrtho2D指定显示范围的图形在用glViewport指定的窗口位置显示出来。

注意,当没有在应用程序中用glViewport指定视区时,则默认的视区大小及位置与整个OpenGL显示窗口一样。

显然,当gluOrtho2D和glViewport指定的矩形区域的宽高比不一样时,图形会发生形变。

那么,已经在世界坐标系中定义的物体,计算机的显示系统怎样确定哪些部分显示,哪些部分不显示呢?

这是通过相关的裁减算法计算出来的。

二、裁减算法

1、点的裁剪

判断点P=(x,y)是否在裁剪区域(xWinMin,xWinMax,yWinMin,yWinMax)内,只要判断是否满足条件

如果满足,就表明在裁剪区域内,否则,就在裁剪区域之外。

2、线段的裁减

线段的裁减要判断线段与裁剪矩形边界的各种关系。

经典的线段裁剪算法有Cohen-Sutherland算法和梁友栋-Barskey算法。

Cohen-Sutherland算法的代码如下:

classwcPt2D{

public:

GLfloatx,y;

};

inlineGLintround(constGLfloata){returnGLint(a+0.5);

}

/*Defineafour-bitcodeforeachoftheoutsideregionsofa

*rectangularclippingwindow.

*/

constGLintwinLeftBitCode=0x1;

constGLintwinRightBitCode=0x2;

constGLintwinBottomBitCode=0x4;

constGLintwinTopBitCode=0x8;

/*Abit-maskregioncodeisalsoassignedtoeachendpointofaninput

*linesegment,accordingtoitspositionrelativetothefouredgesof

*aninputrectangularclipwindow.

*

*Anendpointwitharegion-codevalueof0000isinsidetheclipping

*window,otherwiseitisoutsideatleastoneclippingboundary.If

*the'

or'

operationforthetwoendpointcodesproducesavalueof

*false,theentirelinedefinedbythesetwoendpointsissaved

*(accepted).Ifthe'

and'

operationbetweentwoendpointcodesis

*true,thelineiscompletelyoutsidetheclippingwindow,anditis

*eliminated(rejected)fromfurtherprocessing.

inlineGLintinside(GLintcode){returnGLint(!

code);

inlineGLintreject(GLintcode1,GLintcode2)

{returnGLint(code1&

code2);

inlineGLintaccept(GLintcode1,GLintcode2)

{returnGLint(!

(code1|code2));

GLubyteencode(wcPt2Dpt,wcPt2DwinMin,wcPt2DwinMax)

{

GLubytecode=0x00;

if(pt.x<

winMin.x)

code=code|winLeftBitCode;

if(pt.x>

winMax.x)

code=code|winRightBitCode;

if(pt.y<

winMin.y)

code=code|winBottomBitCode;

if(pt.y>

winMax.y)

code=code|winTopBitCode;

return(code);

}

voidswapPts(wcPt2D*p1,wcPt2D*p2)

wcPt2Dtmp;

tmp=*p1;

*p1=*p2;

*p2=tmp;

voidswapCodes(GLubyte*c1,GLubyte*c2)

GLubytetmp;

tmp=*c1;

*c1=*c2;

*c2=tmp;

voidlineClipCohSuth(wcPt2DwinMin,wcPt2DwinMax,wcPt2Dp1,wcPt2Dp2)

GLubytecode1,code2;

GLintdone=false,plotLine=false;

GLfloatm;

while(!

done){

code1=encode(p1,winMin,winMax);

code2=encode(p2,winMin,winMax);

if(accept(code1,code2)){

done=true;

plotLine=true;

else

if(reject(code1,code2))

else{

/*Labeltheendpointoutsidethedisplaywindowasp1.*/

if(inside(code1)){

swapPts(&

p1,&

p2);

swapCodes(&

code1,&

code2);

/*Useslopemtofindline-clipEdgeintersection.*/

if(p2.x!

=p1.x)

m=(p2.y-p1.y)/(p2.x-p1.x);

if(code1&

winLeftBitCode){

p1.y+=(winMin.x-p1.x)*m;

p1.x=winMin.x;

winRightBitCode){

p1.y+=(winMax.x-p1.x)*m;

p1.x=winMax.x;

winBottomBitCode){

/*Needtoupdatep1.xfornonverticallinesonly.*/

p1.x+=(winMin.y-p1.y)/m;

p1.y=winMin.y;

winTopBitCode){

p1.x+=(winMax.y-p1.y)/m;

p1.y=winMax.y;

if(plotLine)

lineBres(round(p1.x),round(p1.y),round(p2.x),round(p2.y));

//lineBres直线生成算法前面

添加以下的OpenGLglut的框架,并加上键盘控制,注意在把前面的Bresenham直线生成算法加到最前面:

voidmyDisplay()

wcPt2DwinMin,winMax,p1,p2;

winMin.x=100;

winMin.y=200;

//定义裁剪窗口

winMax.x=400;

winMax.y=400;

p1.x=50;

p1.y=50;

//定义被裁剪的直线端点

p2.x=450;

p2.y=450;

glClear(GL_COLOR_BUFFER_BIT);

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

glRectf(winMin.x,winMin.y,winMax.x,winMax.y);

//绘制红色裁剪矩形

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

if(flag)

{

lineClipCohSuth(winMin,winMax,p1,p2);

//绘制裁剪线段

glBegin(GL_LINES);

glVertex2i(p1.x,p1.y);

glVertex2i(p2.x,p2.y);

glEnd();

glFlush();

voidInit()

glClearColor(0.0,0.0,0.0,0.0);

glMatrixMode(GL_PROJECTION);

gluOrtho2D(0.0,640.0,0.0,480.0);

voidReshape(intw,inth)

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

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

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

voidkeyboard(unsignedcharkey,intx,inty)

if(key=='

c'

||key=='

C'

)flag=true;

r'

R'

)flag=false;

glutPostRedisplay();

intmain(intargc,char*argv[])

glutInit(&

argc,argv);

glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);

glutInitWindowPosition(100,100);

glutInitWindowSize(640,480);

glutCreateWindow("

Cohen-Sutherland直线裁减算法,C键裁减,R键复原"

);

Init();

glutDisplayFunc(myDisplay);

glutReshapeFunc(Reshape);

glutKeyboardFunc(keyboard);

glutMainLoop();

return0;

梁友栋-Barskey算法的代码如下:

classwcPt2D

private:

/*DefaultConstructor:

initializepositionas(0.0,0.0).*/

wcPt2D(){

x=y=0.0;

voidsetCoords(GLfloatxCoord,GLfloatyCoord){

x=xCoord;

y=yCoord;

GLfloatgetx()const{

returnx;

GLfloatgety()const{

returny;

GLintclipTest(GLfloatp,GLfloatq,GLfloat*u1,GLfloat*u2)

GLfloatr;

GLintreturnValue=true;

if(p<

0.0){

r=q/p;

if(r>

*u2)

returnValue=false;

else

if(r>

*u1)

*u1=r;

if(p>

r=q/p;

if(r<

returnValue=false;

elseif(r<

*u2=r;

}

/*Thusp=0andlineisparalleltoclippingboundary.*/

if(q<

0.0)

/*Lineisoutsideclippingboundary.*/

return(returnValue);

voidlineClipLiangBarsk(wcPt2DwinMin,wcPt2DwinMax,wcPt2Dp1,wcPt2Dp2)

GLfloatu1=0.0,u2=1.0,dx=p2.getx()-p1.getx(),dy;

if(clipTest(-dx,p1.getx()-winMin.getx(),&

u1,&

u2))

if(clipTest(dx,winMax.getx()-p1.getx(),&

u2)){

dy=p2.gety()-p1.gety();

if(clipTest(-dy,p1.gety()-winMin.gety(),&

if(clipTest(dy,winMax.gety()-p1.gety(),&

if(u2<

1.0){

p2.setCoords(p1.getx()+u2*dx,p1.gety()+u2*dy);

}

if(u1>

p1.setCoords(p1.getx()+u1*dx,p1.gety()+u1*dy);

lineBres(round(p1.getx()),round(p1.gety()),

round(p2.getx()),round(p2.gety()));

}

再加上前面的框架代码,把其中的调用lineClipCohSuth改为lineClipLiangBarsk,注意参数的赋值。

三、上机练习

完整实现Cohen-Sutherland和梁友栋-Barskey线段裁减算法,理解裁减的基本原理,并继续体会怎样用键盘来控制图形的显示。

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

当前位置:首页 > 高等教育 > 文学

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

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