Search This Blog

C Program for Polygon Clipping by Another Polygon - Computer Graphics Lab Program

Polygon clipping is one of the classic problem in computer graphics lab. Generally, polygons or whatever objects, are clipped by a rectangular clipping windows. But, this one is a little more challenging graphics lab experiment in which we have to clip polygon with another polygon. That is the clipping windows is actually another polygon. The following c program implements polygon clipping with another polygon. The program clips any polygon with the clipping polygon, given both should be convex polygons.

#include<graphics.h>
#include<stdio.h>
int graDriver=DETECT,gramode;

int px[10];
int py[10];
int cx[10];
int cy[10];

int psize=4,csize=5;
float ta,tb,tc;
int insidex,insidey,meety,meetx;
int a[10],b[10],c[10];//equations for clipping polygon
int outx1[20],outy1[20],outx2[20],outy2[20],outcount1=0,outcount2=0,outswitcher=1,outcount;

void getEquation(int x1,int yy1,int x2, int y2)
{
if(y2==yy1)
 {
 ta=0;
 tb=1;
 tc=-yy1;
 }
else if(x2==x1)
 {
 ta=1;
 tb=0;
 tc=-x2;
 }
else
 {
 ta=y2-yy1;
 tb=x1-x2;
 tc=-tb*yy1-x1*ta;
 }
}

void addPoint2Output(int tx,int ty)
{
    if(outswitcher%2==1)
    {
        outx1[outcount1]=tx;
        outy1[outcount1++]=ty;
    }
    else
     {
     outx2[outcount2]=tx;
     outy2[outcount2++]=ty;
     }
}

int getXfromOut(int index)
{
    if(outswitcher%2==0)
        return outx1[index];
    else
        return outx2[index];
}

int getYfromOut(int index)
{
    if(outswitcher%2==0)
        return outy1[index];
    else
        return outy2[index];
}

void populateEquations()
{
int i;
for(i=0;i<csize;i++)
 {
 getEquation(cx[i],cy[i],cx[(i+1)%csize],cy[(i+1)%csize]);
 a[i]=ta;
 b[i]=tb;
 c[i]=tc;
 }
}


int isInsideEdge(int x,int y,int a,int b,int c)
{
int z,u;
z=a*insidex+b*insidey+c;
z=z/abs(z);
u=a*x+b*y+c;
if(u==0)
 return 1;
u=u/abs(u);
if(u==z)
    return 1;
else
    return 0;
}

//================
//GET AN INSIDE POINT
//================

void getApointInsideClipPoly()
{
int i=0,yi,xi,xsum=0,ysum=0;
for(i=0;i<csize;i++)
 {
 xsum+=cx[i];
 ysum+=cy[i];
 }
insidex=(int)xsum/csize;
insidey=(int)ysum/csize;
}

//================
//GETiNTERSECTION
//================

void getIntersection(a,b,c)//ta,tb,tc got as global
{
//getEquation() called from context
float mult;
if(ta!=0&&a!=0)
 {
 mult=(float)a/ta;
 meety=(tc*mult-c)/(b-tb*mult);
 meetx=-(b*meety+c)/a;
 }
else
 {
 mult=b/tb;
 meetx=(tc*mult-c)/(a-ta*mult);
 meety=-(a*meetx+c)/b;
 }
}

//================
//dRAW OUTPUT
//================

void draw()
{
int i;
initgraph(&graDriver,&gramode,"C:\\TC\\BGI");
setcolor(GREEN);
if(outcount1!=0)
    {
    for(i=0;i<outcount1;i++)
 line(outx1[i],outy1[i],outx1[(i+1)%outcount1],outy1[(i+1)%outcount1]);
    }
else
    {
    for(i=0;i<outcount2;i++)
 line(outx2[i],outy2[i],outx2[(i+1)%outcount2],outy2[(i+1)%outcount2]);
    }
setcolor(RED);
for(i=0;i<csize;i++)
 line(cx[i],cy[i],cx[(i+1)%csize],cy[(i+1)%csize]);
getch();

closegraph();
}

//================
//RAW DRAW
//================
void rawdraw()
{
int i;
initgraph(&graDriver,&gramode,"C:\\TC\\BGI");
setcolor(RED);
for(i=0;i<csize;i++)
 line(cx[i],cy[i],cx[(i+1)%csize],cy[(i+1)%csize]);
setcolor(GREEN);
for(i=0;i<psize;i++)
 line(px[i],py[i],px[(i+1)%psize],py[(i+1)%psize]);
putpixel(insidex,insidey,YELLOW);
}

//================
//MAIN
//================

int main()
{
int i,j,x1,yy1,x2,y2,i1,i2,temp;
printf("\nEnter no of points of polygon");
scanf("%d",&psize);
printf("\nEnter points of polygon");
for(i=0;i<psize;i++)
 {
 scanf("%d%d",&px[i],&py[i]);
 }
printf("\nEnter no of points of clipping polygon");
scanf("%d",&csize);
printf("\nEnter points of clipping polygon");
for(i=0;i<csize;i++)
 {
 scanf("%d%d",&cx[i],&cy[i]);
 }
populateEquations();

getApointInsideClipPoly();
printf("\nbefore clipping");
rawdraw();
delay(5000);
closegraph();
//copying polygon points to outx2,outy2
for(i=0;i<psize;i++)
    {
     outx2[i]=px[i];
     outy2[i]=py[i];
    }
outcount2=psize;
outcount=outcount2;
for(i=0;i<csize;i++)//clipping line
    {
    printf("\nCheck against clip edge:(%d,%d)>(%d,%d):%dx+%dy+%d=0",cx[i],cy[i],cx[(i+1)%csize],cy[(i+1)%csize],a[i],b[i],c[i]);
    getch();
    for(j=0;j<outcount;j++)//clipped line
 {
 x1=getXfromOut(j);//outx[i];
 yy1=getYfromOut(j);//outy[i];
 x2=getXfromOut((j+1)%outcount);//outx[(i+1)%outcount];
 y2=getYfromOut((j+1)%outcount);//outy[(i+1)%outcount];
 i1=isInsideEdge(x1,yy1,a[i],b[i],c[i]);
 i2=isInsideEdge(x2,y2,a[i],b[i],c[i]);
 if(i1==1&&i2==1)
     {
     addPoint2Output(x2,y2);
     }
 else if(i1==1&&i2==0)
     {
            getEquation(x1,yy1,x2,y2);    
     getIntersection(a[i],b[i],c[i]);
     addPoint2Output(meetx,meety);
     }
 else if(i1==0&&i2==1)
     {
     getEquation(x1,yy1,x2,y2);
     getIntersection(a[i],b[i],c[i]);

     addPoint2Output(meetx,meety);
     addPoint2Output(x2,y2);
     }
 }
    outswitcher++;
    outcount=(outswitcher%2==1)?outcount2:outcount1;
    if(outswitcher%2==1)
 outcount1=0;
    else
 outcount2=0;
    }
draw();
getch();
return 0;
}

No comments: