Program:
// Sutherland Hodgman Polygon Clipping Complete Code | implementation through openGL #include <stdio.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #include <math.h> typedef struct // structure that holds the information of points { float x; float y; } PT; // global variables int n; int i, j; PT p1, p2, p[20], pp[20]; void left() // left clipper { i = 0; j = 0; for (i = 0; i < n; i++) { if (p[i].x < p1.x && p[i + 1].x >= p1.x) //Case-1: outside to inside { if (p[i + 1].x - p[i].x != 0) { pp[j].y = (p[i + 1].y - p[i].y) / (p[i + 1].x - p[i].x) * (p1.x - p[i].x) + p[i].y; // save point of intersection } else { pp[j].y = p[i].y; } pp[j].x = p1.x; j++; pp[j].x = p[i + 1].x; // save that point that lie inside our clipping window // consult theory pp[j].y = p[i + 1].y; j++; } if (p[i].x >= p1.x && p[i + 1].x >= p1.x) //Case-2: inside to inside { pp[j].y = p[i + 1].y; // only save second point that lie inside our clipping window // consult theory pp[j].x = p[i + 1].x; j++; } if (p[i].x >= p1.x && p[i + 1].x < p1.x) // Case-3: inside to outside { if (p[i + 1].x - p[i].x != 0) { pp[j].y = (p[i + 1].y - p[i].y) / (p[i + 1].x - p[i].x) * (p1.x - p[i].x) + p[i].y; // only save point of intersection } else { pp[j].y = p[i].y; } pp[j].x = p1.x; j++; } } for (i = 0; i < j; i++) { p[i].x = pp[i].x; p[i].y = pp[i].y; } p[i].x = pp[0].x; p[i].y = pp[0].y; n = j; } void right() // right clipper { i = 0; j = 0; for (i = 0; i < n; i++) { if (p[i].x > p2.x && p[i + 1].x <= p2.x) //Case-1: outside to inside { if (p[i + 1].x - p[i].x != 0) { pp[j].y = (p[i + 1].y - p[i].y) / (p[i + 1].x - p[i].x) * (p2.x - p[i].x) + p[i].y; // save point of intersection } else { pp[j].y = p[i].y; } pp[j].x = p2.x; j++; pp[j].x = p[i + 1].x; // save that point that lie inside our clipping window // consult theory pp[j].y = p[i + 1].y; j++; } if (p[i].x <= p2.x && p[i + 1].x <= p2.x) // Case-2: inside to inside { pp[j].y = p[i + 1].y; // only save second point that lie inside our clipping window // consult theory pp[j].x = p[i + 1].x; j++; } if (p[i].x <= p2.x && p[i + 1].x > p2.x) // Case-3: inside to outside { if (p[i + 1].x - p[i].x != 0) { pp[j].y = (p[i + 1].y - p[i].y) / (p[i + 1].x - p[i].x) * (p2.x - p[i].x) + p[i].y; // only save point of intersection } else { pp[j].y = p[i].y; } pp[j].x = p2.x; j++; } } for (i = 0; i < j; i++) { p[i].x = pp[i].x; p[i].y = pp[i].y; } p[i].x = pp[0].x; p[i].y = pp[0].y; } void top() // top clipper { i = 0; j = 0; for (i = 0; i < n; i++) { if (p[i].y > p2.y && p[i + 1].y <= p2.y) //Case-1: outside to inside { if (p[i + 1].y - p[i].y != 0) { pp[j].x = (p[i + 1].x - p[i].x) / (p[i + 1].y - p[i].y) * (p2.y - p[i].y) + p[i].x; // save point of intersection } else { pp[j].x = p[i].x; } pp[j].y = p2.y; j++; pp[j].x = p[i + 1].x; // save that point that lie inside our clipping window // consult theory pp[j].y = p[i + 1].y; j++; } if (p[i].y <= p2.y && p[i + 1].y <= p2.y) // Case-2: inside to inside { pp[j].y = p[i + 1].y; // only save second point that lie inside our clipping window // consult theory pp[j].x = p[i + 1].x; j++; } if (p[i].y <= p2.y && p[i + 1].y > p2.y) // Case-3: inside to outside { if (p[i + 1].y - p[i].y != 0) { pp[j].x = (p[i + 1].x - p[i].x) / (p[i + 1].y - p[i].y) * (p2.y - p[i].y) + p[i].x; // only save point of intersection } else { pp[j].x = p[i].x; } pp[j].y = p2.y; j++; } } for (i = 0; i < j; i++) { p[i].x = pp[i].x; p[i].y = pp[i].y; } p[i].x = pp[0].x; p[i].y = pp[0].y; n = j; } void bottom() // bottom clipper { i = 0; j = 0; for (i = 0; i < n; i++) { if (p[i].y < p1.y && p[i + 1].y >= p1.y) // Case-1: outside to inside { if (p[i + 1].y - p[i].y != 0) { pp[j].x = (p[i + 1].x - p[i].x) / (p[i + 1].y - p[i].y) * (p1.y - p[i].y) + p[i].x; // save point of intersection } else { pp[j].x = p[i].x; } pp[j].y = p1.y; j++; pp[j].x = p[i + 1].x; // save that point that lie inside our clipping window // consult theory pp[j].y = p[i + 1].y; j++; } if (p[i].y >= p1.y && p[i + 1].y >= p1.y) // Case-2: inside to inside { pp[j].x = p[i + 1].x; // only save second point that lie inside our clipping window // consult theory pp[j].y = p[i + 1].y; j++; } if (p[i].y >= p1.y && p[i + 1].y < p1.y) // Case-3: inside to outside { if (p[i + 1].y - p[i].y != 0) { pp[j].x = (p[i + 1].x - p[i].x) / (p[i + 1].y - p[i].y) * (p1.y - p[i].y) + p[i].x; // only save point of intersection } else { pp[j].x = p[i].x; } pp[j].y = p1.y; j++; } } for (i = 0; i < j; i++) { p[i].x = pp[i].x; p[i].y = pp[i].y; } p[i].x = pp[0].x; p[i].y = pp[0].y; n = j; } void drawpolygon() { glColor3f(1.0, 0.0, 0.0); for (i = 0; i < n - 1; i++) { glBegin(GL_LINES); glVertex2d(p[i].x, p[i].y); glVertex2d(p[i + 1].x, p[i + 1].y); glEnd(); } glBegin(GL_LINES); glVertex2d(p[i].x, p[i].y); glVertex2d(p[0].x, p[0].y); glEnd(); } void myMouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) // On output, please left click on polygon then and only then clipping performs { glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_LINE_LOOP); glVertex2f(p1.x, p1.y); glVertex2f(p2.x, p1.y); glVertex2f(p2.x, p2.y); glVertex2f(p1.x, p2.y); glEnd(); left(); right(); top(); bottom(); drawpolygon(); } glFlush(); } void display(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.4, 1.0, 0.0); glBegin(GL_LINE_LOOP); glVertex2f(p1.x, p1.y); glVertex2f(p2.x, p1.y); glVertex2f(p2.x, p2.y); glVertex2f(p1.x, p2.y); glEnd(); drawpolygon(); glFlush(); } void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); // clear screen usually black gluOrtho2D(0, 500, 0, 500); } int main(int argc, char **argv) { printf("Enter Window Coordinates:\n"); printf("Please Enter two Points:\n"); // P1(x,y) is the bottom left point for clipping window printf("Enter P1(x,y):\n"); scanf("%f", &p1.x); // if you don't know what value should be given: enter 200 scanf("%f", &p1.y); // if you don't know what value should be given: enter 200 printf("Enter P2(x,y):\n"); // P2(x,y) is the top right point for clipping window scanf("%f", &p2.x); // if you don't know what value should be given: enter 400 scanf("%f", &p2.y); // if you don't know what value should be given: enter 400 printf("\nEnter the no. of vertices:"); // if you don't know what value should be given: enter 3 scanf("%d", &n); for (i = 0; i < n; i++) { printf("\nEnter V%d(x%d,y%d):\n", i + 1, i + 1, i + 1); scanf("%f", &p[i].x); // if you don't know what value should be given: enter V1(100,110), V2(340,210), V3(300,380) scanf("%f", &p[i].y); } p[i].x = p[0].x; // Assign last to first for connected everything p[i].y = p[0].y; glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(640, 480); glutInitWindowPosition(0, 0); glutCreateWindow("Sutherland Hodgman Polygon Clipping Algorithm "); init(); glutDisplayFunc(display); glutMouseFunc(myMouse); // notice mouse movement and call user defined function glFlush(); glutMainLoop(); return 0; }Output:
Before Clip: