中点圈没有重复?

时间:2017-05-22 15:50:58

标签: c++ algorithm bresenham

我有一些代码可以生成网格坐标(SDL_Point只包含x和y的两个int s),其形状为圆形:

std::vector<SDL_Point> circle(const SDL_Point & start, const int radius)
{
    int x{ radius }, y{ 0 };
    int xChange{ 1 - 2 * radius };
    int yChange{ 1 };
    int rError{ 0 };

    std::vector<SDL_Point> circle;
    SDL_Point coord;

    while (x >= y)
    {
        /*  Due to circle's symmetry, we need only to calculate
            points in the first 45º of the circle.
        */

        coord = { start.x + x, start.y + y }; // Octant 1.
        circle.push_back(coord);
        coord = { start.x - x, start.y + y }; // Octant 4.
        circle.push_back(coord);
        coord = { start.x - x, start.y - y }; // Octant 5.
        circle.push_back(coord);
        coord = { start.x + x, start.y - y }; // Octant 8.
        circle.push_back(coord);
        coord = { start.x + y, start.y + x }; // Octant 2.
        circle.push_back(coord);
        coord = { start.x - y, start.y + x }; // Octant 3.
        circle.push_back(coord);
        coord = { start.x - y, start.y - x }; // Octant 6.
        circle.push_back(coord);
        coord = { start.x + y, start.y - x }; // Octant 7.
        circle.push_back(coord);

        ++y;
        rError += yChange;
        yChange += 2;

        if (2 * rError + xChange > 0)
        {
            --x;
            rError += xChange;
            xChange += 2;
        }
    }

    return circle;
}

这个工作正常,但我注意到从一个八分圆复制到另一个八分圆时会添加两个坐标(图中更清晰的灰色):

midpoint circle

是否有一种已知的方法可以避免重复这些重复项,或者我应该在将它们添加到vector之前进行检查?

我想知道最有效的方法是什么。我没有找到任何答案,我想在打印纯色圆圈时通常不会担心。

编辑:我需要矢量作为输出。

谢谢! :)

2 个答案:

答案 0 :(得分:3)

您可以使用强制唯一性的容器,例如

std::set<SDL_Point>

然后使用insert方法而不是push_back。

答案 1 :(得分:2)

如果你考虑你的代码在做什么,有两种情况会产生重复:当y为0时(沿着图的边缘),以及x == y时(圆圈中的对角线) )。您可以在针对这些条件的相应coord计算之前添加检查以排除它们。

例如,coord = { start.x + x, start.y + y };coord = { start.x + x, start.y - y };y为零时生成相同的值。