/*cohen sutherland algorithm*/
#include <iostream.h>
#include <graphics.h>
#include <conio.h>
#include <math.h>
const int clip_line(const WindowCoordinates,l_coords&);
void calculate_intersecting_points(const WindowCoordinates,l_coords&);
void Rectangle(const int,const int,const int,const int);
void Line(const int,const int,const int,const int);
class l_coords
{
public:
float x1;
float y1;
float x2;
float y2;
l_coords(const float sx,const float sy,const float ex,const float ey)
{
x1=sx;
y1=sy;
x2=ex;
y2=ey;
}
};
class WindowCoordinates
{
public:
float xmin;
float ymin;
float xmax;
float ymax;
WindowCoordinates(const float sx,const float sy,const float ex,const float ey)
{
xmin=sx;
ymin=sy;
xmax=ex;
ymax=ey;
}
};
class RegionCode
{
public:
int bit1;
int bit2;
int bit3;
int bit4;
RegionCode( )
{
bit1=0;
bit2=0;
bit3=0;
bit4=0;
}
const int equal_zero( )
{
if(bit1==0 && bit2==0 && bit3==0 && bit4==0)
return 1;
return 0;
}
void get_logical_AND(RegionCode rc1,RegionCode rc2)
{
if(rc1.bit1==1 && rc2.bit1==1)
bit1=1;
if(rc1.bit2==1 && rc2.bit2==1)
bit2=1;
if(rc1.bit3==1 && rc2.bit3==1)
bit3=1;
if(rc1.bit4==1 && rc2.bit4==1)
bit4=1;
}
void get_region_code(const WindowCoordinates wc,const int x,const int y)
{
if((wc.xmin-x)>0)
bit1=1;
if((x-wc.xmax)>0)
bit2=1;
if((wc.ymin-y)>0)
bit3=1;
if((y-wc.ymax)>0)
bit4=1;
}
};
int main( )
{
int driver=VGA;
int mode=VGAHI;
initgraph(&driver,&mode,"..\\Bgi");
cout<<"Press c to view clipped lines"<<endl;
WindowCoordinates WC(180,140,470,340);
setcolor(15);
Rectangle(WC.xmin,WC.ymin,WC.xmax,WC.ymax);
l_coords lc1(150,160,120,320);
l_coords lc2(250,150,200,200);
l_coords lc3(160,200,490,260);
l_coords lc4(300,300,400,380);
l_coords lc5(550,300,450,400);
l_coords lc6(440,110,400,370);
setcolor(7);
Line(lc1.x1,lc1.y1,lc1.x2,lc1.y2);
Line(lc2.x1,lc2.y1,lc2.x2,lc2.y2);
Line(lc3.x1,lc3.y1,lc3.x2,lc3.y2);
Line(lc4.x1,lc4.y1,lc4.x2,lc4.y2);
Line(lc5.x1,lc5.y1,lc5.x2,lc5.y2);
Line(lc6.x1,lc6.y1,lc6.x2,lc6.y2);
char Key=NULL;
do
{
Key=getch( );
}
while(Key!='C' && Key!='c');
settextstyle(0,0,1);
setcolor(0);
outtextxy(163,450," Press 'C' to see Clipped Lines ");
setcolor(15);
outtextxy(165,450,"------ -------");
setcolor(12);
outtextxy(213,450," Press any Key to exit. ");
setcolor(10);
if(clip_line(WC,lc1))
Line(lc1.x1,lc1.y1,lc1.x2,lc1.y2);
if(clip_line(WC,lc2))
Line(lc2.x1,lc2.y1,lc2.x2,lc2.y2);
if(clip_line(WC,lc3))
Line(lc3.x1,lc3.y1,lc3.x2,lc3.y2);
if(clip_line(WC,lc4))
Line(lc4.x1,lc4.y1,lc4.x2,lc4.y2);
if(clip_line(WC,lc5))
Line(lc5.x1,lc5.y1,lc5.x2,lc5.y2);
if(clip_line(WC,lc6))
Line(lc6.x1,lc6.y1,lc6.x2,lc6.y2);
getch( );
return 0;
}
const int clip_line(const WindowCoordinates wc,l_coords &lc)
{
RegionCode rc1,rc2,rc;
rc1.get_region_code(wc,lc.x1,lc.y1);
rc2.get_region_code(wc,lc.x2,lc.y2);
rc.get_logical_AND(rc1,rc2);
if(rc1.equal_zero( ) && rc2.equal_zero( ))
{
lc.x1=(int)(lc.x1+0.5);
lc.y1=(int)(lc.y1+0.5);
lc.x2=(int)(lc.x2+0.5);
lc.y2=(int)(lc.y2+0.5);
return 1;
}
else if(!rc.equal_zero( ))
return 0;
else
{
calculate_intersecting_points(wc,lc);
clip_line(wc,lc);
}
return 1;
}
void calculate_intersecting_points(const WindowCoordinates wc,l_coords &lc)
{
RegionCode rc1,rc2,rc;
rc1.get_region_code(wc,lc.x1,lc.y1);
rc2.get_region_code(wc,lc.x2,lc.y2);
if(!rc1.equal_zero( ))
{
float m;
float x=lc.x1;
float y=lc.y1;
int dx=(lc.x2-lc.x1);
if(dx!=0)
m=((lc.y2-lc.y1)/(lc.x2-lc.x1));
if(rc1.bit1==1)
{
x=wc.xmin;
y=(lc.y1+(m*(x-lc.x1)));
}
else if(rc1.bit2==1)
{
x=wc.xmax;
y=(lc.y1+(m*(x-lc.x1)));
}
else if(rc1.bit3==1)
{
y=wc.ymin;
if(dx!=0)
x=(lc.x1+((y-lc.y1)/m));
}
else if(rc1.bit4==1)
{
y=wc.ymax;
if(dx!=0)
x=(lc.x1+((y-lc.y1)/m));
}
lc.x1=x;
lc.y1=y;
}
if(!rc2.equal_zero( ))
{
float m;
float x=lc.x2;
float y=lc.y2;
int dx=(lc.x2-lc.x1);
if(dx!=0)
m=((lc.y2-lc.y1)/(lc.x2-lc.x1));
if(rc2.bit1==1)
{
x=wc.xmin;
y=(lc.y2+(m*(x-lc.x2)));
}
else if(rc2.bit2==1)
{
x=wc.xmax;
y=(lc.y2+(m*(x-lc.x2)));
}
else if(rc2.bit3==1)
{
y=wc.ymin;
if(dx!=0)
x=(lc.x2+((y-lc.y2)/m));
}
else if(rc2.bit4==1)
{
y=wc.ymax;
if(dx!=0)
x=(lc.x2+((wc.ymax-lc.y2)/m));
}
lc.x2=x;
lc.y2=y;
}
}
void Rectangle(const int x1,const int y1,const int x2,const int y2)
{
Line(x1,y1,x2,y1);
Line(x2,y1,x2,y2);
Line(x2,y2,x1,y2);
Line(x1,y2,x1,y1);
}
void Line(const int x1,const int y1,const int x2,const int y2)
{
int color=getcolor( );
int sx=x1;
int sy=y1;
int ex=x2;
int ey=y2;
if(x1>x2)
{
sx=x2;
sy=y2;
ex=x1;
ey=y1;
}
int dx=abs(ex-sx);
int dy=abs(ey-sy);
int inc_dec=((ey>=sy)?1:-1);
if(dx>dy)
{
int two_dy=(2*dy);
int two_dy_dx=(2*(dy-dx));
int p=((2*dy)-dx);
int x=sx;
int y=sy;
putpixel(x,y,color);
while(x<ex)
{
x++;
if(p<0)
p+=two_dy;
else
{
y+=inc_dec;
p+=two_dy_dx;
}
putpixel(x,y,color);
}
}
else
{
int two_dx=(2*dx);
int two_dx_dy=(2*(dx-dy));
int p=((2*dx)-dy);
int x=sx;
int y=sy;
putpixel(x,y,color);
while(y!=ey)
{
y+=inc_dec;
if(p<0)
p+=two_dx;
else
{
x++;
p+=two_dx_dy;
}
putpixel(x,y,color);
}
}
}