找到给定半径内的所有整数坐标

时间:2013-01-11 19:32:28

标签: performance algorithm geometry coordinates

给定一个二维坐标系,如何在给定点的半径范围内找到整数坐标的所有点?我希望这些点为x坐标和y坐标值。

在给定点周围的正方形中找到点很容易,可以这样做:

for(int x = -radius + point.x; x < radius + point.x; ++x)
for(int y = -radius + point.y; y < radius + point.y; ++y)
{
    points.insert(point(x, y));
}

但是如何在给定点周围找到圆圈中的点?该算法与性能相关,但与精度无关。因此,如果一个点接近半径而不是1,则无关紧要。换句话说,我不需要浮点精度。

4 个答案:

答案 0 :(得分:6)

最简单的解决方案:取一个正方形并过滤它:

Point point(100, 100);
for(int x = -radius; x <= radius; ++x)
for(int y = -radius; y <= radius; ++y)
if(x*x + y*y <= radius* radius)   {
    points.insert(Point(x + point.x, y + point.y));
}

答案 1 :(得分:4)

一种方法是根据-x到+ R的x上的外部循环和y上的内部循环,根据该x值处的圆的y值(从-sqrt(r ^ 2 - x ^ 2)到sqrt) (r ^ 2 - x ^ 2)如果中心位于0,0),如果中心位于X,Y - 只需将X或Y添加到所有循环范围,方法与示例中的方式相同

答案 2 :(得分:2)

您可以对中点圆算法进行少量修改,以获得实心圆。

首先生成坐标:

data = new int[radius];
int f = 1 - radius, ddF_x = 1;
int ddF_y = -2 * radius;
int x = 0, y = radius;
while (x < y)
{
    if (f >= 0)
    {
        y--;
        ddF_y += 2; f += ddF_y;
    }
    x++;
    ddF_x += 2; f += ddF_x;
    data[radius - y] = x; data[radius - x] = y;
}

然后访问所有内部要点:

int x0 = center.X;
int y0 = center.Y - Radius;
int y1 = center.Y + Radius - 1;

for (int y = 0; y < data.Length; y++)
{
    for (int x = -data[y]; x < data[y]; x++)
    {
        doSomething(x + x0, y + y0);
        doSomething(x + x0, y1 - y);
    }
}

这节省了一些不在圆圈中的工作访问点,但是以一点点预处理为代价。这绝对不会对小圈子有帮助,对于较大的圈子,我老实说也不知道。你必须对它进行基准测试。

答案 3 :(得分:1)

以下代码仅沿四分之一圆解析边界以确定内部区域。它不需要计算外点的距离,也不需要计算内点的距离。 (编辑:但最后,添加了圆圈的所有点)

在一些迷你Java基准测试中,对于小半径(<10),它与解析整个正方形的简单方法具有相同的速度。对于半径20-40,它大约快2倍,并且对于半径> 4,它实现了大约4倍的加速。对于一些更大的半径(> 200),加速度再次降低,因为对于任何方法,需要主导时间来创建和添加> 100k点 - 无论它们如何确定。

// add the full length vertical center line once
for (int y = -radius + point.y; y <= radius + point.y; ++y)
    points.insert(Point(point.x, y));

int sqRadius = radius * radius;

// add the shorter vertical lines to the left and to the right
int h = radius;
for (int dx = 1; dx <= radius; ++dx) {
    // decrease h
    while (dx*dx + h*h > sqRadius && h > 0)
        h--;

    for (int y = -h + point.y; y <= h + point.y; ++y) {
        points.insert(Point(point.x + dx, y));
        points.insert(Point(point.x - dx, y));
    }
}