Line clipping with Cohen-Sutherland algorithm

Discuss any general programming issues here
Post Reply
User avatar
lazi
Posts: 625
Joined: Thu Feb 24, 2011 11:08 pm

Line clipping with Cohen-Sutherland algorithm

Post by lazi »

Hi!

Just created a set of functions for line clipping.
Have fun with it.

Code: Select all

;###########################################################
;#                                                         #
;#       Cohen-Sutherland line clipping algorithm          #
;#                        1.0                              #
;#   Ported to Hollywood by Lazi from wikipedia article:   #
;#  http://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland  #
;#                                                         #
;###########################################################



Const #_INSIDE = 0; // 0000
Const #_LEFT = 1;   // 0001
Const #_RIGHT = 2;  // 0010
Const #_BOTTOM = 4; // 0100
Const #_TOP = 8;    // 1000



;// Compute the bit code For a point (x, y) using the clip rectangle
;// bounded diagonally by (xmin, ymin), and (xmax, ymax)


;// ASSUME THAT xmax , xmin , ymax and ymin are global constants.

Function ComputeOutCode(x, y)
        Local code = #_INSIDE;       // initialised as being inside of clip window

        If (x < w_xmin)                  ; To the left of clip window
                code = code | #_LEFT
        ElseIf (x > w_xmax)      ; To the right of clip window
                code = code | #_RIGHT
        EndIf
        If (y < w_ymin)                  ; below the clip window
                code = code | #_TOP
        ElseIf (y > w_ymax)      ; above the clip window
                code = code | #_BOTTOM
        EndIf
        Return (code)
EndFunction

; Cohen&Sutherland clipping algorithm clips a line from
; P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
; diagonal from (xmin, ymin) to (xmax, ymax).

Function CohenSutherlandLineClip(x0, y0, x1, y1)

        ; compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
        Local outcode0 = ComputeOutCode(x0, y0)
        Local outcode1 = ComputeOutCode(x1, y1)


        Local accept = False

        Repeat
                If ((outcode0 | outcode1) = 0)  ; Bitwise OR is 0. Trivially accept and get out of loop
                        accept = True
                        Break
                ElseIf (outcode0 & outcode1)  ; Bitwise AND is not 0. Trivially reject and get out of loop
                        Break
                Else
                        ; failed both tests, so calculate the line segment to clip
                        ; from an outside point to an intersection with clip edge
                        Local x, y

                        ; At least one endpoint is outside the clip rectangle; pick it.
                        Local outcodeout=IIf(outcode0, outcode0, outcode1)

                        ; Now find the intersection point;
                        ; use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
                        If (outcodeOut & #_BOTTOM)            ;// point is above the clip rectangle
                                x = x0 + (x1 - x0) * (w_ymax - y0) / (y1 - y0)
                                y = w_ymax
                        ElseIf (outcodeOut & #_TOP)  ;// point is below the clip rectangle
                                x = x0 + (x1 - x0) * (w_ymin - y0) / (y1 - y0)
                                y = w_ymin
                        ElseIf (outcodeOut & #_RIGHT)   ;// point is To the right of clip rectangle
                                y = y0 + (y1 - y0) * (w_xmax - x0) / (x1 - x0)
                                x = w_xmax
                        ElseIf (outcodeOut & #_LEFT)    ;// point is To the left of clip rectangle
                                y = y0 + (y1 - y0) * (w_xmin - x0) / (x1 - x0)
                                x = w_xmin
                        EndIf
                        ; Now we move outside point to intersection point to clip
                        ; and get ready for next pass.
                        If (outcodeOut = outcode0)
                                x0 = x
                                y0 = y
                                outcode0 = ComputeOutCode(x0, y0)
                        Else
                                x1 = x
                                y1 = y
                                outcode1 = ComputeOutCode(x1, y1)
                        EndIf
                EndIf
        Forever
        If (accept)
               Return(x0, y0, x1, y1)
        Else
               Return(False)
        EndIf
EndFunction

;cropping window position

w_xmax=320;GetAttribute(#DISPLAY,0,#ATTRWIDTH)
w_ymax=200;GetAttribute(#DISPLAY,0,#ATTRHEIGHT)
w_xmin=50
w_ymin=50


Repeat

x1=Rnd(640)
y1=Rnd(480)
x2=Rnd(640)
y2=Rnd(480)

Box(w_xmin,w_ymin,w_xmax-w_xmin,w_ymax-w_ymin,#YELLOW)
Line(x1,y1,x2,y2,#WHITE)
x1,y1,x2,y2=CohenSutherlandLineClip(x1,y1,x2,y2)
If x1 Then Line(x1,y1,x2,y2,#RED,3)

Wait(20)
Cls
Forever                                                  
Post Reply