Thursday, May 7, 2009

C Program for Cohen Sutherland Line Clipping Algorithm

#include<stdio.h>
#include<graphics.h>
#include<conio.h>

typedef unsigned int outcode;
enum { TOP=0x1, BOTTOM=0x2, RIGHT=0x4, LEFT=0x8 };

void lineclip(x0,y0,x1,y1,xwmin,ywmin,xwmax,ywmax )
float x0,y0,x1,y1,xwmin,ywmin,xwmax,ywmax;
{

int gd,gm;
outcode code0,code1,codeout;
int accept = 0, done=0;

code0 = calcode(x0,y0,xwmin,ywmin,xwmax,ywmax);
code1 = calcode(x1,y1,xwmin,ywmin,xwmax,ywmax);

do{
if(!(code0 | code1))
{ accept =1 ; done =1; }
else
if(code0 & code1) done = 1;
else
{
float x,y;
codeout = code0 ? code0 : code1;
if(codeout & TOP)
{
x = x0 + (x1-x0)*(ywmax-y0)/(y1-y0);
y = ywmax;
}
else
if( codeout & BOTTOM)
{
x = x0 + (x1-x0)*(ywmin-y0)/(y1-y0);
y = ywmin;
}
else
if ( codeout & RIGHT)
{
y = y0+(y1-y0)*(xwmax-x0)/(x1-x0);
x = xwmax;
}
else
{
y = y0 + (y1-y0)*(xwmin-x0)/(x1-x0);
x = xwmin;
}
if( codeout == code0)
{
x0 = x; y0 = y;
code0=calcode(x0,y0,xwmin,ywmin,xwmax,ywmax);
}
else
{
x1 = x; y1 = y;
code1 = calcode(x1,y1,xwmin,ywmin,xwmax,ywmax);
}
}
} while( done == 0);

if(accept) line(x0,y0,x1,y1);

rectangle(xwmin,ywmin,xwmax,ywmax);

getch();

}


int calcode (x,y,xwmin,ywmin,xwmax,ywmax)
float x,y,xwmin,ywmin,xwmax,ywmax;
{
int code =0;

if(y> ywmax)
code |=TOP;
else if( y<ywmin)
code |= BOTTOM;
else if(x > xwmax)
code |= RIGHT;
else if ( x< xwmin)
code |= LEFT;

return(code);
}


main()
{

float x2,y2,x1,y1,xwmin,ywmin,xwmax,ywmax;
int gd=DETECT,gm;

clrscr();
initgraph(&gd,&gm,"e:\\tc\\bgi");

printf("\n\n\tEnter the co-ordinates of Line :");

printf("\n\n\tX1 Y1 : ");
scanf("%f %f",&x1,&y1);

printf("\n\n\tX2 Y2 : ");
scanf("%f %f",&x2,&y2);


printf("\n\tEnter the co_ordinates of window :\n ");
printf("\n\txwmin , ywmin : ");
scanf("%f %f",&xwmin,&ywmin);
printf("\n\txwmax , ywmax : ");
scanf("%f %f",&xwmax,&ywmax);
clrscr();
line(x1,y1,x2,y2);
rectangle(xwmin,ywmin,xwmax,ywmax);
getch();
clrscr();


lineclip(x1,y1,x2,y2,xwmin,ywmin,xwmax,ywmax );
getch();
closegraph();

}

26 comments:

Anonymous said...

thank you very much :-*

Angad said...

you're welcome !

William said...

hi.. is there a code for circle clipping with the use of Cohen Sutherland coding?

SRI said...

Thank u..

Angad said...

@ william,
Here is one way circle clipping can be done:
To clip a circle against a rectangle, we can first do a
trivial accept/reject test by intersecting the circle's extent (a square the size of the circle's diameter ) with the clip rectangle, using the algorithm for polygon clipping. If the circle intersects the rectangle, we divide it into quadrant and do the accept/reject test for each quadrant.This method can be used for eclipse too!

