【问题标题】:connect a point to each two closest point between different points将一个点连接到不同点之间的每两个最近点
【发布时间】:2010-11-23 05:40:52
【问题描述】:

您好,我正在用 java 编写一个应用程序。在我的应用程序中,我需要一种方法将每个点连接到许多不同点之间的两个最近点(从一个点到它的两个最近点画一条线)。起初我创建了这个方法,以便将每个点连接到它最近的点:

  public void connectingPoints()
  {

      ArrayList<Point>  externals = new ArrayList<Point>();
      for(int i = 0; i<externals.size(); i++)
      {
          Point point = externals.get(i);
          Point minPoint = externals.get(i+1);
          int minXDistance = minPoint.x-point.x;
          int minYDistance = minPoint.y-point.y;

          for(int j = 1; j<externals.size();i++)
          {
              if((externals.get(j+1).x-point.x<minXDistance)&&(externals.get(j+1).y-point.y<minYDistance))
              {
                  minPoint = externals.get(j+1);
              }
          }
          getGraphics().drawLine(point.x, point.y, minPoint.x, minPoint.y);
          repaint();
      }
  }
}

但是这种方法根本不起作用。为什么?问题出在哪里?以及如何将一个点连接到它的 2 个最近点。

【问题讨论】:

  • 当您说“不起作用”时,它会做什么?
  • 我什至不明白这个问题。
  • 当您应该在嵌套的 for 循环中增加 j 时,您似乎增加了 i

标签: java awt


【解决方案1】:

这并不是真正检查点之间的距离。使用勾股定理计算点之间的距离,然后选择最低和次低的结果。将 X 值之间的距离平方,将 Y 值之间的距离的平方相加,然后取平方根。

【讨论】:

    【解决方案2】:

    我认为您有几个问题。看起来你有这样的课程:

    public class Point {
       public double x;
       public double y;
    }
    

    您可能应该向您的类添加一个如下所示的方法:

    public double distance(Point p) {
        return Math.hypot(this.x - p.x, this.y - p.y);
    }
    

    还有一个:

    public Point getClosestPoint(List<Point> pts) {
        double minDistSoFar = Double.MAX_VALUE;
        Point rval = null;
    
        for (Point p : pts) {
            if (p.x == this.x && p.y == this.y) {
                continue;
            }
    
            double pDist = this.distance(p);
            if (pDist < minDistSoFar) {
                minDistSoFar = pDist;
                rval = p;
            }
        }
    }
    

    现在你的算法可以变成这样:

    public void connectingPoints()
    {
        ArrayList<Point>  externals = new ArrayList<Point>();
        for(Point p : externals) {
            Point minPoint = p.getClosestPoint(externals);
            getGraphics().drawLine(point.x, point.y, minPoint.x, minPoint.y);
            repaint();
        }
    }
    

    编辑:您最初的问题可能是您在循环中索引“i”来检查 j 的值。此外,这里是对您的代码进行简单(且可行)重写的重写。

    public void connectingPoints()
    {
        ArrayList<Point>  externals = new ArrayList<Point>();
        for(int i = 0; i<externals.size(); i++)
        {
            Point point = externals.get(i);
            Point minPoint = externals.get((i+1) % externals.size());
            int minXDistance = minPoint.x-point.x;
            int minYDistance = minPoint.y-point.y;
            double minDist = Math.hypot(minXDistance, minYDistance);
    
            for(int j = 0; j < externals.size(); j++)  // <- you had i++ here!
            {
                if (i == j) {
                    continue;
                }
    
                Point testPt = externals.get(j);
                double dist = Math.hypot(point.x - testPt.x, point.y - testPt.y);
                if (dist < minDist)
                {
                    minDist = dist;
                    minPoint = testPt;
                }
            }
            getGraphics().drawLine(point.x, point.y, minPoint.x, minPoint.y);
            repaint();
        }
    }
    

    【讨论】:

      【解决方案3】:

      问题 1:您不是在计算距离,而是在计算 X 中的距离 + Y 中的距离。

      distance = sqrt( x^2 + y^2)
      

      好消息是,为了进行比较,您可以去掉平方根。您不能删除“square x”和“square y”部分。非常重要。

      问题 2:您找到最近的点两次,而不是最近的两个点。这是一个可以工作的快速-n-脏算法,尽管它肯定有改进的空间:

      For each point
        calculate and store distances to all the other points
        // use a sorted map for the above.
        grab the closest two points and draw your lines.
      

      请注意,这将导致相当多的重新计算,因此还有改进的余地。

      另请注意,这不会创建通过所有点的路径。

      【讨论】:

      • 是的,我在某处捡到的方便的小技巧……可能是在“游戏编程宝石”文章中。我不认为这有 O(n^2) 上限,尽管 big-O 只是查看效率的一种方式。
      • 避免平方根是一个很好的技巧,只要你不遇到溢出。我遇到了一次溢出,从那以后我一直在使用 Java 的 Math.hypot 方法。但是,如果您知道自己需要性能,这是一个真的方便的技巧。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-08
      • 1970-01-01
      • 2016-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多