Advertisement

Drawing circles....

Started by March 25, 2002 08:09 PM
0 comments, last by TerranFury 22 years, 10 months ago
And now for something completely different... Now that we have entered the world of hardware-accelerated 3d, primitive 2d line and circle algorithms may seem pretty useless. That's why this post is not as practical as it is novel. I was bored one day, and created a new (afaik) circle-drawing algorithm. It isn't as fast as Bresenham's, nor is it as wonderfully simple as plotting the parametric function. But it's interesting - I hope.
    
void drawCircle(double centerX, double centerY, double r)
{
           double  v1 = 0,
                   v2 = 1/r,
                   k  = -1 / (r * r),
                   y  = 0,
                   x  = 1;

           do
           {
                v1 += k * x;
                v2 += k * y;
                x  += v1;
                y  += v2;
                plotpixel(x*r+centerX, y*r+centerY);
           }while(!(fuzzyEqual(x, 1, 1e-2) && fuzzyEqual(y, 0, 1e-2)));
}
  
The fuzzyEqual function should be pretty self-explanatory, but I'll post it anyway:
  
inline bool fuzzyEqual(double a, double b, double e)
{
        if(a-e < b && a+e>b)
               return true;
        return false;
}
  
And there you have it. Edited by - TerranFury on March 25, 2002 9:14:20 PM
OK, nobody replied, so I guess I'm the only person who found this little exercise interesting.

But I'll explain what I did anyway.

I essentially use the parametric definition of a circle, namely:
x = cos(theta) * Ty = sin(theta) * T  


However, rather than directly calculating sine and cosine using a Taylor polynomial or the math.h function, I take advantage of a few facts.
1 - Sine/Cos y values in consecutive iterations (T values) are from consecutive evenly spaced x values.
2 - A Hookean spring oscillates sinusodially.

So I basically simulate two springs, one for sine, and one for cosine. These values are stored in x and y, respectively. The actual x and y coordinates are given by multiplying by r and adding an offset for the center of the circle.

To quickly explain what each variable is:
x = displacement of spring Ay = displacement of spring Bv1 = velocity of spring Av2 = velocity of spring Bk = spring constant for both springs A and B  


K, the spring constant, determines the period of the oscillation. Obviously, I want the period to correspond to the number of iterations I want to do. The number of iterations desired is determined by the circumference. Knowing this and solving for k in terms of r (and then negating so I can cumulatively add rather than subtract), I arrive at the expression I used in the code, k=-1/r2.

I still think this is a novel approach to circle drawing, which is why I made this explanatory post.

And now I'm done. 'Till next time, ta ta.



[edited by - TerranFury on March 27, 2002 4:53:09 PM]

This topic is closed to new replies.

Advertisement