【问题标题】:Algorithm to find all points on a 2D grid some distance away from another point在距离另一个点一定距离的二维网格上找到所有点的算法
【发布时间】:2012-07-16 04:05:47
【问题描述】:

我在 2D 网格 (x, y) 上有一个点,我需要找到距离该点 n 距离的所有点。我测量距离的方法是使用两点之间的距离公式。有人知道怎么做吗?

编辑:仅供参考,我正在尝试编写一些 AI 路径查找,该路径查找将在使用基于网格的位置的系统中与目标保持一定距离。目前我正在使用 A* 路径查找,但我不确定这是否重要或有什么不同,因为我对这些东西有点陌生。

【问题讨论】:

  • 您想要在那个范围内的点还是正好在那个距离之外的点?
  • 理想的解决方案是所有点都恰好在距离的某个误差范围内。

标签: grid 2d distance point


【解决方案1】:

我会这样做:

  1. 首先过滤掉在 x 或 y 上比 D 更远的所有点。这些肯定在半径 D 的圆之外。这是一个简单得多的计算,并且可以快速消除大量工作。这是一个外部边界框优化。

  2. 您还可以使用内部边界框优化。如果点在 x 或 y 上比 D * sqrt(2)/2 更近,那么它们肯定在半径 D 的圆内。这也比计算距离公式更便宜。

  3. 那么你有较少的候选点可能在半径 D 的圆内。对于这些,使用距离公式。请记住,如果 D = sqrt(Δx2+Δy2),则 D2 = Δx2+Δy 2.
    所以你可以跳过计算平方根的成本。


因此,在伪代码中,您可以执行以下操作:

for each point
begin
    if test 1 indicates the point is outside the outer bounding box, 
    then skip this point

    if test 2 indicates the point is inside the inner bounding box, 
    then keep this point

    if test 3 indicates the point is inside the radius of the circle, 
    then keep this point
end

【讨论】:

  • 可以通过空间索引进一步优化算法。如果点数真的很高,这将是正确的。如果点数不是那么大,构建空间索引的成本可能不值得。
  • 网格不是很大。我认为目前世界的计划大小只会是 256x256 左右。
  • 好的,所以首先我会过滤 X 和 Y 距离都在该距离内的点,然后使用内部边界框检查过滤这些点?不知道如何使用第二部分。
  • 太好了,谢谢 :) 我需要做一些简单的测试以确保获得我想要的值,但我认为这可能正是我想要的。
【解决方案2】:

这个问题被称为范围查询。蛮力解决方案正如您所描述的:计算所有点与参考点的距离,并返回距离小于所需范围值的点。

蛮力算法是O(N^2)。但是,有更有效的算法使用spatial indexes 来降低算法复杂性和距离计算次数。例如,您可以使用R-Tree 来索引您的积分。

【讨论】:

    【解决方案3】:

    它称为最近邻搜索。更多http://en.wikipedia.org/wiki/Nearest_neighbor_search

    为此有一些开放的库。我使用了一个为 C 编写的并推荐它:http://www.cs.umd.edu/~mount/ANN/。 ANN 代表 Approximate Nearest Neighbor,但是,您可以关闭近似并找到确切的最近邻居。

    【讨论】:

    • 有趣的东西,但我认为这对于我目前正在做的事情来说太重了。不过,我会记住它以备后用。
    【解决方案4】:

    这不会使用距离公式,但如果您正在寻找距离正好为 n 的点,也许您可​​以使用 sin/cos?

    在伪代码中:

    for degrees in range(360):
        x = cos(degrees) * n
        y = sin(degrees) * n
        print x, y
    

    这将以 360 度增量打印 n 以外的每个点。

    【讨论】:

      【解决方案5】:

      Java 实现:

      public static Set<Point> findNearbyPoints(Set<Point> pts, Point centerPt, double radius) {
          Set<Point> nearbyPtsSet = new HashSet<Point>();
          double innerBound = radius * (Math.sqrt(2.0) / 2.0);
          double radiusSq = radius * radius;
          for (Point pt : pts) {
              double xDist = Math.abs(centerPt.x - pt.x);
              double yDist = Math.abs(centerPt.y - pt.y);
              if (xDist > radius || yDist > radius)
                  continue;
              if (xDist > innerBound || yDist > innerBound)
                  continue;
              if (distSq(centerPt, pt) < radiusSq)
                  nearbyPtsSet.add(pt);
          }
          return nearbyPtsSet;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-07
        • 2020-04-02
        • 2023-04-03
        • 1970-01-01
        • 1970-01-01
        • 2013-11-10
        • 1970-01-01
        • 2020-05-27
        相关资源
        最近更新 更多