2
votes

I have adapted some code from a great article I found about circle drawing by Mukund Sivaraman to execute a passed function for each point on a given circle:

template<class Function>
static void For_each_point_on_circle(Image *image, int radius, Function function)
{
    int x, y;
    int l;
    l = (int) radius * cos (M_PI / 4);
    for (x = 0; x <= l; x++)
    {
        y = (int) sqrt ((double) (radius * radius) - (x * x));
        function(image, x, y);
        function(image, x, -y);
        function(image, -x, y);
        function(image, -x, -y);
        function(image, y, x);
        function(image, y, -x);
        function(image, -y, x);
        function(image, -y, -x);
  }
}

However, what I really need is to calculate the points around the circle in sequence, so the calls to function(image, x, y) will go from 0 to 360 degrees in sequence rather than skipping about, which is acceptable when drawing the circle.

I could calculate all the points and sort them, but I was hoping someone may know a way to do it properly, maybe using multiple loops each calculating a segment each?

Many thanks.

2
How far apart are the points on the circle? (1 degree?) - Cameron
Just 1 pixel away from each other, not necessarily any fixed degrees away. Thanks. - user1454345
If you want to go round the circle in even spaces (even with regard to arc length, not x-axis) I would suggest using polar coordinates and a suitable division of 2*PI based on how many points you want to plot. - mathematician1975
What is wrong with the obvious function(image, radius*cos(angle), radius*sin(angle))? - BlueRaja - Danny Pflughoeft
@Danny: it is easier to stay in pixel coordinates then try to step in polar coordinates. the angular pixel spacing isn't constant around the circle. if you wanted to compute it, it would be a function of angle and resolution. - atb

2 Answers

4
votes

something like this should do it:

template<class Function>
static void For_each_point_on_circle(Image *image, int radius, Function function)
{
    int x, y;
    int l;
    l = (int) radius * cos (M_PI / 4);
    for (x = -l; x < l; x++)
    {
        y = (int) sqrt ((double) (radius * radius) - (x * x));
        function(image, x, y);
    }
    for (x = -l; x < l; x++)
    {
        y = (int) sqrt ((double) (radius * radius) - (x * x));
        function(image, y, -x);
    }
    for (x = -l; x < l; x++)
    {
        y = (int) sqrt ((double) (radius * radius) - (x * x));
        function(image, -x, -y);
    }
    for (x = -l; x < l; x++)
    {
        y = (int) sqrt ((double) (radius * radius) - (x * x));
        function(image, -y, x);
    }
}
2
votes

Here's an article on pathing out a circle in discrete steps. Its motivation is for a CNC machine stepper motor controller, but maybe it will work for your purposes.

https://github.com/Falmarri/cnc/blob/master/BresenHam-3D-helix.pdf