两个直线裁剪算法的OpenGL实现
if 0
//Cohen-Sutherland
include
include
define PI 3.14159
define Xleft 100
define Xright 400
define Yup 400
define Ydown 100
void init()
{
// 设置背景色为白色 不透明度为0
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 600, 0.0, 600);
glClear(GL_COLOR_BUFFER_BIT);
}
void gl_Point(int x, int y) {
glPointSize(5);
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
glFlush();
}
void circle(double x, double y)
{
int n = 150;
double R = 15;
glColor3i(1, 1, 1);
for (int i = 0; i < 150; i++)
{
gl_Point(x + R * cos(2 * PI * i / n), y + R * sin(2 * PI * i / n));
}
}
void DDA(int x1, int y1, int x2, int y2) {
int k, i;
float x, y, dx, dy;
k = abs(x2 - x1);
if (abs(y2 - y1) > k)
k = abs(y2 - y1);
//直线被划分为每一小段的长度
dx = float(x2 - x1) / k;
dy = float(y2 - y1) / k;
x = float(x1);
y = float(y1);
for (i = 0; i < k; i++) {
gl_Point(int(x + 0.5), int(y + 0.5));
x = x + dx;
y = y + dy;
}
}
int encode(double x, double y)
{
int c = 0;
if (x < Xleft) c = 1; else if (x > Xright) c = 2;
if (y < Ydown) c = c + 4; else if (y > Yup) c = c + 8;
return c;
}
void CohenSutherland(double x0, double y0, double x2, double y2)
{
int c, c0, c1;
double x, y;
c0 = encode(x0, y0);
c1 = encode(x2, y2);
while (c0 != 0 || c1 != 0)
{
if ((c0 & c1) != 0) break;
c = c0;
if (c == 0) c = c1;
if ((c & 1) == 1) {
y = y0 + (y2 - y0) * (Xleft - x0) / (x2 - x0);
x = Xleft;
}
else if ((c & 2) == 2) {
y = y0 + (y2 - y0) * (Xright - x0) / (x2 - x0);
x = Xright;
}
else if ((c & 4) == 4) {
x = x0 + (x2 - x0) * (Ydown - y0) / (y2 - y0);
y = Ydown;
}
else if ((c & 8) == 8) {
x = x0 + (x2 - x0) * (Yup - y0) / (y2 - y0);
y = Yup;
}
circle(x, y);
if (c == c0) {
x0 = x;
y0 = y;
c0 = encode(x, y);
}
else if (c == c1){
x2 = x;
y2 = y;
c1 = encode(x, y);
}
1
| } glColor3f(0.0, 1.0, 0.0); DDA(x0, y0, x2, y2); |
}
void display()
{
int x0 = 50, y0 = 100, x1 = 450, y1 = 500;
glColor3f(1.0, 0.0, 0.0);
DDA(x0, y0, x1, y1);
1
| glColor3f(0.0, 0.0, 0.0); DDA(Xleft, 0, Xleft, 600); DDA(Xright, 0, Xright, 600); DDA(0, Ydown, 600, Ydown); DDA(0, Yup, 600, Yup); CohenSutherland(x0, y0, x1, y1); |
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(0, 0);
glutInitWindowSize(768, 768);
glutCreateWindow("CohenSutherland");
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
endif
if 1
//liang-Barsky
include
include
include
using namespace std;
void init()
{
// 设置背景色为白色 不透明度为0
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 600, 0.0, 600);
glClear(GL_COLOR_BUFFER_BIT);
}
void DrawClippingWindow(double cd[])
{
glBegin(GL_LINE_LOOP);
glLineWidth(10);
for (int i = 0; i < 8; i = i + 2) {
glVertex2f(cd[i], cd[i + 1]);
}
glEnd();
}
void drawline(double cd[])
{
glBegin(GL_LINES);
glLineWidth(10);
for (int i = 0; i < 8; i = i + 2) {
glVertex2f(cd[i], cd[i + 1]);
}
glEnd();
}
void gl_Point(int x, int y)
{
glColor3f(1.0, 0.0, 0.0);
glPointSize(3.0f);
glBegin(GL_POINTS);
glVertex2f(x, y);
glEnd();
glFlush();
}
void DDA(int x1, int y1, int x2, int y2) {
int k, i;
float x, y, dx, dy;
k = abs(x2 - x1);
if (abs(y2 - y1) > k)
k = abs(y2 - y1);
//直线被划分为每一小段的长度
dx = float(x2 - x1) / k;
dy = float(y2 - y1) / k;
x = float(x1);
y = float(y1);
for (i = 0; i < k; i++) {
gl_Point(int(x + 0.5), int(y + 0.5));
x = x + dx;
y = y + dy;
}
}
int LBLineClipTest(float p, float q, float& umax, float& umin)
{
float r = 0.0;
1
| 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, i1, j1;
deltax = x2 - x1;
deltay = y2 - y1;
umax = 0.0;
umin = 1.0;
1
| 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)) { i1 = int(x1 + umax * deltax + 0.5); j1 = int(y1 + umax * deltay + 0.5); x2 = int(x1 + umin * deltax + 0.5); y2 = int(y1 + umin * deltay + 0.5); cout << i1 << " " << j1 << " " << x2 << " " << y2 << endl; } DDA(i1, j1, x2, y2); } } } |
}
void display()
{
double re[8] = { 200, 200, 400, 200, 400, 400, 200, 400 };
double line[4] = {50,100, 450, 500 };
1
| glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, 600, 600); glColor3f(0, 0, 0); DrawClippingWindow(re); drawline(line); LBLineClip(200, 400, 200, 400, 450, 500, 50, 100); glFlush(); |
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RED);
glutInitWindowSize(600, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("Liang-Barsky");
init();
glutDisplayFunc(display);
glutMainLoop();
}
endif