Path: utzoo!utgpu!cunews!cognos!alzabo!andras From: andras@alzabo.ocunix.on.ca (Andras Kovacs) Newsgroups: comp.sys.acorn Subject: Re: Drawing lines in C Message-ID: <1991Feb25.081646.15077@alzabo.ocunix.on.ca> Date: 25 Feb 91 08:16:46 GMT References: <8671@castle.ed.ac.uk> Reply-To: andras@alzabo.UUCP (Andras Kovacs) Organization: Brian's XENIXlings, Ottawa, Canada Lines: 141 In article <8671@castle.ed.ac.uk> ecwu61@castle.ed.ac.uk (R Renwick) writes: > I want to plot lines on the screen in C, not under the wimp. >How can I do it??? I can't seem to find an example anywhere. Here is an implementation of Bresenham's algorithm for line drawing. Please don't judge my programming from this example :-); it is just to pass on some code to the needy. Anyway, this program will draw random lines on the screen. It does not do clipping; if your x coordinates are out of screen, then it will wrap around; if the y ones are out of bounds then BOMB!BOMB! I put the screen pointer into a global 'cause I would hate to pass it everytime on the stack. As you observe there is some code duplicated in the Line routine; it is an attempt to optimize by trading size for speed. The plot is inlined to speed things up a bit. This implementation draws around 1400 lines per second (including the loop overhead and the - significant - time required to generate the random coordinates); a carefully coded and little bit cheating assembly version does approx. 2200 lines/sec (in the same test bed). (John Kortink will understand this; Tiggr and some others will try to squeeze the same performance out of their C compilers but they are doomed :-) ). There is lots of ways to do clipping on different levels; you have to choose for yourself the best one for the particular problem - but it will slow down the line drawing (obviously). ---- cut here ---- #include #include #include void Line(int x1, int y1, int x2, int y2, char col); int InputBlock[] = {149, -1}; char *screen; int main(int argc, char *argv[]) { int i, limit; reg_set regs; if (argc != 2) { printf("Usage: Lines <# of lines>\n"); return -1; } mode(13); regs.r[0] = (int)InputBlock; regs.r[1] = (int)(&screen); swi(XOS_MASK | OS_ReadVduVariables, ®s); swi(XOS_MASK | OS_RemoveCursors, ®s); limit = atoi(argv[1]); #define r(n) rand() % n for (i = 0; i < limit; ++i) Line(r(320), r(256), r(320), r(256), r(256)); getchar(); mode(0); return 0; } void Line(int x1, int y1, int x2, int y2, char col) { int dx, dy, e, yincr, xincr, tmp; if (abs(x2 - x1) >= abs(y2 - y1)) { if (x1 > x2) { tmp = x1; x1 = x2; x2 = tmp; tmp = y1; y1 = y2; y2 = tmp; } dx = x2 - x1; dy = y2 - y1; if (dy > 0) yincr = 1; else yincr = -1; dy = abs(dy); e = (dy << 1) - dx; for ( ; x1 <= x2; ++x1) { *(screen + x1 + y1 * 320) = col; if (e > 0) { y1 += yincr; e -= dx << 1; } e += dy << 1; } } else { if (y1 > y2) { tmp = x1; x1 = x2; x2 = tmp; tmp = y1; y1 = y2; y2 = tmp; } dx = x2 - x1; dy = y2 - y1; if (dx > 0) xincr = 1; else xincr = -1; dx = abs(dx); e = (dx << 1) - dy; for ( ; y1 <= y2; ++y1) { *(screen + x1 + y1 * 320) = col; if (e > 0) { x1 += xincr; e -= dy << 1; } e += dx << 1; } } } ---- cut here ---- Oh, I just realized that there is no comments in this source; I suppose I'll never be a CS student... :-) Andras -- Andras Kovacs andras@alzabo.ocunix.on.ca Nepean, Ont.