Angad said...

@ SRI,
you are welcome!

Ashish Rathore said...

thanx for the code......

Anonymous said...

u dont hv code for sutherman-hodgeman polygon clipping!!!!

:(

TRISHA said...

THANX A LOT

Strings said...

i spend ma whole day to solve this stuff....

this code really help me a lot...

thanx thanx alot.......

itz coool and gr8...

Strings said...

#include
#include
#include
#define left 0x1
#define right 0x2
#define bottom 0x4
#define top 0x8
int gen_code(int,int);
int WinMinX,WinMaxX,WinMinY,WinMaxY,n;
void line_check(int,int,int,int);
void draw_window();
void main()
{
int gd=DETECT,gm,i;
int x0,y0,x1,y1;
initgraph(&gd,&gm," ");
printf("\n\tRead value for clipping window Boundry ");
printf("\n\t************************************** ");
printf("\n\n\t Xwmin, Ywmin :");
scanf("%d%d",&WinMinX,&WinMinY);
printf("\n\t Xwmax, Ywmax :");
scanf("%d%d",&WinMaxX,&WinMaxY);
initgraph(&gd,&gm," ");
printf("\n\tEnter Line End points :");
printf("\n\t X0 , Y0 :");
scanf("%d %d",&x0,&y0);
printf("\n\t X1 , Y1 :");
scanf("%d %d",&x1,&y1);
initgraph(&gd,&gm," ");
line(x0,y0,x1,y1);
draw_window();
getch();
initgraph(&gd,&gm," ");
draw_window();
line_check(x0,y0,x1,y1);
getch();
}

int gen_code(int pnt_x,int pnt_y)
{
int i;
int code;
if(pnt_yWinMaxY)
code=bottom;
else if(pnt_xWinMaxX)
code=right;
else
code=0x0;
return code;
}

void line_check(int x0,int y0,int x1,int y1)
{
int code1,code2,outcode;
float x,y;
int done=1,draw;
while(done)
{
draw=0;
code1=gen_code(x0,y0);
code2=gen_code(x1,y1);
if(!(code1 | code2))
{
draw=1; done=0;
}
else if( code1 & code2 )
{
done=0; draw=0;
}
else
{
outcode=code1;
if(code1==0)
outcode=code2;
if(outcode & bottom )
{
x=x0+(x1-x0)*(WinMaxY-y0)/(y1-y0);
y=WinMaxY;
}

else if(outcode & top)
{
x=x0+(x1-x0)*(WinMinX-y0)/(y1-y0);
y=WinMinY;
}
else if(outcode & left )
{
y=y0+(y1-y0)*(WinMinX-x0)/(x1-x0);
x=WinMinX;
}
else
{
y=y0+(y1-y0)*(WinMaxX-x0)/(x1-x0);
x=WinMaxX;
}

if(outcode!=code1)
{
x1=x; y1=y;
}
else
{
x0=x; y0=y;
}
}
}
if(draw)
line(x0,y0,x1,y1);
return;

}
void draw_window()
{
setcolor(3);
setlinestyle(SOLID_LINE,1,1);
rectangle(WinMinX,WinMinY,WinMaxX,WinMaxY);
}

Strings said...

this is my version....:)

hey !!!!

Guys check it out...

Strings said...

#include
#include
#include
#define left 0x1
#define right 0x2
#define bottom 0x4
#define top 0x8
int gen_code(int,int);
int WinMinX,WinMaxX,WinMinY,WinMaxY,n;
void line_check(int,int,int,int);
void draw_window();
void main()
{
int gd=DETECT,gm,i;
int x0,y0,x1,y1;
initgraph(&gd,&gm," ");
printf("\n\tRead value for clipping window Boundry ");
printf("\n\t************************************** ");
printf("\n\n\t Xwmin, Ywmin :");
scanf("%d%d",&WinMinX,&WinMinY);
printf("\n\t Xwmax, Ywmax :");
scanf("%d%d",&WinMaxX,&WinMaxY);
initgraph(&gd,&gm," ");
printf("\n\tEnter Line End points :");
printf("\n\t X0 , Y0 :");
scanf("%d %d",&x0,&y0);
printf("\n\t X1 , Y1 :");
scanf("%d %d",&x1,&y1);
initgraph(&gd,&gm," ");
line(x0,y0,x1,y1);
draw_window();
getch();
initgraph(&gd,&gm," ");
draw_window();
line_check(x0,y0,x1,y1);
getch();
}

