清华版CG 实验4 编码裁剪算法

1.实验目的:

了解二维图形裁剪的原理(点的裁剪、直线的裁剪、多边形的裁剪),利用VC+OpenGL实现直线的裁剪算法。

2.实验内容:

(1) 理解直线裁剪的原理(Cohen-Surtherland算法、梁友栋算法)

(2) 利用VC+OpenGL实现直线的编码裁剪算法,在屏幕上用一个封闭矩形裁剪任意一条直线。

(3) 调试、编译、修改程序。

(4) 尝试实现梁友栋裁剪算法。

3.实验原理:

编码裁剪算法中,为了快速判断一条直线段与矩形窗口的位置关系,采用了如图A.4所示的空间划分和编码方案。

图A.4 裁剪编码

裁剪一条线段时,先求出两端点所在的区号code1和code2,若code1 = 0且code2 = 0,则说明线段的两个端点均在窗口内,那么整条线段必在窗口内,应取之;若code1和code2经按位与运算的结果不为0,则说明两个端点同在窗口的上方、下方、左方或右方。这种情况下,对线段的处理是弃之。如果上述两种条件都不成立,则按第三种情况处理。求出线段与窗口某边的交点,在交点处把线段一分为二,其中必有一段完全在窗口外,可弃之,对另一段则重复上述处理。

4.实验代码:

#include <GL/glut.h>

#include <stdio.h>

#include <stdlib.h>

#define LEFT_EDGE 1

#define RIGHT_EDGE 2

#define BOTTOM_EDGE 4

#define TOP_EDGE 8

void LineGL(int x0,int y0,int x1,int y1)

{

glBegin (GL_LINES);

glColor3f (1.0f, 0.0f, 0.0f); glVertex2f (x0,y0);

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

glEnd ();

}

struct Rectangle

{

float xmin,xmax,ymin,ymax;

};

Rectangle rect;

int x0,y0,x1,y1;

int CompCode(int x,int y,Rectangle rect)

{

int code=0x00;

if(y<rect.ymin)

code=code|4;

if(y>rect.ymax)

code=code|8;

if(x>rect.xmax)

code=code|2;

if(x<rect.xmin)

code=code|1;

return code;

}

int cohensutherlandlineclip(Rectangle rect, int &x0,int & y0,int &x1,int &y1)

{

int accept,done;

float x,y;

accept=0;

done=0;

int code0,code1, codeout;

code0 = CompCode(x0,y0,rect);

code1 = CompCode(x1,y1,rect);

do{

if(!(code0 | code1))

{

accept=1;

done=1;

}

else if(code0 & code1)

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=x0+(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);

}

}

}while(!done);

if(accept)

LineGL(x0,y0,x1,y1);

return accept;

}

void myDisplay()

{

glClear(GL_COLOR_BUFFER_BIT);

glColor3f (1.0f, 0.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 = 450,y0 = 0, x1 = 0, y1 = 450;

printf("Press key ‘c‘ to Clip!\nPress key ‘r‘ to Restore!\n");

}

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

}

void keyboard(unsigned char key, int x, int y)

{

switch (key)

{

case ‘c‘:

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

glutPostRedisplay();

break;

case ‘r‘:

Init();

glutPostRedisplay();

break;

case ‘x‘:

exit(0);

break;

default:

break;

}

}

int main(int argc, char *argv[])

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

glutInitWindowPosition(100, 100);

glutInitWindowSize(640, 480);

glutCreateWindow("Hello World!");

Init();

glutDisplayFunc(myDisplay);

glutReshapeFunc(Reshape);

glutKeyboardFunc(keyboard);

glutMainLoop();

return 0;

}

5.实验提高

请分别给出直线的三种不同位置情况,测试实验代码是否存在问题,有的话请调试改正。可能的话,可以尝试实现梁友栋裁剪算法。

清华版CG 实验4 编码裁剪算法,布布扣,bubuko.com

时间: 2024-10-13 02:15:50

清华版CG 实验4 编码裁剪算法的相关文章

清华版CG 实验2 直线生成算法实现

1.实验目的: 理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法. 2.实验内容: (1) 根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果: (2) 指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告: (3) 根据示范代码,将其改造为圆的光栅化算法,写入实验报告: (4) 了解和使用OpenGL的生成直线的命令,来验证程序运行结果. 3.实验原理: 示范代码原理参见教材直线

清华版CG 实验7 OpenGL光照

一.实验目的: 了解掌握OpenGL程序的光照与材质,能正确使用光源与材质函数设置所需的绘制效果. 二.实验内容: (1)下载并运行Nate Robin教学程序包中的lightmaterial程序,试验不同的光照与材质系数: (2)运行示范代码1,了解光照与材质函数使用. 三.实验原理: 为在场景中增加光照,需要执行以下步骤: (1) 设置一个或多个光源,设定它的有关属性: (2) 选择一种光照模型: (3) 设置物体的材料属性. 具体见教材第8章8.6节用OpenGL生成真实感图形的相关内容.

清华版CG 实验5 OpenGL模型视图变换

1.实验目的: 理解掌握OpenGL程序的模型视图变换. 2.实验内容: (1)阅读实验原理,运行示范实验代码,理解掌握OpenGL程序的模型视图变换: (2)根据示范代码,尝试完成实验作业: 3.实验原理: 在OpenGL程序中,视图变换必须出现在模型变换之前,但可以在绘图之前的任何时候执行投影变换和视口变换. 1.在指定的视图变换之前,应该使用glLoadIdentity()函数把当前矩阵设置为单位矩阵. 2.在载入单位矩阵之后,使用gluLookAt()函数指定视图变换.如果程序没有调用g

清华版CG 实验8 OpenGL交互

1.实验目的: 理解掌握一个OpenGL程序的常见交互方法. 2.实验内容: (1)运行示范代码,掌握程序鼠标交互方法.鼠标坐标获取方法: (2)尝试为示范代码添加键盘与菜单控制.绘制直线功能: 3.实验原理: 要想在OpenGL中处理鼠标事件非常的方便,GLUT已经为我们的注册好了函数,只要我们提供一个方法.使用函数glutMouseFunc,就可以帮我们注册我们的函数,这样当发生鼠标事件时就会自动调用我们的方法. 函数的原型是: void glutMouseFunc(void(*func)(

清华版CG 实验3 OpenGL几何变换

1.实验目的: 理解掌握OpenGL二维平移.旋转.缩放变换的方法. 2.实验内容: (1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移.旋转.缩放变换的方法: (2)根据示范代码,尝试完成实验作业: 3.实验原理: (1)OpenGL下的几何变换 在OpenGL的核心库中,每一种几何变换都有一个独立的函数,所有变换都在三维空间中定义. 平移矩阵构造函数为glTranslate<f,d>(tx, ty, tz),作用是把当前矩阵和一个表示移动物体的矩阵相乘.tx, ty,tz指定这

清华版CG 实验6 Bezier曲线生成

1.实验目的: 了解曲线的生成原理,掌握几种常见的曲线生成算法,利用VC+OpenGL实现Bezier曲线生成算法. 2.实验内容: (1) 结合示范代码了解曲线生成原理与算法实现,尤其是Bezier曲线: (2) 调试.编译.修改示范程序. 3.实验原理: Bezier曲线是通过一组多边形折线的顶点来定义的.如果折线的顶点固定不变,则由其定义的Bezier曲线是唯一的.在折线的各顶点中,只有第一点和最后一点在曲线上且作为曲线的起始处和终止处,其他的点用于控制曲线的形状及阶次.曲线的形状趋向于多

CGA裁剪算法之Sutherland-Hodgman多边形裁剪算法

CGA裁剪算法之Sutherland-Hodgman多边形裁剪算法 Sutherland-Hodgman算法也叫逐边裁剪法,该算法是萨瑟兰德(I.E.Sutherland)和霍德曼(Hodgman)在1974年提出的. 这种算法采用了分割处理.逐边裁剪的方法.这一算法,适合任何凸多边形窗口对任何“凸或者凹,或者平面或者非平面”多边形的裁剪处理. 逐边逐次裁剪特点:逐边是分别用裁剪平面的边界来处理,且裁剪各个边界的处理顺序无关紧要.逐次是每次的裁剪边界对多边形的每条边处理是依次进行的,有顺序要求.

[计算机图形学 with OpenGL] Chapter8 习题8.12 NLN二维线段裁剪算法实现

Nicholl-Lee-Nicholl二维线段裁剪算法相对于Cohen-Sutherland和Liang-Barsky算法来说,在求交点之前进行了线段端点相对于几个区域的判断,可以确切的知道要求交点的边的信息. 此方法只在二维空间裁剪时使用,C-S和L-B裁剪方法则可应用到三维空间. 算法步骤: 1 先使用C-S裁剪算法的区域码判断方法,去除一部分在裁剪区域外面的线段.显示在完全在裁剪区域内的线段.其他不能判断的情况,采用NLN算法进行裁剪. 2 p1和p2若有一点在区域内,必要时交换端点以确保

Cyrus-Beck裁剪算法及OpenGL实践

恩..接着就是Cyrus-Beck算法.这个算法比之前的Cohen-Sutherland算法厉害,处理任意凸多边形对线段的裁剪.自然,这个算法也比Cohen-Sutherland算法复杂不少. 首先,是线段与多边形相交的情况: 我们把定义向量c = (C - A),而线段AC是射线A + ct的一部分.那么t取0和1就是线段AC.我们将射线与多边形的每条边求出相交时的t.取tin = max(0, tin),tout = max(tout, 1).最终会获得一个区间[tin,tout]就是经多边