#include <GL/glut.h>
#include <stdlib.h>
#define DIST(x1,y1,x2,y2) sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
#include<vector>
using namespace std;
//class declaration
class ObjPoint
{
public:
ObjPoint(int xv, int yv) :x(xv), y(yv) {}
int x;
int y;
};
class ObjLine
{
public:
ObjLine(ObjPoint p1v, ObjPoint p2v) :
p1(p1v.x, p1v.y), p2(p2v.x, p2v.y) {}
ObjPoint p1;
ObjPoint p2;
};
class ObjRect
{
public:
ObjRect(int x1, int x2, int y1, int y2) :
xl(x1), xr(x2), yb(y1), yt(y2) {}
int xl;
int xr;
int yb;
int yt;
};
//global variables
int cut_status = 0;
vector<ObjLine>lines;
vector<ObjLine>cutlines;
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
}
GLbyte code(ObjPoint p1, ObjRect w)
{
GLbyte pcode = 0;
if (p1.x < w.xl)
{
pcode = pcode | 0x01;
}
if (p1.x > w.xr)
{
pcode = pcode | 0x02;
}
if (p1.y < w.yb)
{
pcode = pcode | 0x04;
}
if (p1.y > w.yt)
{
pcode = pcode | 0x08;
}
return pcode;
}
int far(ObjPoint p1, ObjPoint p2, ObjPoint& pf, ObjRect w)
{
//处理
long dist;
ObjPoint pm(0, 0);
GLbyte p1code, p2code, pmcode;
p1code = code(p1, w);
p2code = code(p2, w);
if (p2code == 0)
{
pf = p2;
return 0;
}
else
{
dist = DIST(p1.x, p1.y, p2.x, p2.y);
while (dist > 1)
{
p1code = code(p1, w);
p2code = code(p2, w);
pm.x = (p1.x + p2.x) / 2;
pm.y = (p1.y + p2.y) / 2;
pmcode = code(pm, w);
if (pmcode == 0)
{
p1 = pm;
}
else
{
if ((pmcode & p2code) != 0)
{
p2 = pm;
}
else
{
p1 = pm;
}
}
dist = DIST(p1.x, p1.y, p2.x, p2.y);
}
pf = p2;
}
return 0;
}
void cut(ObjRect w)
{
unsigned int i;
ObjPoint p1(0, 0);
ObjPoint p2(0, 0);
ObjPoint pf(0, 0);
GLbyte p1code, p2code;
cutlines.clear();
for (i = 0; i < lines.size(); i++)
{
p1 = lines[i].p1;
p2 = lines[i].p2;
p1code = code(p1, w);
p2code = code(p2, w);
if ((p1code | p2code) == 0)
{
cutlines.push_back(lines[i]);
}
//2、可能有交点
else if ((p1code & p2code) == 0)
{
// p1 p2最远可见点
if (far(p1, p2, pf, w))continue;
//p1 p2交换
p2 = p1;
p1 = pf;
if (far(p1, p2, pf, w))continue;
//可见段在p1 pf之间
cutlines.push_back(ObjLine(p1, pf));
}
else if ((p1code & p2code) != 0)
{
}
}
}
void draw_line(void)
{ //绘制一条线
unsigned int i;
glPolygonMode(GL_FRONT, GL_LINE);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex2f(-100, -100);
glVertex2f(100, -100);
glVertex2f(100, 100);
glVertex2f(-100, 100);
glEnd();
if (cut_status == 0)
{
for (i = 0; i < lines.size(); i++)
{
glBegin(GL_LINES);
glVertex2f(lines[i].p1.x, lines[i].p1.y);
glVertex2f(lines[i].p2.x, lines[i].p2.y);
glEnd();
}
}
else if (cut_status == 1)
{
cut(ObjRect(-100, 100, -100, 100));
glColor3f(0.0, 0.0, 1.0);
for (i = 0; i < cutlines.size(); i++)
{
glBegin(GL_LINES);
glVertex2f(cutlines[i].p1.x, cutlines[i].p1.y);
glVertex2f(cutlines[i].p2.x, cutlines[i].p2.y);
glEnd();
}
}
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'o':
cut_status = 0;
break;
case 'c':
cut_status = 1;
break;
}
glutPostRedisplay();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glColor3f(1.0, 1.0, 1.0);
draw_line();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
gluOrtho2D(-150.0, 150.0, -150.0 * (GLfloat)h / (GLfloat)w, 150.0 * (GLfloat)h / (GLfloat)w);
else
gluOrtho2D(-150.0 * (GLfloat)w / (GLfloat)h,
150.0 * (GLfloat)w / (GLfloat)h, -150.0, 150.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
lines.push_back(ObjLine(ObjPoint(-350, -150), ObjPoint(200, 200)));
lines.push_back(ObjLine(ObjPoint(-150, 0), ObjPoint(0, 150)));
lines.push_back(ObjLine(ObjPoint(80, 250), ObjPoint(-150, 0)));
lines.push_back(ObjLine(ObjPoint(80, 250), ObjPoint(-80, -250)));
lines.push_back(ObjLine(ObjPoint(0, 0), ObjPoint(70, 0)));
lines.push_back(ObjLine(ObjPoint(-110, 110), ObjPoint(110, 110)));
lines.push_back(ObjLine(ObjPoint(-110, 10), ObjPoint(70, 30)));
lines.push_back(ObjLine(ObjPoint(-150, -150), ObjPoint(150, 150)));
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
计图实验:裁剪算法
最新推荐文章于 2024-05-02 20:30:24 发布