Cohen–Sutherland algorithm
In computer graphics, the Cohen-Sutherland algorithm is a line clipping algorithm. The algorithm divides a 2D space into 9 parts, of which only the middle part (viewport) is visible.
The algorithm
The algorithm includes, excludes or partially includes the line based on where the two endpoints are:
- Both endpoints are in the viewport (bitwise OR of endpoints == 0): trivial accept.
- Both endpoints are on the same side of the rectangle, which is not visible (bitwise AND of endpoints != 0): trivial reject.
- Both endpoints are in different parts: In case of this non trivial situation the algorithm finds one of the two points that are outside the viewport (there is at least one point outside). The intersection of the outpoint and extended viewport border is then calculated (i.e. with the parametric equation for the line) and this new point replaces the outpoint. The algorithm repeats until a trivial accept or reject occurs.
The numbers in the figure below are called outcodes. An outcode is computed for each of the two points in the line. The first bit is set to 1 if the point is above the viewport. The bits in the outcode represent: Top, Bottom, Right, Left. For example the outcode 1010 represents a point that is top-right of the viewport. Note that the outcodes for endpoints must be recalculated on each iteration after the clipping occurs.
1001 | 1000 | 1010 |
0001 | 0000 | 0010 |
0101 | 0100 | 0110 |
Pascal implementation for Cohen-Sutherland algorithm
procedure CohenSutherlandLineClipAndDraw(
x0,y0,x1,y1,xmin,xmax,ymin,ymax : real ; value: integer);
{ Cohen-Sutherland clipping algorithm for line P0=(x0,y0) to P1=(x1,y1)
and clip rectangle with diagonal from (xmin,ymin) to (xmax,ymax).}
type
edge = (LEFT,RIGHT,BOTTOM,TOP);
outcode = set of edge;
var
accept,done : boolean;
outcode0,outcode1,outcodeOut : outcode;
{Outcodes for P0,P1, and whichever point lies outside the clip rectangle}
x,y : real;
procedure CompOutCode(x,y: real; var code:outcode);
{Compute outcode for the point (x,y) }
begin
code := [];
if y > ymax then code := [TOP]
else if y < ymin then code := [BOTTOM];
if x > xmax then code := code + [RIGHT]
else if x < xmin then code := code + [LEFT]
end;
begin
accept := false; done := false;
CompOutCode (x0,y0,outcode0); CompOutCode (x1,y1,outcode1);
repeat
if(outcode0=[]) and (outcode1=[]) then {Trivial accept and exit}
begin accept := true; done:=true end
else if (outcode0*outcode1) <> [] then
done := true {Logical intersection is true,
so trivial reject and exit.}
else
{Failed both tests, so calculate the line segment to clip;
from an outside point to an intersection with clip edge.}
begin
{At least one endpoint is outside the clip rectangle; pick it.}
if outcode0 <> [] then
outcodeOut := outcode0 else outcodeOut := outcode1;
{Now find intersection point;
use formulas y=y0+slope*(x-x0),x=x0+(1/slope)*(y-y0).}
if TOP in outcodeOut then
begin {Divide line at top of clip rectangle}
x := x0 + (x1 - x0) * (ymax - y0) / (y1 - y0);
y := ymax
end
else if BOTTOM in outcodeOut then
begin {Divide line at bottom of clip rectangle}
x := x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
y := ymin
end
if RIGHT in outcodeOut then
begin {Divide line at right edge of clip rectangle}
y := y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
x := xmax
end
else if LEFT in outcodeOut then
begin {Divide line at left edge of clip rectangle}
y := y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
x := xmin
end;
{Now we move outside point to intersection point to clip,
and get ready for next pass.}
if (outcodeOut = outcode0) then
begin
x0 := x; y0 := y; CompOutCode(x0,y0,outcode0)
end
else
begin
x1 := x; y1 := y; CompOutCode(x1,y1,outcode1);
end
end {subdivide}
until done;
if accept then MidpointLineReal(x0,y0,x1,y1,value) {Version for
real coordinates}
end; {CohenSutherlandLineClipAndDraw}
See also
Algorithms used for the same purpose: