Cohen-Sutherland & Liang-Barsky直线裁剪算法

两个直线裁剪算法的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 &lt; 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 &lt; umax)         return 0;     else if (r &lt; umin)         umin = r; } else if (q &lt; 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 &lt;&lt; i1 &lt;&lt; " " &lt;&lt; j1 &lt;&lt; " " &lt;&lt; x2 &lt;&lt; " " &lt;&lt; y2 &lt;&lt; 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();
1
return 0;
} endif
上一篇
下一篇

鄂公网安备 42082102000192号