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