int gen_code(int pnt_x,int pnt_y)
{
int i;
int code;
if(pnt_yWinMaxY)
code=bottom;
else if(pnt_xWinMaxX)
code=right;
else
code=0x0;
return code;
}

void line_check(int x0,int y0,int x1,int y1)
{
int code1,code2,outcode;
float x,y;
int done=1,draw;
while(done)
{
draw=0;
code1=gen_code(x0,y0);
code2=gen_code(x1,y1);
if(!(code1 | code2))
{
draw=1; done=0;
}
else if( code1 & code2 )
{
done=0; draw=0;
}
else
{
outcode=code1;
if(code1==0)
outcode=code2;
if(outcode & bottom )
{
x=x0+(x1-x0)*(WinMaxY-y0)/(y1-y0);
y=WinMaxY;
}

else if(outcode & top)
{
x=x0+(x1-x0)*(WinMinX-y0)/(y1-y0);
y=WinMinY;
}
else if(outcode & left )
{
y=y0+(y1-y0)*(WinMinX-x0)/(x1-x0);
x=WinMinX;
}
else
{
y=y0+(y1-y0)*(WinMaxX-x0)/(x1-x0);
x=WinMaxX;
}

if(outcode!=code1)
{
x1=x; y1=y;
}
else
{
x0=x; y0=y;
}
}
}
if(draw)
line(x0,y0,x1,y1);
return;

}
void draw_window()
{
setcolor(3);
setlinestyle(SOLID_LINE,1,1);
rectangle(WinMinX,WinMinY,WinMaxX,WinMaxY);
}

Anonymous said...

Where have you given the color parameters in your code?

Anonymous said...

Great buddy you made my life simpler..

Angad said...

Turbo C has a 16-bit system to display colors, these colors have pre defined values which can initialized using the numbers 0-15. Using the statement 'setcolor(3)', I have specified the color parameters. I hope this helps......

tondralok said...

i found an error on the code that shows me on this line "void lineclip(x0,y0,x1,y1,xwmin,ywmin,xwmax,ywmax )"
and tells "style of function definition is now absolute".
pls tell me what can i for it ?

Anonymous said...

It's very good but much complex

Anonymous said...

thank you very much
Anas

Anonymous said...

chuttiya bana rha hey sala !! madarchod

Anonymous said...

bhaakk sale...

Nikki said...

thank a lot..:) its working

Anonymous said...

Hi, I think there is a problem in the code @

if(y> ywmax)
code |=TOP;
else if( y xwmax)
code |= RIGHT;
else if ( x< xwmin)
code |= LEFT;

what happens if the point-koords are bigger than ywmax, and bigger than xwmax?

Because of the "else if" the code wouldn't check for X-statements?

So I think, the X-statements should begin with a new "if" and not as a follow of the Y-statements.

right?

Anonymous said...

@tondralok

That error comes when u do not specify the data type of the parameters u passed in the funtion.

SO instead of "void lineclip(x0,y0,x1,y1,xwmin,ywmin,xwmax,ywmax)"

try
void lineclip(int x0,int y0,int x1,int y1,int xwmin,int ywmin,int xwmax,int ywmax)

Anonymous said...

oops its too late :-( sorry

Anonymous said...

watz the path that is specified in initgraph(&gd,&gm,"e:\\tc\\bgi");?????????