From: Jay Link (jlink@interlink-bbs.com)
Date: Wed 01 Dec 1999 - 21:01:13 IST
> Maybe I'm missing something here, so just ignore me in that case, but > wouldnt the best solution be the Bresenham circle algorithm? It's > fast, elegant, and takes aspect ratio into account. Hey Chris, That worked out very well! Thanks for posting it. There were two problems, however: 1) The circle, whether filled or not, had a single blank line in the center. But, that can be fixed by making y >= 0, not just > 0. Here's how that would look, then, using gl_hline(): #define SCREEN_WIDTH 320 #define SCREEN_HEIGTH 200 void bresenham_circle(int xc, int yc, int r, char c) { int x = 0, y = r, d = 2 * (1 - r); while (y >= 0) { gl_hline(xc + x, yc + y, xc - x, c); gl_hline(xc + x, yc - y, xc - x, c); if(d + y > 0) { y--; d -= (2 * y * SCREEN_WIDTH / SCREEN_HEIGTH) - 1; } if(x > d) { x++; d += (2 * x) + 1; } } } 2) Now, the second problem is that your (or, Bresenham's) circle looks good in 320 x 200 modes, but in a more modern 4/3 mode (i.e. 640 x 480), it looks a little skewed. Contrast this with gl_circle(), which looks ok in 4/3 modes, but looks bad in 320 x 200. Using your post as an inspiration, though, I learned how ridiculously easy it is to change the gl_circle() algorithm to make a filled circle instead. Like I said, though, it looks good in high res, but skewed in 320 x 200. void gl_filled_circle(int xc, int yc, int r, char c) { int x = 0, y = r, d = 1 - r; gl_line(xc + x, yc + y, xc - x, yc + y, c); gl_line(xc + x, yc - y, xc - x, yc - y, c); gl_line(xc + y, yc + x, xc - y, yc + x, c); gl_line(xc + y, yc - x, xc - y, yc - x, c); while (x < y) { if (d < 0) { d += x * 2 + 3; } else { d += x * 2 - y * 2 + 5; y--; } x++; gl_line(xc + x, yc + y, xc - x, yc + y, c); gl_line(xc + x, yc - y, xc - x, yc - y, c); gl_line(xc + y, yc + x, xc - y, yc + x, c); gl_line(xc + y, yc - x, xc - y, yc - x, c); } } Perhaps there is a way to iron out either one of these to look good in all resolutions, perhaps by using vga_getxdim()? Or, they could be combined into one super-function, where if vga_getxdim() = 320 then do Bresenham's, otherwise do the modified gl_circle(). Anyway, Matan, I think this definitely needs to be in 1.4.1, however it's coded, and I like the idea of fixing gl_circle() so that it looks good in 320 x 200, as well. Thanks, everyone, for your suggestions! -Jay Link
This archive was generated by hypermail 2.1.4 : Wed 21 Jan 2004 - 22:10:22 IST