Jump to content

Cohen–Sutherland algorithm

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by 217.80.236.110 (talk) at 01:44, 13 October 2008. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

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: