
                            Line Drawing Techniques
                            =======================

                                 By Peter Hibbs
                                 --------------

     This article will describe two methods of drawing lines on the low rez
     screen together with the sub-routines elsewhere on this disk.

     The following files should be used in conjunction with these notes :-

     LINEDRAW.S      Source code files for line drawing routines.
     LINEDRAW.DOC    Quick reference document file for routines.
     LINEDEMO.S      Source code file for line drawing demo program.
     LINEDEMO.PRG    Low rez line drawing demo program.
     RADARDEM.PRG    Another low rez demo program.
     LINES.DOC       This document.


     GENERAL
     -------
     Two different line drawing sub-routines are provided in the LINEDRAW.S
     file, the programmer will have to select the one most suitable for his
     application. Both methods  are  fairly  similar  but  produce slightly
     different results which may be  significant  in the final application.
     Note that these are not the only  ways  to  draw a line, the VDI built
     into to the Operating System uses another method and NVDI uses another
     (even faster) method again.  If  GEM  is  available to the programmer,
     using the standard VDI calls from NVDI  is the quickest method. I have
     looked at the code in NVDI with  a disassembler but could not work out
     how it works (not without a lot  of time and effort anyway), if anyone
     else would like to have a go at this, I would be interested to see the
     results. The two routines  described  below  are  much slower although
     they do have the advantage  that  the  location  of  each pixel can be
     determined which could be useful in some programs.

     LINE DRAWING
     ------------
     The two routines use basically  the  same  strategy, the start and end
     co-ordinates of the line are passed  to  the routines in registers d0-
     d3, the line  drawing  routine  then  plots  the  position  of all the
     intermediate pixel co-ordinates, calling another routine (draw_pix) to
     draw each pixel on the screen  in  the appropriate colour. This method
     is relatively slow, however, as the  location  of each pixel on screen
     has to be calculated each  time  the  'draw_pix' routine is called. On
     the other hand,  in  some  programs  it  could  be  used  to check the
     location of a pixel against some other parameters.

     For example, in a CAD  program  a  number  of  lines could be drawn on
     screen using the normal GEM VDI  calls. The user then clicks somewhere
     on a line to execute  some  editing  function  and  the program has to
     determine which line has been  selected.  The CAD program would 'draw'
     the lines one at a time and  the 'draw_pix' routine replaced with some
     code which compares the mouse co-ordinates with the pixel co-ordinates
     being 'drawn' by the  line  routine.  When  the  two  match (or nearly
     match) the program can easily determine which line has been selected.

     Another possibility is that lines can  be  drawn in memory (instead of
     on screen) by changing the address in the 'screen' variable store and,
     if necessary, changing the 'width' of the RAM area.

     Draw_pix Sub-routine
     --------------------
     Examination of the line drawing routines 'line1' and 'line2' will show
     that neither have direct access to  the  screen memory, all they do is
     calculate the co-ordinates of the  pixels  to be shown, the 'draw_pix'
     routine handles writing to screen  memory and colour information. This
     means that the line drawing routines can  be used in any resolution or
     for drawing lines directly to  RAM,  only the 'draw_pix' routine needs
     to be changed to cater for  different  screens. In the present version
     of the 'draw_pix' routine it is assumed that the data is being written
     to a low rez screen  (16  colours/4  planes)  that  is 320 pixels (160
     bytes) wide by 200 pixels (200 lines) high and that the 'screen' store
     holds the address of  the  start  of  the  screen memory. The 'colour'
     store defines the colour of the pixel  being drawn. To cater for other
     screen sizes, the routine will need to be re-written.

     The pixel x and y co-ordinates are  passed to the routine in registers
     d0 and d1 respectively.

     No clipping facilities are included  in the routines supplied although
     this is very easy to incorporate in the 'draw_pix' routine. The pixels
     co-ordinates (in registers d0-d3)  can  be  compared with the clipping
     parameters in memory stores and  the 'draw_pix' sub-routine skipped if
     the values are outside the required area of drawing.

     Mode 1 Line drawing routine
     ---------------------------
     The first algorithm was taken from the  "Real Time 3D Graphics for the
     Atari ST" book by Andrew  Tyler.  The  line  drawn  by this routine is
     identical to that used by  the  VDI  and uses the Bresenham algorithm.
     There is a brief description of how the  code works in this book but I
     won't bother to reproduce  that  here  (I  didn't really understand it
     properly anyway) but if anyone is interested, please let me know.

     The line is drawn as shown  below,  each  O  represents a pixel and in
     this example a line is drawn  in  a  shallow  slope. Note that the end
     pixels of each section of the line do not overlap.

                      OOOO
                      ^   OOOO
                      |       OOOO
                      |           OOOO
                    start             OOOO
                                          OOOO
                                              OOOO
                                                  OOOO
                                                      OOOO
                                                         ^
                                                         |
                                                        end


     Mode 2 Line drawing routine
     ---------------------------
     The second algorithm was taken  from  the "ST 3D Graphics Programming"
     book by  Uwe  Braun.  The  line  drawn  by  this  routine  is slightly
     different than that used by the VDI as shown in the diagram below.

                     OOOOO
                     ^   OOOOO
                     |       OOOOO
                     |           OOOOO
                   start             OOOOO
                                         OOOOO
                                             OOOOO
                                                 OOOOO
                                                     OOOOO
                                                         ^
                                                         |
                                                        end

     When a line  is  drawn  horizontally  or  vertically  the  pixels will
     obviously be adjacent to each other. However,  when a line is drawn at
     an angle (except for a 45 degree  angle),  the pixels at the start and
     end of each section overlap  each  other  by  one pixel which tends to
     give the appearance of a  slightly  thicker  line.  This effect can be
     useful as shown in the demo program described below.

     DEMONSTRATION PROGRAMS
     ----------------------
     In the demo program called  LINEDEMO.PRG  a  series of lines are drawn
     between randomly selected points on  the  screen in different colours.
     The lines are drawn alternately using  first  mode  1 and then mode 2,
     although it is  not  that  obvious  that  the  lines are significantly
     different. Press the space bar to  draw  each line and press ESCAPE to
     quit. The source code file (LINEDEMO.S)  for this demo program is also
     provided.

     In the second demo  program  called  RADARDEM.PRG  (which  is a sample
     screen from my Wargames program)  the  second  mode  is used (i.e. the
     'thicker' version). There is a good  reason  for using this routine in
     this program, the routine draws a  line  from the centre of the screen
     to the edge which covers EVERY pixel  as it rotates whereas the mode 1
     routine does not. If the mode 1  routine was used in this application,
     there would be a large  number  of  pixels (and therefore radar blips)
     which  would  not  be  registered  on   screen.  This  effect  can  be
     demonstrated by pressing key 2  during  the scanning, the 'line erase'
     part of the program code is  inhibited  and the line drawing method is
     changed to mode 1, it can be  seen  that  a large number of pixels are
     not drawn as the line rotates. Pressing key 3 changes the line drawing
     method back to mode 2  (with  the  erase  code still inhibited) and in
     this mode ALL the pixels are drawn as the line rotates. Press key 1 to
     return to the normal mode or the ESCAPE key to quit the program.

     CONCLUSION
     ----------
     I am sure there are  other  and  quicker  methods of drawing lines, if
     anyone has any other  information  about  this,  please  send it in to
     Ictari.
