将一个点连接到不同点之间的每两个最近点

时间:2010-11-22 17:52:22

标签: java awt

您好我正在用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点。

3 个答案:

答案 0 :(得分:2)

这并不是真正检查点之间的距离。使用毕达哥拉斯定理计算点之间的距离,然后选择最低和第二低的结果。平方X值之间的距离,加上Y值之间距离的平方,然后取平方根。

答案 1 :(得分:1)

问题1:你没有计算距离,你计算距离为X +距离Y.

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

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

问题2:你找到最近的点两次,而不是最近的两点。这是一个快速且非常脏的算法,虽然它确实留有改进的余地,但它仍然有效:

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.

请注意,这会导致相当多的重新计算,因此有待改进。

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

答案 2 :(得分:1)

我认为你有几个问题。看起来你有这样一个类:

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();
    }
}