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.