Click here to Skip to main content
15,914,221 members
Please Sign up or sign in to vote.
1.40/5 (5 votes)
See more:
c++ code for line clipping
a window clips lines

C++
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#include<graphics.h>
#include<stdlib.h>
typedef struct coord
{
int x,y;
char code[4];
}PT;
void drawwindow();
void drawline(PT p1,PT p2,int c1);
PT setcode(PT p);
int visibility(PT p1,PT p2);
PT resetendpt(PT p1,PT p2);
void main()
{
int gd=DETECT,gm,v;
PT p1,p2,ptemp;
initgraph(&gd,&gm,"");
cleardevice();
printf("\t\tCOHEN-SUTHERLAND LINE CLIPPING ALGORITHM");
printf("\nEnter the two end points p1(x,y)");
scanf("%d%d",&p1.x,&p1.y);
printf("Enter the two end points p2(x,y):");
scanf("%d%d",&p2.x,&p2.y);
cleardevice();
printf("\t\tCLIPPING WINDOW");
drawwindow();
getch();
printf("\tCOHEN-SUTHERLAND LINE CLIPPING ALGORITHM");
printf("\n\t\tBEFORE CLIPPING");
drawline(p1,p2,4);
getch();
p1=setcode(p1);
p2=setcode(p2);
v=visibility(p1,p2);
switch(v)
{
  case 0:
   cleardevice();
   //printf("\t\tCLIPPING WINDOW");
   drawwindow();
   drawline(p1,p2,15);
  break;
 case 1:
   cleardevice();
   drawwindow();
  break;
  case 2:
   cleardevice();
   p1=resetendpt(p1,p2);
   p2=resetendpt(p2,p1);
   drawwindow();
   printf("\tCOHEN-SUTHERLAND LINE CLIPPING ALGORITHM");
   printf("\n\t\tAFTER CLIPPING");
   drawline(p1,p2,15);
  break;
 }
 getch();
 closegraph();
//return(0);
}
void drawwindow()
{
 setcolor(RED);
 setlinestyle(DOTTED_LINE, 1, 1);
 line(150,100,100,100);
 line(150,100,150,50);
 line(450,100,500,100);
 line(450,100,450,50);
 line(450,350,500,350);
 line(450,350,450,400);
 line(150,350,150,400);
 line(150,350,100,350) ;
 line(150,100,100,100);
 line(150,100,150,50);
 setlinestyle(SOLID_LINE, 1, 1);
 line(150,100,450,100);
 line(450,100,450,350);
 line(450,350,150,350);
 line(150,350,150,100);
 
 outtextxy(450,30,"1001");
 outtextxy(470,200,"1000");
 outtextxy(470,370,"1010");
 outtextxy(300,370,"0010");
 outtextxy(120,370,"0110");
 outtextxy(120,200,"0100");
 outtextxy(120,30,"0101");
 outtextxy(300,30,"0001");
 outtextxy(300,200,"0000");
}
void drawline(PT p1,PT p2,int c1)
{
 setcolor(c1);
 line(p1.x,p1.y,p2.x,p2.y);
}
 
PT setcode(PT p)
{
 PT ptemp;
 if(p.y<100)
  ptemp.code[0]='1';
 else
  ptemp.code[0]='0';
 if(p.y>350)
  ptemp.code[1]='1';
 else
  ptemp.code[1]='0';
 if(p.x>200)
  ptemp.code[2]='1';
 else
  ptemp.code[2]='0';
 if(p.x<150)
  ptemp.code[3]='1';
 else
  ptemp.code[3]='0';
  ptemp.x=p.x;
  ptemp.y=p.y;
 return(ptemp);
}
int visibility(PT p1,PT p2)
{
 int i,flag=0;
 for(i=0;i<4;i++)
 {
  if((p1.code[i]!='0')||(p2.code[i]!='0'))
  flag=1;
 }
 if(flag==0)
 return(0);
 for(i=0;i<4;i++)
 {
  if((p1.code[i]==p2.code[i])&&(p1.code[i]=='1'))
  flag=0;
 }
 if(flag==0)
 return(1);
 return(2);
}
PT resetendpt(PT p1,PT p2)
{
 PT temp;
 int x,y,i;
 float m,k;
 if(p1.code[3]=='1')
 x=150;
 if(p1.code[2]=='1')
 x=450;
 if((p1.code[3]=='1')||(p1.code[2]=='1'))
 {
  m=(float)(p2.y-p1.y)/(p2.x-p1.x);
  k=(p1.y+(m*(x-p1.x)));
  temp.y=k;
  temp.x=x;
  for(i=0;i<4;i++)
  {
   temp.code[i]=p1.code[i];
   if(temp.y<=350 && temp.y>=100)
    return(temp);
  }
  if(p1.code[0]=='1')
  y=100;
  if(p1.code[1]=='1')
  y=350;
  if((p1.code[0]=='1')||(p1.code[1]=='1'))
  {
   m=(float)(p2.y-p1.y)/(p2.x-p1.x);
   k=(float)p1.x+(float)(y-p1.y)/m;
   temp.y=y;
   temp.x=k;
   for(i=0;i<4;i++)
   temp.code[i]=p1.code[i];
   return(temp);
  }
 }
 else
 return(p1);
 return(p2);
}


i tried this but it didnt work
Posted
Updated 30-Mar-12 6:22am
v2
Comments
fjdiewornncalwe 30-Mar-12 10:10am    
You need to add more information to your question. What have you tried? What are you having trouble with? etc.
nv3 30-Mar-12 10:46am    
What in particular do you have trouble with? Does your program crash, or deliver wrong results, and in which of your test cases? Just pasting a ton of code will probably not invite many people to look at your problem.

1 solution

I don't know which particular problem you are stumbling over, as their are a couple of things that need improvement.

1) In your setcode function there is one test for p.x >= 200, which should obviously read >= 450. That is probably the trouble you have.

2) Storing the attributes left, right, top, bottom in a character array is no good idea as it deprives you from the big advantage of the Cohen-Sutherland algorithm: Being able to rule out two important cases with a bit-wise OR-operation and AND-operation. Instead you should store them as bit-flags in an int variable. For example:

const int RIGHT  = 8;
const int LEFT   = 4;
const int BOTTOM = 2;
const int TOP    = 1;

int code = 0;
if (x < 150)
    code |= LEFT;
if (x > 450)
    code |= RIGHT;
....


Now you can check if both points are on the same side of the clipping rectangle by asking:
int code1 = getcode (pt1);
int code2 = getcode (pt2);
if ((code1 & code2) != 0)
    // both points are on one side and hence the
    // clipped line is empty
    return false;
if ((code1 | code2) == 0)
    // both points are inside the clipping rectange
    // so we can return the entire line
    ....


3) Of course you want to write your code in a more general way and
use variables for the coordinates of your clipping rectangle.

4) Your resetendpt function is somewhat simplified from the original Cohen-Sutherland algorithm and has the problem that when the x- or y-coordinates of both points are equal that will lead to division by zero. In the original algorithm, these cases have been excluded by the tests that I showed in (2).

I recommend you to lookup the original algorithm in Wikipedia or some other source and study, how it is done their. Of course, I could paste here a piece of code that solves your work, but I think as a homework assignment it is important that you do that by yourself. If you run into problems, please use the improve question button to tell us the problem, and you sure will get a further hint along the way.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900