计算机图形学Cohen_Sutherland算法裁剪线段

来源:互联网 发布:租用阿里云vps 编辑:程序博客网 时间:2024/05/01 01:29
/**
*时间:2011年12月20日
*作者:鲍志强
*功能:直线的裁剪
*指导老师:杜吉祥
**/
#include<GL/glut.h>
#include<math.h>
#include<iostream>
using namespace std;

//定义窗口结构体
typedef struct Window
{
float Xwl;
float Xwr;
float Ywt;
float Ywb;
} *win;

//画窗体
void drawWindow(win pw)
{
glBegin(GL_LINE_LOOP);
glColor3f(1.0,0.0,0.0);
glVertex2f(pw->Xwl,pw->Ywt);
glVertex2f(pw->Xwl,pw->Ywb);
glVertex2f(pw->Xwr,pw->Ywb);
glVertex2f(pw->Xwr,pw->Ywt);
glEnd();
glFlush();
}
//画线
void drawLine(float *p,float *c)
{
glLineWidth(3);   //设置直线的宽度
glBegin(GL_LINES);
glColor3f(c[0],c[1],c[2]);
glVertex2f(p[0],p[1]);
glVertex2f(p[2],p[3]);
glEnd();
glFlush();
}

void Cohen_Sutherland(float *Points,win pw)
{
int code1[]={0,0,0,0},
code2[]={0,0,0,0};
float cutColor[]={0.0,0.0,0.0};

//求出 code1
if(Points[0]<pw->Xwl)
code1[3]=1;
else if(Points[0]>pw->Xwr)
code1[2]=1;
if(Points[1]<pw->Ywb)
code1[1]=1;
else if(Points[1]>pw->Ywt)
code1[0]=1;

//求出 code2
if(Points[2]<pw->Xwl)
code2[3]=1;
else if(Points[2]>pw->Xwr)
code2[2]=1;
if(Points[3]<pw->Ywb)
code2[1]=1;
else if(Points[3]>pw->Ywt)
code2[0]=1;

//判断是否能够 简取
if(code1[0]|code2[0] &&
code1[1]|code2[1] &&
code1[2]|code2[2] &&
code1[3]|code2[3])
{
cout<<"简取线段!"<<endl;
drawLine(Points,cutColor);
return;
}

//判断是否能够 简弃
if(code1[0]&code2[0] ||
code1[1]&code2[1] ||
code1[2]&code2[2] ||
code1[3]&code2[3])
{
cout<<"简弃线段!"<<endl;
return;
}

//不能 简取 简弃,求出所有交点
float k=(Points[3]-Points[1])/(Points[2]-Points[0]);
float x=0,y=0;
float temp[8]={0};
float node[4]={0};

x=pw->Xwl;
y=(Points[1]+((Points[3]-Points[1])/(Points[2]-Points[0]))*(x-Points[0]));
temp[0]=x;
temp[1]=y;

x=pw->Xwr;
y=(Points[1]+((Points[3]-Points[1])/(Points[2]-Points[0]))*(x-Points[0]));
temp[2]=x;
temp[3]=y;

y=pw->Ywb;
x=(Points[0]+(y-Points[1])/((Points[3]-Points[1])/(Points[2]-Points[0])));
temp[4]=x;
temp[5]=y;

y=pw->Ywt;
x=(Points[0]+(y-Points[1])/((Points[3]-Points[1])/(Points[2]-Points[0])));
temp[6]=x;
temp[7]=y;

//取出实交点
for(int i=0;i<4;i++)
{
if(temp[i*2]>=pw->Xwl &&
temp[i*2]<=pw->Xwr &&
temp[i*2+1]>=pw->Ywb &&
temp[i*2+1]<=pw->Ywt)
{
cout<<temp[i*2]<<"  "<<temp[i*2+1]<<endl;
if(temp[i*2]<Points[0])
{
if(node[0]==0)
{
node[0]=Points[0];
node[1]=Points[1];
}
else
{
node[2]=Points[0];
node[3]=Points[1];
}
}
else if(temp[i*2]>Points[2])
{
if(node[0]==0)
{
node[0]=Points[2];
node[1]=Points[3];
}
else
{
node[2]=Points[2];
node[3]=Points[3];
}
}
else
{
if(node[0]==0)
{
node[0]=temp[i*2];
node[1]=temp[i*2+1];
}
else
{
node[2]=temp[i*2];
node[3]=temp[i*2+1];
}
}
}
}

drawLine(node,cutColor);
}

//显示回调函数
void OnDisplay()
{
//消除颜色缓冲区
glClear(GL_COLOR_BUFFER_BIT);

//定义四条直线
float Points1[]={50,200,300,500};
float Points2[]={150,200,400,400};
float Points3[]={250,200,600,400};
float Points4[]={50,450,200,500};

float color[]={1.0,0,0};

//定义裁剪窗口
//数组格式为:minX maxX minY maxY
win pw=(win)malloc(sizeof(Window)); //声明一个窗口的全局变量
pw->Xwl=100;
pw->Xwr=550;
pw->Ywb=100;
pw->Ywt=450;

drawLine(Points1,color);
drawLine(Points2,color);
drawLine(Points3,color);
drawLine(Points4,color);
drawWindow(pw);
//裁剪直线
Cohen_Sutherland(Points1,pw);
Cohen_Sutherland(Points2,pw);
Cohen_Sutherland(Points3,pw);
Cohen_Sutherland(Points4,pw);
}

void OnReshape(int w,int h)
{
glClearColor(1.0f,1.0f,1.0f,0.0f);      //设置背景颜色
gluOrtho2D(0,w,0,h); //将当前绘图区域设置为二维正交投影的
}

int main(int argc, char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowSize(700,600);
glutInitWindowPosition(200,100);
glutCreateWindow("My OpenGL");
glutDisplayFunc(&OnDisplay);
glutReshapeFunc(&OnReshape);

glutMainLoop();
return 0;
}

0 0
原创粉丝点击