计算机图形学裁剪定义,计算机图形学裁剪【计算机图形学实验四 :裁剪】

贵州大学实验报告

学院:计算机科学与技术 专业: 计算机科学与技术 班级:计科131

- 2 -

- 3 -

glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(x1, y1); glEnd(); }

//矩形的结构体

typedef struct Rectangle {

float xmin; float xmax; float ymin; float ymax; } Rectan ;

Rectan rect;

int x0, y0, x1, y1;

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

int CompCode(int x , int y , Rectan rect ) {

int code = 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; }

return code; }

- 4 -

//裁剪直线

int cohensutherlandlineclip(Rectan rect , int & x0, int & y0, int & x1, int & y1) {

int accept = 0, done = 0; float x, y;

int code0, code1, codeout;

int x00 = 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)

- 5 -

{

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

- 6 -

{

x0 = x1; y0 = y1; done = 1; accept = 1; } } }

if (accept) {

LineGL(x0, y0, x1, y1); }

return accept; }

void myDisplay() {

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(); }

void Init() {

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; }

- 7 -

void Reshape(int w , int h ) {

glViewport(0, 0, (GLsizei ) w , (GLsizei ) h ); glMatrixMode(GL_PROJECTION); glLoadIdentity();

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

//按键盘上字母c 裁剪,字母r 恢复原状,字母x 退出。 void keyboard(unsigned char key , int x , int y ) {

switch (key ) {

case "c" :

cohensutherlandlineclip(rect, x0, y0, x1, y1); glutPostRedisplay(); peak ; case "r" : Init();

glutPostRedisplay(); peak ; case "x" : exit(0); peak ; default : peak ; } }

int main(int argc , 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(); return 0;

- 8 -

- 9 -

- 10 -

1) 如果整条直线完全在窗口之内。此时,不需剪裁,显示整条直线,简称“取”之。 2) 如果整条直线明显在窗口之外,此时,不需剪裁,不显示直线。简称“弃”之。 3) 如果部分直线在窗口之内,部分在窗口之外。此时,需要求出直线与窗框之交点,并将窗口外的直线部分剪裁掉,显示窗口内的部分。 图2-1多边形裁剪区域编码 图2-2线段裁剪 为使计算机能够快速判断一条直线段与窗口属何种关系,采用如下编码方法。延长窗口的边,把未经裁剪的图形区域分成九个区,如图2-1所示。每个区具有一个位代码,即位二进制数,从左到右各位依次表示上、下、右、左。裁剪一条线段(如图2-2)时,先求出端点P1P2所在的区号code1和code2。若code1=0, 且code2=0,则说明线段P1P2均在窗口内,那么整条线段也必在窗口内,应取之。 若code1和code2经按位与运算后的结果code1&code2≠ 0,则说明两个端点同在窗口的上方、下方、左方或右方。在这种情况下,可判断线段完全在窗口外,可弃之。 如果上述两种条件均不成立,则按第三种情况处理。求出线段与窗口某边的交点,在交点处把线段一分为二,其中必有一段完全在窗口外,可弃之。再对另一段重复上述处理。 在实现本算法时,不必把线段与每条窗口边界依次求交,只要按顺序检测到端点的编码不为0,才把线段与对应的窗口边界求交。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值