#include
#include
#define L 00001
#define R 00002
#define B 00004
#define T 00010
#define M 00000
#define LT 00011
#define LB 00005
#define RT 00012
#define RB 00006
//#define L 0x0001
//#define R 0x0002
//#define B 0x0004
//#define T 0x0008
//#define M 0x0000
//
//#define LT 0x0009
//#define LB 0x0005
//#define RT 0x000a
//#define RB 0x0006
using namespace std;
struct rectan {
int xx0, yy0;
int xx1, yy1;
}rec;
int temX = 0, tempY = 0;
int c0 = 0, c1 = 0, c3 = 0;
bool f = false;
int CSLine(float xwl, float xwr, float ywb, float ywt, float x, float y) { //得到编码区
int temp = 0;
if (x < xwl) {
temp |= L;
}
else if (x > xwr) {
temp |= R;
}
if (y < ywb) {
temp |= B;
}
else if (y > ywt) {
temp |= T;
}
return temp;
}
void CSLineP(int temp, float xwl, float xwr, float ywb, float ywt, float &x1, float &y1, float x2, float y2, float& x, float& y) {
float k = (y2 - y1) / (x2 - x1);
if ((temp & L) == 1) {
y1 = y1 + k * (xwl - x1);
x1 = xwl;
}
if ((temp & R) == 2) {
y1 = y1 + k * (xwr - x1);
x1 = xwr;
}
if ((temp & B) == 4 && y1 < ywb) {
x1 = x1 + (ywb - y1) / k;
y1 = ywb;
}
if ((temp & T) == 8 && y1 > ywt) {
x1 = x1 + (ywt - y1) / k;
y1 = ywt;
}
x = x1, y = y1;
}
void CSLine(float xwl, float xwr, float ywb, float ywt, float x1, float y1, float x2, float y2) {
int code1 = CSLine(xwl, xwr, ywb, ywt, x1, y1);
int code2 = CSLine(xwl, xwr, ywb, ywt, x2, y2);
int flag = 0;
if (code1 & code2) {
flag = 0;
}
else if (code1 == 0 && code2 == 0) {
flag = 1;
}
else {
flag = 2;
}
if (flag == 1) {
glBegin(GL_LINES);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
glEnd();
}
else if (flag == 2) {
float newX1 = 0, newY1 = 0;
float newX2 = 0, newY2 = 0;
CSLineP(code1, xwl, xwr, ywb, ywt, x1, y1, x2, y2, newX1, newY1);
//交换两点的坐标
float tempx = x1, tempy = y1;
x1 = x2;
x2 = tempx;
y1 = y2;
y2 = tempy;
CSLineP(code2, xwl, xwr, ywb, ywt, x1, y1, x2, y2, newX2, newY2);
if (!(newX1 >= xwr && newX2 >= xwr) && !(newX1 <= xwl && newX2 <= xwl) && !(newY1 <= ywb && newY2 <= ywb) && !(newY1 >= ywt && newY2 >= ywt)) {
glBegin(GL_LINES);
glVertex2f(newX1, newY1);
glVertex2f(newX2, newY2);
glEnd();
}
}
}
void Init() {
glClear(GL_COLOR_BUFFER_BIT);
glLineWidth(5);
if (c1 == 0) {
glColor3f(0.f, 0.8f, 0.8f);
glBegin(GL_LINES);
glVertex2f(20, 120);
glVertex2f(430, 440);
glEnd();
}
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0.f, 0.8f, 0.5f);
if (c1 > 0) {
glRectf(rec.xx0, rec.yy0, rec.xx1, rec.yy1);
c3 = 1;
}
if (c3 == 1) {
glColor3f(1.0f, 0.0f, 0.0f);
CSLine(rec.xx0, rec.xx1, rec.yy1, rec.yy0, 20, 120, 430, 440);
}
if (f) {
glRectf(rec.xx0, rec.yy0, temX, tempY);
}
glutSwapBuffers();
}
void ChangeSize(GLsizei w, GLsizei h) {
if (h == 0) {
h = 1;
}
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, 600.f, 0.f, 600.f, 1.f, -1.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouseF(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
if (!f) {
f = true;
rec.xx0 = x;
rec.yy0 = 600 - y;
c0 = 1;
}
else {
f = false;
c1 = 1;
rec.xx1 = x;
rec.yy1 = 600 - y;
glutPostRedisplay();
}
}
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
f = false;
rec.xx0 = 0;
rec.yy0 = 0;
rec.xx1 = 0;
rec.yy1 = 0;
c1 = 0;
c0 = 0;
c3 = 0;
glutPostRedisplay();
}
}
void mouseMoveF(int x, int y) {
if (f) {
temX = x;
tempY = 600 - y;
glutPostRedisplay();
}
}
void main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutCreateWindow("CSLine");
glutDisplayFunc(Init);
glutReshapeFunc(ChangeSize);
glutMouseFunc(mouseF);
glutPassiveMotionFunc(mouseMoveF);
glClearColor(0.f, 0.5f, 0.5f, 1.f);
glutMainLoop();
}
运行结果:
liang-barsky裁剪:
#include
#include
using namespace std;
int LBLineClipTest(float p, float q, float &umax, float &umin) {
float r = 0.0;
if (p < 0.0) {
r = q / p;
if (r > umin) {
return 0;
}
else if (r > umax) {
umax = r;
}
}
else if (p > 0.0) {
r = q / p;
if (r < umax) {
return 0;
}
else if (r < umin) {
umin = r;
}
}
else if (q < 0.0) {
return 0;
}
return 1;
}
void LBLineClip(float xwl, float xwr, float ywb, float ywt, float x1, float y1, float x2, float y2) {
float umax, umin, deltax, deltay, xx2, yy2, xx1, yy1;
deltax = x2 - x1;
deltay = y2 - y1;
umax = 0.0;
umin = 1.0;
if (LBLineClipTest(-deltax, x1 - xwl, umax, umin)) {
if (LBLineClipTest(deltax, xwr - x1, umax, umin)) {
if (LBLineClipTest(-deltay, y1 - ywb, umax, umin)) {
if (LBLineClipTest(deltay, ywt - y1, umax, umin)) {
xx1 = int(x1 + umax*deltax + 0.5);
yy1 = int(y1 + umax*deltay + 0.5);
xx2 = int(x1 + umin*deltax + 0.5);
yy2 = int(y1 + umin*deltay + 0.5);
}
glBegin(GL_LINES);
glVertex2f(xx1, yy1);
glVertex2f(xx2, yy2);
glEnd();
}
}
}
}
void RenderSence() {
glClear(GL_COLOR_BUFFER_BIT);
glPolygonMode(GL_FRONT_AND_BACK , GL_LINE);
glLineWidth(5);
glColor3f(1.0f, 0.0f, 0.0f);
glRectf(20, 20, 120, 130);
LBLineClip(20, 120, 20, 130, 30, 190, 80, 10);
glFlush();
}
void ChangeSize(GLsizei w, GLsizei h) {
if (h == 0) {
h = 1;
}
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h) {
glOrtho(-100.0f, 250.0f, -100.0f, 250.0f * h / w, 1.0f, -1.0f);
}
else {
glOrtho(-100.0f, 250.0f * w / h, -100.0f, 250.0f, 1.0f, -1.0f);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void SetupRC() {
glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
}
void main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutCreateWindow("GLLine");
glutDisplayFunc(RenderSence);
glutReshapeFunc(ChangeSize);
SetupRC();
glutMainLoop();
}