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