Here you will learn about cohen sutherland line clipping algorithm in C and C++.
This is one of the oldest and most popular line clipping algorithm. To speed up the process this algorithm performs initial tests that reduce number of intersections that must be calculated. It does so by using a 4 bit code called as region code or outcodes. These codes identify location of the end point of line.
Each bit position indicates a direction, starting from the rightmost position of each bit indicates left, right, bottom, top respectively.
Once we establish region codes for both the endpoints of a line we determine whether the endpoint is visible, partially visible or invisible with the help of ANDing of the region codes.
There arises 3 cases which are explained in the algorithm below in step 4.
Also Read: Liang Barsky Line Clipping Algorithm in C and C++
Algorithm
1. Read 2 end points of line as p1(x1,y1) and p2(x2,y2)
2. Read 2 corner points of the clipping window (left-top and right-bottom) as (wx1,wy1) and (wx2,wy2)
3. Assign the region codes for 2 endpoints p1 and p2 using following steps:-
initialize code with 0000
Set bit 1 if x<wx1
Set bit 2 if x>wx2
Set bit 3 if y<wy2
Set bit 4 if y>wy1
4. Check for visibility of line
- If region codes for both endpoints are zero then line is completely visible. Draw the line go to step 9.
- If region codes for endpoints are not zero and logical ANDing of them is also nonzero then line is invisible. Discard the line and move to step 9.
- If it does not satisfy 4.a and 4.b then line is partially visible.
5. Determine the intersecting edge of clipping window as follows:-
- If region codes for both endpoints are nonzero find intersection points p1’ and p2’ with boundary edges.
- If region codes for any one end point is non zero then find intersection point p1’ or p2’.
6. Divide the line segments considering intersection points.
7. Reject line segment if any end point of line appears outside of any boundary.
8. Draw the clipped line segment.
9. Stop.
Program for Cohen Sutherland Line Clipping Algorithm in C and C++
C Program
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<graphics.h> #include<dos.h> typedef struct coordinate { int x,y; char code[4]; }PT; void drawwindow(); void drawline(PT p1,PT p2); PT setcode(PT p); int visibility(PT p1,PT p2); PT resetendpt(PT p1,PT p2); void main() { int gd=DETECT,v,gm; PT p1,p2,p3,p4,ptemp; printf("\nEnter x1 and y1\n"); scanf("%d %d",&p1.x,&p1.y); printf("\nEnter x2 and y2\n"); scanf("%d %d",&p2.x,&p2.y); initgraph(&gd,&gm,"c:\\turboc3\\bgi"); drawwindow(); delay(500); drawline(p1,p2); delay(500); cleardevice(); delay(500); p1=setcode(p1); p2=setcode(p2); v=visibility(p1,p2); delay(500); switch(v) { case 0: drawwindow(); delay(500); drawline(p1,p2); break; case 1: drawwindow(); delay(500); break; case 2: p3=resetendpt(p1,p2); p4=resetendpt(p2,p1); drawwindow(); delay(500); drawline(p3,p4); break; } delay(5000); closegraph(); } void drawwindow() { line(150,100,450,100); line(450,100,450,350); line(450,350,150,350); line(150,350,150,100); } void drawline(PT p1,PT p2) { line(p1.x,p1.y,p2.x,p2.y); } PT setcode(PT p) //for setting the 4 bit code { PT ptemp; if(p.y<100) ptemp.code[0]='1'; //Top else ptemp.code[0]='0'; if(p.y>350) ptemp.code[1]='1'; //Bottom else ptemp.code[1]='0'; if(p.x>450) ptemp.code[2]='1'; //Right else ptemp.code[2]='0'; if(p.x<150) ptemp.code[3]='1'; //Left 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.x=k; temp.y=y; for(i=0;i<4;i++) temp.code[i]=p1.code[i]; return(temp); } else return(p1); } |
C++ Program
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
#include<iostream.h> #include<stdlib.h> #include<math.h> #include<graphics.h> #include<dos.h> typedef struct coordinate { int x,y; char code[4]; }PT; void drawwindow(); void drawline(PT p1,PT p2); PT setcode(PT p); int visibility(PT p1,PT p2); PT resetendpt(PT p1,PT p2); void main() { int gd=DETECT,v,gm; PT p1,p2,p3,p4,ptemp; cout<<"\nEnter x1 and y1\n"; cin>>p1.x>>p1.y; cout<<"\nEnter x2 and y2\n"; cin>>p2.x>>p2.y; initgraph(&gd,&gm,"c:\\turboc3\\bgi"); drawwindow(); delay(500); drawline(p1,p2); delay(500); cleardevice(); delay(500); p1=setcode(p1); p2=setcode(p2); v=visibility(p1,p2); delay(500); switch(v) { case 0: drawwindow(); delay(500); drawline(p1,p2); break; case 1: drawwindow(); delay(500); break; case 2: p3=resetendpt(p1,p2); p4=resetendpt(p2,p1); drawwindow(); delay(500); drawline(p3,p4); break; } delay(5000); closegraph(); } void drawwindow() { line(150,100,450,100); line(450,100,450,350); line(450,350,150,350); line(150,350,150,100); } void drawline(PT p1,PT p2) { line(p1.x,p1.y,p2.x,p2.y); } PT setcode(PT p) //for setting the 4 bit code { PT ptemp; if(p.y<100) ptemp.code[0]='1'; //Top else ptemp.code[0]='0'; if(p.y>350) ptemp.code[1]='1'; //Bottom else ptemp.code[1]='0'; if(p.x>450) ptemp.code[2]='1'; //Right else ptemp.code[2]='0'; if(p.x<150) ptemp.code[3]='1'; //Left 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.x=k; temp.y=y; for(i=0;i<4;i++) temp.code[i]=p1.code[i]; return(temp); } else return(p1); } |
Output
Before Clipping
After Clipping
This article is submitted by Rahul Maheshwari. You can connect with him on facebook.
Comment below if you have doubts or found any information incorrect in above cohen sutherland line clipping algorithm in C and C++.
Mast tha bhai
v=1 is not coming.
Yes, if the line doesn’t lie in the visibility region. here we obtain v=2 for line being partially inside the visibility region. Hence line clipping is done.
NICE……simple and sweet codding
Showing error “BGI Error: Graphic is not initialized (used ‘initgraph’)?
Help please!
May be the path you set in initgraph is not correct.
Simply put this line
initgraph(&gdrive,&gmode,”C:\tc\bgi”. check if your path has TC or turboC3 or anything else.
Check your path correctly.
If that is not the solution then go to options and check the library to see if graphics library is ticked or not.
I think the problem shall lie among these two only.
I feel thank you nice
hey!can you upload this algorithm program in python.
this program is not running.
I did it and it is running well and good.
What’s the error showing in your program?
how to draw for three lines
Algorithm is the same. You just need to apply it for 3 separate lines. You may require to call the function multiple times for each pair of co-ordinates that constructs the line.
I think Top and Bottom conditions are wrong. As if y>350 it should be on top.