1、参考博客
https://blog.csdn.net/ZY_cat/article/details/78290047
注:参考博客内有原理介绍和算法的代码实现,但个人在运行时出现了bug,遂修改了代码。
2、代码实现
#include "pch.h"
#include <GL/glut.h>
#include<time.h>
#define left 1
#define right 2
#define bottom 4
#define top 8
#define number 5 //control the number of lines
class LineClass
{
public:
GLfloat x1, y1, x2, y2;
GLfloat x1_init, y1_init, x2_init, y2_init;
}lines[number];
/*the boundary of the rectangular area*/
GLfloat xleft = 30, xright = 70, ytop = 70, ybottom = 30;
/*to judge if the points of the line in the aimed area*/
GLint encode(GLfloat x, GLfloat y) {
GLint code = 0;
if (x < xleft) code |= left; //take or action
if (x > xright) code |= right;
if (y > ytop) code |= top;
if (y < ybottom) code |= bottom;
return code;
}
void pointChange() {
/*temp location (x,y) and (x0,y0)*/
GLfloat x, y, x0, y0;
for (GLint i = 0; i < number; i++) {
/*initial position of two terminal points*/
/*to get different random number,or you can use random function to do this*/
lines[i].x1 = 2 +i * 9;
lines[i].x2 = 50+i * i * 3;
lines[i].y1 = 100 - i * i * i ;
lines[i].y2 = 19+i * i * 4;
/*if k is 0 or 1 / k is 0*/
if (lines[i].x1 == lines[i].x2)
lines[i].x1++;
if (lines[i].y1 == lines[i].y2)
lines[i].y1++;
lines[i].x1_init = lines[i].x1;
lines[i].x2_init = lines[i].x2;
lines[i].y1_init = lines[i].y1;
lines[i].y2_init = lines[i].y2;
/*the code of the two terminal points*/
GLint code1, code2;
code1 = encode(lines[i].x1, lines[i].y1);
code2 = encode(lines[i].x2, lines[i].y2);
/*temp code*/
GLint code;
/*gradient of line and its' value will not change*/
/*if the line is not all in the area*/
while (code1 != 0 || code2 != 0) {
/*if the line is not in the area at all*/
if (code1 & code2) { //this part is that I changed
lines[i].x1 = 0;
lines[i].x2 = 0;
lines[i].y1 = 0;
lines[i].y2 = 0;
break;
}
/*set code value of code1 and code 2 one by one*/
if (code1 != 0) {
code = code1;
}
else {
code = code2;
}
y0 = lines[i].y1;
x0 = lines[i].x1;
/*to check if the line need to cut and cutting*/
/*if the line is at left side of the rectangular area*/
if (code & left) {
x = xleft;
/*using equation to caculate y*/
y = y0 - (x0 - x) * (lines[i].y1 - lines[i].y2) / (lines[i].x1 - lines[i].x2);
}
/*checking right after updating data*/
else if (code & right) {
x = xright;
y = y0 - (x0 - x) * (lines[i].y1 - lines[i].y2) / (lines[i].x1 - lines[i].x2);
}
/*checking top after updating data*/
else if (code & bottom) {
y = ybottom;
x = x0 - (y0 - y) * (lines[i].x1 - lines[i].x2) / (lines[i].y1 - lines[i].y2);
}
/*checking top after updating data*/
else if (code & top) {
y = ytop;
x = x0 - (y0 - y) * (lines[i].x1 - lines[i].x2) / (lines[i].y1 - lines[i].y2);
}
/*updating the data*/
if (code == code1) {
lines[i].x1 = x;
lines[i].y1 = y;
code1 = encode(lines[i].x1, lines[i].y1);
}
else {
lines[i].x2 = x;
lines[i].y2 = y;
code2 = encode(lines[i].x2, lines[i].y2);
}
}
}
}
/*initial the window*/
void init() {
/*the color of window display is white*/
glClearColor(1.0, 1.0, 1.0, 1.0);
/*set the matrix projection matrix*/
glMatrixMode(GL_PROJECTION);
/*set relative cooedinate of the window*/
gluOrtho2D(0.0, 100.0, 0.0, 100.0);
pointChange();
}
void displayFcn() {
/*draw a rectangular int the window*/
/*clear the color of present frame*/
glClear(GL_COLOR_BUFFER_BIT);
/*set color of the boundary of rectangular to red*/
glColor3f(1.0, 0.0, 0.0);
/*set the bold of the boundary*/
glPointSize(2);
glBegin(GL_LINE_LOOP);
glVertex2f(xleft, ybottom);
glVertex2f(xright, ybottom);
glVertex2f(xright, ytop);
glVertex2f(xleft, ytop);
glEnd();
/*force execution of GL commands in finite time*/
glFlush();
for (GLint i = 0; i < number; i++) {
/*draw original line*/
glColor3f(1.0, 0.0, 0.0);
glPointSize(2);
glBegin(GL_LINES);
glVertex2f(lines[i].x1_init, lines[i].y1_init);
glVertex2f(lines[i].x2_init, lines[i].y2_init);
glEnd();
/*force execution of GL commands in finite time*/
glFlush();
/*draw the line after cutting*/
glColor3f(0.0, 0.0, 0.0);
glPointSize(2);
glBegin(GL_LINES);
glVertex2f(lines[i].x1, lines[i].y1);
glVertex2f(lines[i].x2, lines[i].y2);
glEnd();
/*force execution of GL commands in finite time*/
glFlush();
}
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("Cohen-Sutherland");
init();
glutDisplayFunc(displayFcn);
glutMainLoop();
return 0;
}
3、实际效果
4、注:此代码可能存在本人未发觉的bug,欢迎指正。