I haven't forgotten the folks in the QBasic / QuickBASIC land just yet. For you, I would highly recommend the "Line" statement that is already a part of the QBasic language. It is optimized by using solely integers to perform line drawings (we'll later learn how to do this in C) and has a couple of extra features not available in our own line functions. However, if you're the type that likes to take the hard path, here is the full QBasic listing:
' Line function ' ' Draws any line of any slope or angle. ' SUB DrawLine(X1%, Y1%, X2%, Y2%, C%) DIM currX!, currY! ' Current pixel to be plotted DIM deltaX!, deltaY!, slope! ' 2 deltas and slope deltaX! = X2% - X1% ' Get value for delta X deltaY! = Y2% - Y1% ' Get value for delta Y deltaX! = ABS(deltaX!) ' Need absolute values deltaY! = ABS(deltaY!) IF deltaY! > deltaX! THEN ' |slope| > 1 IF Y2% < Y1% THEN SWAP Y2%, Y1% ' Swap coordinates SWAP X2%, X1% ' Y1 must be < Y2 END IF ' Compute deltas and slope deltaX! = X2% - X1% deltaY! = Y2% - Y1% ' Slope off the vertical axis slope! = deltaX! / deltaY! ' Plot each pixel starting at (X1, X2) currX! = X1% FOR currY! = Y1% TO Y2% ' May use 'SetPixel currX!, currY!, C%' instead PSET(currX!, currY!), C% ' Increment X by slope currX! = currX! + slope! NEXT currY! EXIT SUB ELSEIF deltaX! <> 0! OR deltaY! <> 0! THEN ' |slope| < 1 IF X2% < X1% THEN SWAP X2%, X1% ' Swap coordinates SWAP Y2%, Y1% ' X1 must be < X2 END IF ' Compute deltas and slope deltaX! = X2% - X1% deltaY! = Y2% - Y1% ' Slope off the horizontal axis slope! = deltaY! / deltaX! ' Plot each pixel starting at (X1, X2) currY! = Y1% FOR currX! = X1% TO X2% ' May use 'SetPixel currX!, currY!, C%' instead PSET(currX!, currY!), C% ' Increment X by slope currY! = currY! + slope! NEXT currX! EXIT SUB ELSE ' Set a single pixel because X1 = X2 and Y1 = Y2 PSET(X1%, Y1%), C% END IF END SUB
A word of warning for you QBasic users. This procedure passes the values to the procedure by reference. This means that if you were to call the procedure like so:
DrawLine a1, b1, a2, b2, c
and the procedure needed to swap the coordinates of the line, the values in (a1, b1) and (a2, b2) would also be swapped upon returning from the function. You would be wise to always call the procedure like so:
DrawLine (a1), (b1), (a2), (b2), (c)
unless this type of value swapping is desired (seldom is). This will eliminate the possibility of having any variables being changed by the procedure.
I found out after testing the DrawLine procedure in QuickBASIC that the BYVAL keyword is not supported unless the code for the procedure is outside of the QuickBASIC environment (that is, if it is DECLARE-ing a C or ASM generated function). The use of BYVAL will not work with our DrawLine procedure. To prevent the modifying of passed parameters, passed them enclosed in parentheses like the example shown above. Sorry for the confusion. |