Topic summary
Liang–Barsky algorithm
In computer graphics, the Liang–Barsky algorithm (named after You-Dong Liang and Brian A. Barsky) is a line clipping algorithm first published in early 1984. The Liang–Barsky algorithm uses the parametric equation of a line and inequalities describing the range of the clipping window to determine the intersections between the line and the clip window. With these intersections, it knows which portion of the line should be drawn. So this algorithm is significantly more efficient than Cohen–Sutherland. The idea of the Liang–Barsky clipping algorithm is to do as much testing as possible before computing line intersections.
The algorithm uses the parametric form of a straight line:
A point is in the clip window, if
and
which can be expressed as the 4 inequalities
where
To compute the final line segment:
- A line parallel to a clipping window edge has for that boundary.
- If for that , , then the line is completely outside and can be eliminated.
- When , the line proceeds outside to inside the clip window, and when , the line proceeds inside to outside.
- For nonzero , gives for the intersection point of the line and the window edge (possibly projected).
- The two actual intersections of the line with the window edges, if they exist, are described by and , calculated as follows. For , look at boundaries for which (i.e. outside to inside). Take to be the largest among . For , look at boundaries for which (i.e. inside to outside). Take to be the minimum of .
- If , the line is entirely outside the clip window. If it is entirely inside it.
// Liang–Barsky line-clipping algorithm#include<iostream>#include<graphics.h>#include<math.h>usingnamespacestd;// this function gives the maximumfloatmaxi(floatarr[],intn){floatm=0;for(inti=0;i<n;++i)if(m<arr[i])m=arr[i];returnm;}// this function gives the minimumfloatmini(floatarr[],intn){floatm=1;for(inti=0;i<n;++i)if(m>arr[i])m=arr[i];returnm;}voidliang_barsky_clipper(floatxmin,floatymin,floatxmax,floatymax,floatx1,floaty1,floatx2,floaty2){// defining variablesfloatp1=-(x2-x1);floatp2=-p1;floatp3=-(y2-y1);floatp4=-p3;floatq1=x1-xmin;floatq2=xmax-x1;floatq3=y1-ymin;floatq4=ymax-y1;floatexitParams[5],entryParams[5];intexitIndex=1,entryIndex=1;exitParams[0]=1;entryParams[0]=0;rectangle(xmin,ymin,xmax,ymax);// drawing the clipping windowif((p1==0&&q1<0)||(p2==0&&q2<0)||(p3==0&&q3<0)||(p4==0&&q4<0)){outtextxy(80,80,"Line is parallel to clipping window!");return;}if(p1!=0){floatr1=q1/p1;floatr2=q2/p2;if(p1<0){entryParams[entryIndex++]=r1;exitParams[exitIndex++]=r2;}else{entryParams[entryIndex++]=r2;exitParams[exitIndex++]=r1;}}if(p3!=0){floatr3=q3/p3;floatr4=q4/p4;if(p3<0){entryParams[entryIndex++]=r3;exitParams[exitIndex++]=r4;}else{entryParams[entryIndex++]=r4;exitParams[exitIndex++]=r3;}}floatclippedX1,clippedY1,clippedX2,clippedY2;floatu1,u2;u1=maxi(entryParams,entryIndex);// maximum of entry pointsu2=mini(exitParams,exitIndex);// minimum of exit pointsif(u1>u2){outtextxy(80,80,"Line is outside the clipping window!");return;}clippedX1=x1+(x2-x1)*u1;clippedY1=y1+(y2-y1)*u1;clippedX2=x1+(x2-x1)*u2;clippedY2=y1+(y2-y1)*u2;setcolor(CYAN);line(clippedX1,clippedY1,clippedX2,clippedY2);// draw clipped segmentsetlinestyle(1,1,0);line(x1,y1,clippedX1,clippedY1);// original start to clipped startline(x2,y2,clippedX2,clippedY2);// original end to clipped end}intmain(){cout<<"Liang-Barsky Line Clipping";cout<<"The system window layout is: (0,0) at bottom left and (631, 467) at top right";cout<<"Enter the coordinates of the window (xmin, ymin, xmax, ymax): ";floatxmin,ymin,xmax,ymax;cin>>xmin>>ymin>>xmax>>ymax;cout<<"Enter the endpoints of the line (x1, y1) and (x2, y2): ";floatx1,y1,x2,y2;cin>>x1>>y1>>x2>>y2;intgd=DETECT,gm;initgraph(&gd,&gm,"");// using winbgimliang_barsky_clipper(xmin,ymin,xmax,ymax,x1,y1,x2,y2);getch();closegraph();}