Skip to content

Instantly share code, notes, and snippets.

@moonblade
Created March 8, 2017 15:06
Show Gist options
  • Save moonblade/bc2d6bafb7352283b0827230d4cba4d3 to your computer and use it in GitHub Desktop.
Save moonblade/bc2d6bafb7352283b0827230d4cba4d3 to your computer and use it in GitHub Desktop.
// polygon Clipping using Sutherland-Hodgeman Algorithm
#include <GL/glut.h>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <list>
using namespace std;
float xmin=220;
float ymin=220;
float xmax=420;
float ymax=420;
const int TOP = 8, BOTTOM = 4, LEFT = 2, RIGHT = 1;
class Point
{
public:
float x;
float y;
Point();
Point(float x1, float y1){
x=x1;
y=y1;
}
};
std::list<Point> subjectPolygon ;
void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0,0.0);
glBegin(GL_POLYGON);
for (Point point : subjectPolygon)
glVertex2i(point.x,point.y);
glEnd();
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINE_LOOP);
glVertex2i(xmin,ymin);
glVertex2i(xmin,ymax);
glVertex2i(xmax,ymax);
glVertex2i(xmax,ymin);
glEnd();
glFlush();
}
// outputList.clear();
// Point S = inputList.last;
// for (Point E in inputList) do
// if () then
// if () then
// outputList.add(ComputeIntersection(S,E,clipEdge));
// end if
// outputList.add(E);
// else if (S inside clipEdge) then
// outputList.add(ComputeIntersection(S,E,clipEdge));
// end if
// S = E;
// done
Point computeIntersection(Point S,Point E, int clipEdge){
float m1 = (E.y-S.y)/(E.x-S.x);
float b1, x, y;
// float x1,y1,x2,y2;
switch(clipEdge){
case LEFT:
if(m1==0)
return Point(xmin, E.y);
b1 = E.y - m1*E.x;
y = m1*xmin + b1;
return Point(xmin, y);
break;
case TOP:
if((E.x-S.x) == 0)
return Point(E.x, ymax);
b1 = E.y - m1*E.x;
x = (ymax - b1)/m1 ;
return Point(x, ymax);
break;
case RIGHT:
if(m1==0)
return Point(xmax, E.y);
b1 = E.y - m1*E.x;
y = m1*xmax + b1;
return Point(xmax, y);
break;
case BOTTOM:
if((E.x-S.x) == 0)
return Point(E.x, ymin);
b1 = E.y - m1*E.x;
x = (ymin - b1)/m1 ;
return Point(x, ymin);
break;
}
// float m2=(y2-y1)/(x2-x1);
// cout<<"slopes : "<<m1 <<" "<<m2<<endl;
// float b2 = y2 - m2*x2;
// float intersectionX = (b2-b1)/(m1-m2);
// float intersectionY = m1*intersectionX + b1;
// cout<<"X Y intersection : "<< intersectionX <<" "<<intersectionY<<endl;
// return Point(intersectionX, intersectionY);
}
list<Point> clipLeft(list<Point> outputList){
list<Point> inputList = outputList;
outputList.clear();
Point S = inputList.back();
for(Point E : inputList){
//E inside clipEdge
if(E.x>xmin){
// S not inside clipEdge
if(S.x < xmin)
outputList.push_back(computeIntersection(S,E,LEFT));
outputList.push_back(E);
}
// S inside clipEdge
else if(S.x > xmin)
outputList.push_back(computeIntersection(S,E,LEFT));
S = E;
}
return outputList;
}
list<Point> clipRight(list<Point> outputList){
list<Point> inputList = outputList;
outputList.clear();
Point S = inputList.back();
for(Point E : inputList){
//E inside clipEdge
if(E.x<xmax){
// S not inside clipEdge
if(S.x > xmax)
outputList.push_back(computeIntersection(S,E,RIGHT));
outputList.push_back(E);
}
// S inside clipEdge
else if(S.x < xmax)
outputList.push_back(computeIntersection(S,E,RIGHT));
S = E;
}
return outputList;
}
list<Point> clipTop(list<Point> outputList){
list<Point> inputList = outputList;
outputList.clear();
Point S = inputList.back();
for(Point E : inputList){
//E inside clipEdge
if(E.y<ymax){
// S not inside clipEdge
if(S.y > ymax)
outputList.push_back(computeIntersection(S,E,TOP));
outputList.push_back(E);
}
// S inside clipEdge
else if(S.y < ymax)
outputList.push_back(computeIntersection(S,E,TOP));
S = E;
}
return outputList;
}
list<Point> clipBottom(list<Point> outputList){
list<Point> inputList = outputList;
outputList.clear();
Point S = inputList.back();
for(Point E : inputList){
//E inside clipEdge
if(E.y>ymin){
// S not inside clipEdge
if(S.y < ymin)
outputList.push_back(computeIntersection(S,E,TOP));
outputList.push_back(E);
}
// S inside clipEdge
else if(S.y > ymin)
outputList.push_back(computeIntersection(S,E,TOP));
S = E;
}
return outputList;
}
// fro debugging
void print(list<Point> outputList){
for(Point E : outputList){
cout<< E.x <<" "<<E.y<<endl;
}
}
void initializePolygon(){
// polygon to be clipped
subjectPolygon.push_back(Point(100,100));
subjectPolygon.push_back(Point(100,300));
subjectPolygon.push_back(Point(400,300));
subjectPolygon.push_back(Point(600,150));
subjectPolygon.push_back(Point(400,100));
}
void sutherland_Hodgeman()
{
// glutDisplayFunc(display);
std::list<Point> outputList = subjectPolygon;
outputList = clipLeft(outputList);
// print(outputList);
// outputList = clipTop(outputList);
outputList = clipRight(outputList);
// print(outputList);
// outputList = clipBottom(outputList);
subjectPolygon = outputList;
display();
}
void mykey(unsigned char key,int x,int y)
{
if(key=='c')
{ cout<<"Hello";
sutherland_Hodgeman();
glFlush();
}
}
void init(void) {
glClearColor(0,0,0,0);
glColor3f(1.0f,0.0f,0.0f);
glPointSize(4.0);
glMatrixMode(GL_PROJECTION);
glutDisplayFunc(display);
glutKeyboardFunc(mykey);
glLoadIdentity();
gluOrtho2D(0 , 640 , 0 , 640);
}
int main(int argc,char * argv[]) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(800,600);
glutInitWindowPosition(100,100);
glutCreateWindow("Sutherland Hodgeman Polygon Clipping");
//initialise polygon coordinates
initializePolygon();
init();
// sutherland_Hodgeman();
// glutKeyboardFunc(mykey);
glutMainLoop();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment