Tuesday, December 30, 2008

Cohonen Sutherland Line Clipping

#include<iostream.h>
#include<graphics.h>
#include<conio.h>
#define TRUE 1
#define FALSE 0

typedef unsigned int outcode;
typedef unsigned char boolean;
struct point
{
 double x,y;
};
struct line
{
 struct point p1,p2;
};
enum{TOP = 0x1,BOTTOM = 0x2,RIGHT = 0x4,LEFT = 0x8};
outcode Compoutcode(double x, double y, double xmin, double xmax, double ymin, double ymax)
{
 outcode code = 0;
 if(y > ymax)
  code|=TOP;
 else
  if(y < ymin)
   code|=BOTTOM;
 if(x>xmax)
  code|=RIGHT;
 else
  if(x<xmin)
   code|=LEFT;
 return code;
}
void LineClipAndDraw(double x0,double y0,double x1,double y1,double xmin,double xmax,double ymin,double ymax)
{
 outcode outcode0,outcode1,outcodeOut;
 boolean accept = TRUE,done = FALSE;
 outcode0 = Compoutcode(x0,y0,xmin,xmax,ymin,ymax);
 outcode1 = Compoutcode(x1,y1,xmin,xmax,ymin,ymax);
 do
 {
  if(!(outcode0|outcode1))
  {
   accept = TRUE;
   done = TRUE;
  }
  else
   if(outcode0 & outcode1)
   {
    done = TRUE;
    accept = FALSE;
   }
   else
   {
    double x,y;
    outcodeOut = outcode0?outcode0:outcode1;
    if(outcodeOut&TOP)
    {
     x = x0+(x1-x0)*(ymax-y0)/(y1-y0);
     y = ymax;
    }
    else
     if(outcodeOut & BOTTOM)
     {
      x = x0 + (x1-x0)*(ymin-y0)/(y1-y0);
      y = ymin;
     }
     else
      if(outcodeOut & RIGHT)
      {
       y = y0 + (y1-y0)*(xmax-x0)/(x1-x0);
       x = xmax;
      }
      else
      {
       y = y0 + (y1 - y0)*(xmin - x0)/(x1-x0);
       x = xmin;
      }
      if(outcodeOut == outcode0)
      {
       x0 = x;
       y0 = y;
       outcode0 = Compoutcode(x0,y0,xmin,xmax,ymin,ymax);
      }
      else
      {
       x1 = x;
       y1 = y;
       outcode1 = Compoutcode(x1,y1,xmin,xmax,ymin,ymax);
      }
   }
 }while(done == FALSE);
 if(accept)
  line(x0,y0,x1,y1);
}

void main()
{
 int gmode = DETECT,gdriver;
 struct line lines[10];
 int n;
 double xmin,xmax;
 double ymin,ymax;
 double xscale,yscale;
 int i;
 initgraph(&gmode,&gdriver,"c:/tc/bgi");
 cout << "Enter the number of lines: ";
 cin >> n;
 cout << "Enter the endpoints of the lines: " << endl;
 for(i=0;i<n;i++)
 {
  cout <<"line "<< i+1 << ":\n";
  cout << "x1 : ";
  cin >> lines[i].p1.x;
  cout << "y1 : ";
  cin >> lines[i].p1.y;
  cout << "x2 : ";
  cin >> lines[i].p2.x;
  cout << "y2 : ";
  cin >> lines[i].p2.y;
  cout << endl;
 }
 cout << "Enter the Top Left of the clip window: "<< endl;
 cout << "X Axis : ";
 cin >> xmin;
 cout << "Y Axis : ";
 cin >> ymin;
 cout << "Enter the Bottom Right of the clip window: "<< endl;
 cout << "X axis : ";
 cin >> xmax;
 cout << "Y axis : ";
 cin >> ymax;
 cleardevice();
 for(i =0;i<n;i++)
  line(lines[i].p1.x,lines[i].p1.y,lines[i].p2.x,lines[i].p2.y);
 rectangle(xmin,ymin,xmax,ymax);
 getch();
 cleardevice();
 rectangle(xmin,ymin,xmax,ymax);
 for(i =0;i<n;i++)
  LineClipAndDraw(lines[i].p1.x, lines[i].p1.y, lines[i].p2.x, lines[i].p2.y, xmin, xmax, ymin, ymax);
 getch();
 closegraph();
}

No comments: