I searched for a substitute circle- and ellipse-drawing method to ease the pain of those who don't see anything on the screen when they call dbCircle or dbEllipse. The main purpose was to draw an outline using only dbLine commands. As a second thought, it occurred to me that it would be easy to parameterize the function to draw both filled and unfilled shapes.
I chose a Bresenham-type algorythm which is an accepted method of drawing rasterized shapes, avoiding sine/cosine and square root calculations which are supposed to be slow. Since I understand the principle but haven't gone into the details, I adapted a ready-made code given in the article of another author. All credits are due to him.
Here is the explanation of the circle-drawing algorythm:
http://homepage.smc.edu/kennedy_john/BCIRCLE.PDF
And the adapted functions:
// Circle-drawing functions which:
// 1. make circles visible on the screen for those people who have the dbCircle bug,
// 2. make it possible to draw filled circles.
// The algorythm is copied from this article by John Kennedy:
// http://homepage.smc.edu/kennedy_john/BCIRCLE.PDF
// For filled circle: connect the calculated points
// with horizontal lines.
void PlotCircleLines(int CX, int CY, int X, int Y)
{
dbLine(CX + X, CY + Y, CX - X, CY + Y);
dbLine(CX - X, CY - Y, CX + X, CY - Y);
dbLine(CX + Y, CY + X, CX + Y, CY - X);
dbLine(CX - Y, CY + X, CX - Y, CY - X);
}
// For unfilled circle: plot the outline.
void PlotCirclePoints(int CX, int CY, int X, int Y)
{
// These should be dots, but dbDot would disappear as well,
// so we draw one-pixel-long lines.
dbLine(CX + X, CY + Y, CX + X + 1, CY + Y + 1);
dbLine(CX - X, CY + Y, CX - X + 1, CY + Y + 1);
dbLine(CX - X, CY - Y, CX - X + 1, CY - Y + 1);
dbLine(CX + X, CY - Y, CX + X + 1, CY - Y + 1);
dbLine(CX + Y, CY + X, CX + Y + 1, CY + X + 1);
dbLine(CX - Y, CY + X, CX - Y + 1, CY + X + 1);
dbLine(CX - Y, CY - X, CX - Y + 1, CY - X + 1);
dbLine(CX + Y, CY - X, CX + Y + 1, CY - X + 1);
}
// Parameters: center point coordinates, radius, filled or not.
void drawCircle(int CX, int CY, int R, bool Filled)
{
int X, Y, XChange, YChange, RadiusError;
X = R;
Y = 0;
XChange = 1 - 2 * R;
YChange = 1;
RadiusError = 0;
while (X >= Y)
{
if (Filled) PlotCircleLines(CX, CY, X, Y);
else PlotCirclePoints(CX, CY, X, Y);
Y++;
RadiusError += YChange;
YChange += 2;
if (2 * RadiusError + XChange > 0)
{
X--;
RadiusError += XChange;
XChange += 2;
}
}
}