计图实验:裁剪算法

14 篇文章 0 订阅
#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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Spray!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值